]> git.lizzy.rs Git - rust.git/commitdiff
Use HIR map instead of tcx in constant evaluator
authorSeo Sanghyeon <sanxiyn@gmail.com>
Mon, 29 Feb 2016 13:54:02 +0000 (22:54 +0900)
committerSeo Sanghyeon <sanxiyn@gmail.com>
Mon, 29 Feb 2016 13:54:02 +0000 (22:54 +0900)
Constant evaluator can be called while tcx is in construction.

src/librustc/middle/const_eval.rs
src/test/compile-fail/issue-31910.rs [new file with mode: 0644]

index 9ec79c84afb30b6d61ee132fceaec0060321af0d..3d28f3a8a3f0cb732b437409a14c7fb8eea8a83b 100644 (file)
@@ -1019,7 +1019,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
               }
               Some(Def::AssociatedConst(def_id)) => {
                   if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
-                      match tcx.impl_or_trait_item(def_id).container() {
+                      match impl_or_trait_container(tcx, def_id) {
                           ty::TraitContainer(trait_id) => match tcx.map.find(node_id) {
                               Some(ast_map::NodeTraitItem(ti)) => match ti.node {
                                   hir::ConstTraitItem(ref ty, _) => {
@@ -1222,6 +1222,23 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
     Ok(result)
 }
 
+fn impl_or_trait_container(tcx: &ty::ctxt, def_id: DefId) -> ty::ImplOrTraitItemContainer {
+    // This is intended to be equivalent to tcx.impl_or_trait_item(def_id).container()
+    // for local def_id, but it can be called before tcx.impl_or_trait_items is complete.
+    if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
+        if let Some(ast_map::NodeItem(item)) = tcx.map.find(tcx.map.get_parent_node(node_id)) {
+            let container_id = tcx.map.local_def_id(item.id);
+            match item.node {
+                hir::ItemImpl(..) => return ty::ImplContainer(container_id),
+                hir::ItemTrait(..) => return ty::TraitContainer(container_id),
+                _ => ()
+            }
+        }
+        panic!("No impl or trait container for {:?}", def_id);
+    }
+    panic!("{:?} is not local", def_id);
+}
+
 fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                                                 ti: &'tcx hir::TraitItem,
                                                 trait_id: DefId,
diff --git a/src/test/compile-fail/issue-31910.rs b/src/test/compile-fail/issue-31910.rs
new file mode 100644 (file)
index 0000000..65fcd7d
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 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.
+
+#![feature(associated_consts)]
+
+enum Enum<T: Trait> {
+    X = Trait::Number, //~ ERROR constant evaluation error
+}
+
+trait Trait {
+    const Number: i32 = 1;
+}
+
+fn main() {}