about summary refs log tree commit diff
path: root/src/librustc_const_eval
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2016-12-21 12:32:59 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2016-12-28 11:27:57 +0200
commite64f64a2fc1deb955b42542fa399f2fa2b609866 (patch)
treec9b856eb84b258363a07ff747ffe8591a8251a4b /src/librustc_const_eval
parent864928297d0fc0675c5eae62a58d8488941d58cf (diff)
downloadrust-e64f64a2fc1deb955b42542fa399f2fa2b609866.tar.gz
rust-e64f64a2fc1deb955b42542fa399f2fa2b609866.zip
rustc: separate bodies for static/(associated)const and embedded constants.
Diffstat (limited to 'src/librustc_const_eval')
-rw-r--r--src/librustc_const_eval/check_match.rs4
-rw-r--r--src/librustc_const_eval/diagnostics.rs8
-rw-r--r--src/librustc_const_eval/eval.rs47
3 files changed, 33 insertions, 26 deletions
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index da28187496b..cb1d67d01c7 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -67,7 +67,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
     }
 
     fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
-                b: hir::ExprId, s: Span, id: ast::NodeId) {
+                b: hir::BodyId, s: Span, id: ast::NodeId) {
         if let FnKind::Closure(..) = fk {
             span_bug!(s, "check_match: closure outside of function")
         }
@@ -120,7 +120,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
     }
 
     fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
-                b: hir::ExprId, s: Span, n: ast::NodeId) {
+                b: hir::BodyId, s: Span, n: ast::NodeId) {
         intravisit::walk_fn(self, fk, fd, b, s, n);
 
         for input in &fd.inputs {
diff --git a/src/librustc_const_eval/diagnostics.rs b/src/librustc_const_eval/diagnostics.rs
index 83b0d9dec6d..b24cd261dd5 100644
--- a/src/librustc_const_eval/diagnostics.rs
+++ b/src/librustc_const_eval/diagnostics.rs
@@ -576,18 +576,18 @@ https://doc.rust-lang.org/reference.html#ffi-attributes
 
 
 E0306: r##"
-In an array literal `[x; N]`, `N` is the number of elements in the array. This
+In an array type `[T; N]`, `N` is the number of elements in the array. This
 must be an unsigned integer. Erroneous code example:
 
 ```compile_fail,E0306
-let x = [0i32; true]; // error: expected positive integer for repeat count,
-                      //        found boolean
+const X: [i32; true] = [0]; // error: expected `usize` for array length,
+                            //        found boolean
 ```
 
 Working example:
 
 ```
-let x = [0i32; 2];
+const X: [i32; 1] = [0];
 ```
 "##,
 }
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index 09f38e5be8f..c42b558830f 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -56,15 +56,17 @@ macro_rules! math {
 fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                   variant_def: DefId)
                                   -> Option<&'tcx Expr> {
-    fn variant_expr<'a>(variants: &'a [hir::Variant], id: ast::NodeId)
-                        -> Option<&'a Expr> {
+    let variant_expr = |variants: &'tcx [hir::Variant], id: ast::NodeId |
+                        -> Option<&'tcx Expr> {
         for variant in variants {
             if variant.node.data.id() == id {
-                return variant.node.disr_expr.as_ref().map(|e| &**e);
+                return variant.node.disr_expr.map(|e| {
+                    &tcx.map.body(e).value
+                });
             }
         }
         None
