]> git.lizzy.rs Git - rust.git/commitdiff
enable cross crate and unsafe const fn
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 14 Jan 2016 14:03:48 +0000 (15:03 +0100)
committerOliver 'ker' Schneider <rust19446194516@oli-obk.de>
Sun, 17 Jan 2016 14:24:46 +0000 (15:24 +0100)
src/librustc/middle/const_eval.rs
src/test/compile-fail/const-call.rs
src/test/compile-fail/const-fn-stability-calls-2.rs [deleted file]
src/test/run-pass/const-fn-cross-crate.rs
src/test/run-pass/const-fn.rs

index eae2aa9cb7e736547332d177b6ea48812604bbdb..5a07124792d9c24131427dad7afbc02fbcb2e5ac 100644 (file)
@@ -27,7 +27,7 @@
 use util::nodemap::NodeMap;
 
 use graphviz::IntoCow;
-use syntax::{ast, abi};
+use syntax::ast;
 use rustc_front::hir::Expr;
 use rustc_front::hir;
 use rustc_front::intravisit::FnKind;
@@ -1089,19 +1089,16 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
       hir::ExprCall(ref callee, ref args) => {
           let sub_ty_hint = ty_hint.erase_hint();
           let callee_val = try!(eval_const_expr_partial(tcx, callee, sub_ty_hint, fn_args));
-          let (decl, block, constness) = try!(get_fn_def(tcx, e, callee_val));
-          match (ty_hint, constness) {
-              (ExprTypeChecked, _) => {
-                  // no need to check for constness... either check_const
-                  // already forbids this or we const eval over whatever
-                  // we want
-              },
-              (_, hir::Constness::Const) => {
-                  // we don't know much about the function, so we force it to be a const fn
-                  // so compilation will fail later in case the const fn's body is not const
-              },
-              _ => signal!(e, NonConstPath),
-          }
+          let did = match callee_val {
+              Function(did) => did,
+              callee => signal!(e, CallOn(callee)),
+          };
+          let (decl, result) = if let Some(fn_like) = lookup_const_fn_by_id(tcx, did) {
+              (fn_like.decl(), &fn_like.body().expr)
+          } else {
+              signal!(e, NonConstPath)
+          };
+          let result = result.as_ref().expect("const fn has no result expression");
           assert_eq!(decl.inputs.len(), args.len());
 
           let mut call_args = NodeMap();
@@ -1116,7 +1113,6 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
               let old = call_args.insert(arg.pat.id, arg_val);
               assert!(old.is_none());
           }
-          let result = block.expr.as_ref().unwrap();
           debug!("const call({:?})", call_args);
           try!(eval_const_expr_partial(tcx, &**result, ty_hint, Some(&call_args)))
       },
@@ -1397,46 +1393,3 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>,
     };
     compare_const_vals(&a, &b)
 }
-
-
-// returns Err if callee is not `Function`
-// `e` is only used for error reporting/spans
-fn get_fn_def<'a>(tcx: &'a ty::ctxt,
-                  e: &hir::Expr,
-                  callee: ConstVal)
-                  -> Result<(&'a hir::FnDecl, &'a hir::Block, hir::Constness), ConstEvalErr> {
-    let did = match callee {
-        Function(did) => did,
-        callee => signal!(e, CallOn(callee)),
-    };
-    debug!("fn call: {:?}", tcx.map.get_if_local(did));
-    match tcx.map.get_if_local(did) {
-        None => signal!(e, UnimplementedConstVal("calling non-local const fn")), // non-local
-        Some(ast_map::NodeItem(it)) => match it.node {
-            hir::ItemFn(
-                ref decl,
-                hir::Unsafety::Normal,
-                constness,
-                abi::Abi::Rust,
-                _, // ducktype generics? types are funky in const_eval
-                ref block,
-            ) => Ok((&**decl, &**block, constness)),
-            _ => signal!(e, NonConstPath),
-        },
-        Some(ast_map::NodeImplItem(it)) => match it.node {
-            hir::ImplItemKind::Method(
-                hir::MethodSig {
-                    ref decl,
-                    unsafety: hir::Unsafety::Normal,
-                    constness,
-                    abi: abi::Abi::Rust,
-                    .. // ducktype generics? types are funky in const_eval
-                },
-                ref block,
-            ) => Ok((decl, block, constness)),
-            _ => signal!(e, NonConstPath),
-        },
-        Some(ast_map::NodeTraitItem(..)) => signal!(e, NonConstPath),
-        Some(_) => signal!(e, UnimplementedConstVal("calling struct, tuple or variant")),
-    }
-}
index d49da47a87c83ad9e7716a0488b5a3d6cc8839b9..1143d3bd5cd96491e1e5c5116eef414e01843d5a 100644 (file)
 
 #![feature(const_fn)]
 
-const unsafe fn g(x: usize) -> usize {
-    x
-}
-
 fn f(x: usize) -> usize {
     x
 }
 
 fn main() {
     let _ = [0; f(2)]; //~ ERROR: non-constant path in constant expression [E0307]
-    let _ = [0; g(2)]; //~ ERROR: non-constant path in constant expression [E0307]
 }
diff --git a/src/test/compile-fail/const-fn-stability-calls-2.rs b/src/test/compile-fail/const-fn-stability-calls-2.rs
deleted file mode 100644 (file)
index 592a312..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test use of const fn from another crate without a feature gate.
-
-// aux-build:const_fn_lib.rs
-
-extern crate const_fn_lib;
-
-use const_fn_lib::foo;
-
-fn main() {
-    let x: [usize; foo()] = [];
-    //~^ ERROR unimplemented constant expression: calling non-local const fn [E0250]
-}
index 5d0c17af7171902a2bd6441220c597633913dc62..7b4b751fd7f255d62f3fbcade5319592bb2a062d 100644 (file)
@@ -22,4 +22,5 @@
 
 fn main() {
     assert_eq!(FOO, 22);
+    let _: [i32; foo()] = [42; 22];
 }
index 38c73febc310843de85447d67ff64ad311e53c21..5961ed8d3390d9ac4a1266e77e9c24622f7270c0 100644 (file)
@@ -20,14 +20,20 @@ const fn sub(x: u32, y: u32) -> u32 {
     x - y
 }
 
+const unsafe fn div(x: u32, y: u32) -> u32 {
+    x / y
+}
+
 const SUM: u32 = add(44, 22);
 const DIFF: u32 = sub(44, 22);
+const DIV: u32 = unsafe{div(44, 22)};
 
 fn main() {
     assert_eq!(SUM, 66);
     assert!(SUM != 88);
 
     assert_eq!(DIFF, 22);
+    assert_eq!(DIV, 2);
 
     let _: [&'static str; sub(100, 99) as usize] = ["hi"];
 }