-    }
+    };
 
     if let Some(variant_node_id) = tcx.map.as_local_node_id(variant_def) {
         let enum_node_id = tcx.map.get_parent(variant_node_id);
@@ -96,21 +98,24 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         match tcx.map.find(node_id) {
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
-                hir::ItemConst(ref ty, ref const_expr) => {
-                    Some((&const_expr, tcx.ast_ty_to_prim_ty(ty)))
+                hir::ItemConst(ref ty, body) => {
+                    Some((&tcx.map.body(body).value,
+                          tcx.ast_ty_to_prim_ty(ty)))
                 }
                 _ => None
             },
             Some(ast_map::NodeTraitItem(ti)) => match ti.node {
-                hir::TraitItemKind::Const(ref ty, ref expr_option) => {
+                hir::TraitItemKind::Const(ref ty, default) => {
                     if let Some(substs) = substs {
                         // If we have a trait item and the substitutions for it,
                         // `resolve_trait_associated_const` will select an impl
                         // or the default.
                         let trait_id = tcx.map.get_parent(node_id);
                         let trait_id = tcx.map.local_def_id(trait_id);
-                        let default_value = expr_option.as_ref()
-                            .map(|expr| (&**expr, tcx.ast_ty_to_prim_ty(ty)));
+                        let default_value = default.map(|body| {
+                            (&tcx.map.body(body).value,
+                             tcx.ast_ty_to_prim_ty(ty))
+                        });
                         resolve_trait_associated_const(tcx, def_id, default_value, trait_id, substs)
                     } else {
                         // Technically, without knowing anything about the
@@ -125,8 +130,9 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 _ => None
             },
             Some(ast_map::NodeImplItem(ii)) => match ii.node {
-                hir::ImplItemKind::Const(ref ty, ref expr) => {
-                    Some((&expr, tcx.ast_ty_to_prim_ty(ty)))
+                hir::ImplItemKind::Const(ref ty, body) => {
+                    Some((&tcx.map.body(body).value,
+                          tcx.ast_ty_to_prim_ty(ty)))
                 }
                 _ => None
             },
@@ -142,8 +148,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
         let mut used_substs = false;
         let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
-            Some((&InlinedItem { body: ref const_expr, .. }, _)) => {
-                Some((&**const_expr, Some(tcx.sess.cstore.item_type(tcx, def_id))))
+            Some((&InlinedItem { ref body, .. }, _)) => {
+                Some((&body.value, Some(tcx.sess.cstore.item_type(tcx, def_id))))
             }
             _ => None
         };
@@ -864,18 +870,18 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
               Struct(_) => signal!(e, UnimplementedConstVal("tuple struct constructors")),
               callee => signal!(e, CallOn(callee)),
           };
-          let (arg_defs, body_id) = match lookup_const_fn_by_id(tcx, did) {
-              Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), ii.body.expr_id()),
+          let (arg_defs, body) = match lookup_const_fn_by_id(tcx, did) {
+              Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), &ii.body),
               Some(ConstFnNode::Local(fn_like)) =>
                   (fn_like.decl().inputs.iter()
                    .map(|arg| match arg.pat.node {
                        hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
                        _ => None
                    }).collect(),
-                   fn_like.body()),
+                   tcx.map.body(fn_like.body())),
               None => signal!(e, NonConstPath),
           };
-          let result = tcx.map.expr(body_id);
+          let result = &body.value;
           assert_eq!(arg_defs.len(), args.len());
 
           let mut call_args = DefIdMap();
@@ -893,7 +899,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
               }
           }
           debug!("const call({:?})", call_args);
-          eval_const_expr_partial(tcx, &result, ty_hint, Some(&call_args))?
+          eval_const_expr_partial(tcx, result, ty_hint, Some(&call_args))?
       },
       hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ety) {
           Ok(val) => val,
@@ -953,11 +959,12 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
       }
       hir::ExprArray(ref v) => Array(e.id, v.len() as u64),
-      hir::ExprRepeat(_, ref n) => {
+      hir::ExprRepeat(_, n) => {
           let len_hint = ty_hint.checked_or(tcx.types.usize);
+          let n = &tcx.map.body(n).value;
           Repeat(
               e.id,
-              match eval_const_expr_partial(tcx, &n, len_hint, fn_args)? {
+              match eval_const_expr_partial(tcx, n, len_hint, fn_args)? {
                   Integral(Usize(i)) => i.as_u64(tcx.sess.target.uint_type),
                   Integral(_) => signal!(e, RepeatCountNotNatural),
                   _ => signal!(e, RepeatCountNotInt),