]> git.lizzy.rs Git - rust.git/commitdiff
Make TypeckTables::type_dependent_defs use ItemLocalId instead of NodeId.
authorMichael Woerister <michaelwoerister@posteo>
Fri, 4 Aug 2017 07:49:40 +0000 (09:49 +0200)
committerMichael Woerister <michaelwoerister@posteo>
Fri, 11 Aug 2017 10:11:38 +0000 (12:11 +0200)
31 files changed:
src/librustc/hir/def_id.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/ich/impls_hir.rs
src/librustc/ich/impls_ty.rs
src/librustc/infer/mod.rs
src/librustc/lint/context.rs
src/librustc/middle/dead.rs
src/librustc/middle/effect.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/reachable.rs
src/librustc/ty/context.rs
src/librustc/util/nodemap.rs
src/librustc_const_eval/eval.rs
src/librustc_const_eval/pattern.rs
src/librustc_data_structures/indexed_vec.rs
src/librustc_driver/pretty.rs
src/librustc_lint/builtin.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_passes/consts.rs
src/librustc_privacy/lib.rs
src/librustc_save_analysis/lib.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustc_typeck/check/writeback.rs

index 7f76e1bf770bf26c5549a66aec2a51dc998869f6..bb3b248674ab7a84e6c4cd4cb8b225c669403b2c 100644 (file)
@@ -201,4 +201,11 @@ pub fn local(index: DefIndex) -> DefId {
     pub fn is_local(&self) -> bool {
         self.krate == LOCAL_CRATE
     }
+
+    pub fn invalid() -> DefId {
+        DefId {
+            krate: INVALID_CRATE,
+            index: CRATE_DEF_INDEX,
+        }
+    }
 }
index 421a81c0d23422f572965c2d8edfffd20bef961b..27048a71454bcad09839f621d61ae7dbea9ebee4 100644 (file)
@@ -155,6 +155,11 @@ enum ParamMode {
     Optional
 }
 
+struct LoweredNodeId {
+    node_id: NodeId,
+    hir_id: hir::HirId,
+}
+
 impl<'a> LoweringContext<'a> {
     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
         /// Full-crate AST visitor that inserts into a fresh
@@ -278,11 +283,14 @@ fn allocate_hir_id_counter<T: Debug>(&mut self,
     fn lower_node_id_generic<F>(&mut self,
                                 ast_node_id: NodeId,
                                 alloc_hir_id: F)
-                                -> NodeId
+                                -> LoweredNodeId
         where F: FnOnce(&mut Self) -> hir::HirId
     {
         if ast_node_id == DUMMY_NODE_ID {
-            return ast_node_id;
+            return LoweredNodeId {
+                node_id: DUMMY_NODE_ID,
+                hir_id: hir::DUMMY_HIR_ID,
+            }
         }
 
         let min_size = ast_node_id.as_usize() + 1;
@@ -291,12 +299,22 @@ fn lower_node_id_generic<F>(&mut self,
             self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
         }
 
-        if self.node_id_to_hir_id[ast_node_id] == hir::DUMMY_HIR_ID {
+        let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
+
+        if existing_hir_id == hir::DUMMY_HIR_ID {
             // Generate a new HirId
-            self.node_id_to_hir_id[ast_node_id] = alloc_hir_id(self);
+            let hir_id = alloc_hir_id(self);
+            self.node_id_to_hir_id[ast_node_id] = hir_id;
+            LoweredNodeId {
+                node_id: ast_node_id,
+                hir_id,
+            }
+        } else {
+            LoweredNodeId {
+                node_id: ast_node_id,
+                hir_id: existing_hir_id,
+            }
         }
-
-        ast_node_id
     }
 
     fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
@@ -323,7 +341,7 @@ fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
     /// actually used in the HIR, as that would trigger an assertion in the
     /// HirIdValidator later on, which makes sure that all NodeIds got mapped
     /// properly. Calling the method twice with the same NodeId is fine though.
-    fn lower_node_id(&mut self, ast_node_id: NodeId) -> NodeId {
+    fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
             let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner
                                                                  .last_mut()
@@ -340,7 +358,7 @@ fn lower_node_id(&mut self, ast_node_id: NodeId) -> NodeId {
     fn lower_node_id_with_owner(&mut self,
                                 ast_node_id: NodeId,
                                 owner: NodeId)
-                                -> NodeId {
+                                -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
             let local_id_counter = this.item_local_id_counters
                                        .get_mut(&owner)
@@ -375,7 +393,7 @@ fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>)
         id
     }
 
-    fn next_id(&mut self) -> NodeId {
+    fn next_id(&mut self) -> LoweredNodeId {
         self.lower_node_id(self.sess.next_node_id())
     }
 
@@ -517,7 +535,7 @@ fn lower_loop_destination(&mut self, destination: Option<(NodeId, Spanned<Ident>
         match destination {
             Some((id, label_ident)) => {
                 let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
-                    hir::LoopIdResult::Ok(self.lower_node_id(loop_id))
+                    hir::LoopIdResult::Ok(self.lower_node_id(loop_id).node_id)
                 } else {
                     hir::LoopIdResult::Err(hir::LoopIdError::UnresolvedLabel)
                 };
@@ -534,7 +552,7 @@ fn lower_loop_destination(&mut self, destination: Option<(NodeId, Spanned<Ident>
                 hir::Destination {
                     ident: None,
                     target_id: hir::ScopeTarget::Loop(
-                        loop_id.map(|id| Ok(self.lower_node_id(id)))
+                        loop_id.map(|id| Ok(self.lower_node_id(id).node_id))
                                .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
                                .into())
                 }
@@ -557,7 +575,7 @@ fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
 
     fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
         hir::TypeBinding {
-            id: self.lower_node_id(b.id),
+            id: self.lower_node_id(b.id).node_id,
             name: self.lower_ident(b.ident),
             ty: self.lower_ty(&b.ty),
             span: b.span,
@@ -594,7 +612,7 @@ fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
                 return self.lower_ty(ty);
             }
             TyKind::Path(ref qself, ref path) => {
-                let id = self.lower_node_id(t.id);
+                let id = self.lower_node_id(t.id).node_id;
                 let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit);
                 return self.ty_path(id, t.span, qpath);
             }
@@ -645,7 +663,7 @@ fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
         };
 
         P(hir::Ty {
-            id: self.lower_node_id(t.id),
+            id: self.lower_node_id(t.id).node_id,
             node: kind,
             span: t.span,
         })
@@ -758,7 +776,7 @@ fn lower_qpath(&mut self,
             // Otherwise, the base path is an implicit `Self` type path,
             // e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
             // `<I as Iterator>::Item::default`.
-            let new_id = self.next_id();
+            let new_id = self.next_id().node_id;
             self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))
         };
 
@@ -782,7 +800,7 @@ fn lower_qpath(&mut self,
             }
 
             // Wrap the associated extension in another type node.
-            let new_id = self.next_id();
+            let new_id = self.next_id().node_id;
             ty = self.ty_path(new_id, p.span, qpath);
         }
 
@@ -887,7 +905,7 @@ fn lower_parenthesized_parameter_data(&mut self,
 
     fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
         P(hir::Local {
-            id: self.lower_node_id(l.id),
+            id: self.lower_node_id(l.id).node_id,
             ty: l.ty.as_ref().map(|t| self.lower_ty(t)),
             pat: self.lower_pat(&l.pat),
             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
@@ -905,8 +923,10 @@ fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
     }
 
     fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
+        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(arg.id);
         hir::Arg {
-            id: self.lower_node_id(arg.id),
+            id: node_id,
+            hir_id,
             pat: self.lower_pat(&arg.pat),
         }
     }
@@ -969,7 +989,7 @@ fn lower_ty_param(&mut self, tp: &TyParam, add_bounds: &[TyParamBound]) -> hir::
         }
 
         hir::TyParam {
-            id: self.lower_node_id(tp.id),
+            id: self.lower_node_id(tp.id).node_id,
             name,
             bounds,
             default: tp.default.as_ref().map(|x| self.lower_ty(x)),
@@ -987,7 +1007,7 @@ fn lower_ty_params(&mut self, tps: &Vec<TyParam>, add_bounds: &NodeMap<Vec<TyPar
 
     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
         hir::Lifetime {
-            id: self.lower_node_id(l.id),
+            id: self.lower_node_id(l.id).node_id,
             name: self.lower_ident(l.ident),
             span: l.span,
         }
@@ -1059,7 +1079,7 @@ fn lower_generics(&mut self, g: &Generics) -> hir::Generics {
 
     fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
         hir::WhereClause {
-            id: self.lower_node_id(wc.id),
+            id: self.lower_node_id(wc.id).node_id,
             predicates: wc.predicates
                           .iter()
                           .map(|predicate| self.lower_where_predicate(predicate))
@@ -1098,7 +1118,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                                                           ref rhs_ty,
                                                           span}) => {
                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                    id: self.lower_node_id(id),
+                    id: self.lower_node_id(id).node_id,
                     lhs_ty: self.lower_ty(lhs_ty),
                     rhs_ty: self.lower_ty(rhs_ty),
                     span,
@@ -1114,16 +1134,16 @@ fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
                                                .enumerate()
                                                .map(|f| self.lower_struct_field(f))
                                                .collect(),
-                                         self.lower_node_id(id))
+                                         self.lower_node_id(id).node_id)
             }
             VariantData::Tuple(ref fields, id) => {
                 hir::VariantData::Tuple(fields.iter()
                                               .enumerate()
                                               .map(|f| self.lower_struct_field(f))
                                               .collect(),
-                                        self.lower_node_id(id))
+                                        self.lower_node_id(id).node_id)
             }
-            VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
+            VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id),
         }
     }
 
@@ -1134,7 +1154,7 @@ fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
         };
         hir::TraitRef {
             path,
-            ref_id: self.lower_node_id(p.ref_id),
+            ref_id: self.lower_node_id(p.ref_id).node_id,
         }
     }
 
@@ -1149,7 +1169,7 @@ fn lower_poly_trait_ref(&mut self, p: &PolyTraitRef) -> hir::PolyTraitRef {
     fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
         hir::StructField {
             span: f.span,
-            id: self.lower_node_id(f.id),
+            id: self.lower_node_id(f.id).node_id,
             name: self.lower_ident(match f.ident {
                 Some(ident) => ident,
                 // FIXME(jseyfried) positional field hygiene
@@ -1198,8 +1218,11 @@ fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
             }
         }
 
+        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(b.id);
+
         P(hir::Block {
-            id: self.lower_node_id(b.id),
+            id: node_id,
+            hir_id,
             stmts: stmts.into(),
             expr,
             rules: self.lower_block_check_mode(&b.rules),
@@ -1249,7 +1272,7 @@ fn lower_item_kind(&mut self,
                                         hir::Visibility::Restricted {
                                             path: path.clone(),
                                             // We are allocating a new NodeId here
-                                            id: this.next_id(),
+                                            id: this.next_id().node_id,
                                         }
                                     }
                                 };
@@ -1387,7 +1410,7 @@ fn lower_item_kind(&mut self,
     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
         self.with_parent_def(i.id, |this| {
             hir::TraitItem {
-                id: this.lower_node_id(i.id),
+                id: this.lower_node_id(i.id).node_id,
                 name: this.lower_ident(i.ident),
                 attrs: this.lower_attrs(&i.attrs),
                 node: match i.node {
@@ -1448,7 +1471,7 @@ fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
     fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
         self.with_parent_def(i.id, |this| {
             hir::ImplItem {
-                id: this.lower_node_id(i.id),
+                id: this.lower_node_id(i.id).node_id,
                 name: this.lower_ident(i.ident),
                 attrs: this.lower_attrs(&i.attrs),
                 vis: this.lower_visibility(&i.vis, None),
@@ -1540,7 +1563,7 @@ pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
         });
 
         Some(hir::Item {
-            id: self.lower_node_id(i.id),
+            id: self.lower_node_id(i.id).node_id,
             name,
             attrs,
             node,
@@ -1552,7 +1575,7 @@ pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
     fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
         self.with_parent_def(i.id, |this| {
             hir::ForeignItem {
-                id: this.lower_node_id(i.id),
+                id: this.lower_node_id(i.id).node_id,
                 name: i.ident.name,
                 attrs: this.lower_attrs(&i.attrs),
                 node: match i.node {
@@ -1630,8 +1653,11 @@ fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
     }
 
     fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
+        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(p.id);
+
         P(hir::Pat {
-            id: self.lower_node_id(p.id),
+            id: node_id,
+            hir_id,
             node: match p.node {
                 PatKind::Wild => hir::PatKind::Wild,
                 PatKind::Ident(ref binding_mode, pth1, ref sub) => {
@@ -1813,7 +1839,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let call_move_val_init =
                         hir::StmtSemi(
                             make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
-                            self.next_id());
+                            self.next_id().node_id);
                     let call_move_val_init = respan(e.span, call_move_val_init);
 
                     let place = self.expr_ident(e.span, place_ident, place_binding);
@@ -1883,11 +1909,15 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                             // wrap the if-let expr in a block
                             let span = els.span;
                             let els = P(self.lower_expr(els));
-                            let id = self.next_id();
+                            let LoweredNodeId {
+                                node_id,
+                                hir_id,
+                            } = self.next_id();
                             let blk = P(hir::Block {
                                 stmts: hir_vec![],
                                 expr: Some(els),
-                                id,
+                                id: node_id,
+                                hir_id,
                                 rules: hir::DefaultBlock,
                                 span,
                                 targeted_by_break: false,
@@ -1986,8 +2016,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
 
+                let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
+
                 return hir::Expr {
-                    id: self.lower_node_id(e.id),
+                    id: node_id,
+                    hir_id,
                     node: if is_unit {
                         hir::ExprPath(struct_path)
                     } else {
@@ -2234,7 +2267,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                                                hir::MatchSource::ForLoopDesugar),
                                 ThinVec::new()))
                 };
-                let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id()));
+                let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id().node_id));
 
                 let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
 
@@ -2254,7 +2287,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let body_block = self.with_loop_scope(e.id,
                                                         |this| this.lower_block(body, false));
                 let body_expr = P(self.expr_block(body_block, ThinVec::new()));
-                let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id()));
+                let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id().node_id));
 
                 let loop_block = P(self.block_all(e.span,
                                                   hir_vec![next_let,
@@ -2266,8 +2299,10 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 // `[opt_ident]: loop { ... }`
                 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
                                               hir::LoopSource::ForLoop);
+                let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
                 let loop_expr = P(hir::Expr {
-                    id: self.lower_node_id(e.id),
+                    id: node_id,
+                    hir_id,
                     node: loop_expr,
                     span: e.span,
                     attrs: ThinVec::new(),
@@ -2406,8 +2441,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
             ExprKind::Mac(_) => panic!("Shouldn't exist here"),
         };
 
+        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
+
         hir::Expr {
-            id: self.lower_node_id(e.id),
+            id: node_id,
+            hir_id,
             node: kind,
             span: e.span,
             attrs: e.attrs.clone(),
@@ -2420,7 +2458,7 @@ fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
                 node: hir::StmtDecl(P(Spanned {
                     node: hir::DeclLocal(self.lower_local(l)),
                     span: s.span,
-                }), self.lower_node_id(s.id)),
+                }), self.lower_node_id(s.id).node_id),
                 span: s.span,
             },
             StmtKind::Item(ref it) => {
@@ -2431,22 +2469,22 @@ fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
                         node: hir::DeclItem(item_id),
                         span: s.span,
                     }), id.take()
-                          .map(|id| self.lower_node_id(id))
-                          .unwrap_or_else(|| self.next_id())),
+                          .map(|id| self.lower_node_id(id).node_id)
+                          .unwrap_or_else(|| self.next_id().node_id)),
                     span: s.span,
                 }).collect();
             }
             StmtKind::Expr(ref e) => {
                 Spanned {
                     node: hir::StmtExpr(P(self.lower_expr(e)),
-                                          self.lower_node_id(s.id)),
+                                          self.lower_node_id(s.id).node_id),
                     span: s.span,
                 }
             }
             StmtKind::Semi(ref e) => {
                 Spanned {
                     node: hir::StmtSemi(P(self.lower_expr(e)),
-                                          self.lower_node_id(s.id)),
+                                          self.lower_node_id(s.id).node_id),
                     span: s.span,
                 }
             }
@@ -2477,9 +2515,9 @@ fn lower_visibility(&mut self,
                 hir::Visibility::Restricted {
                     path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
                     id: if let Some(owner) = explicit_owner {
-                        self.lower_node_id_with_owner(id, owner)
+                        self.lower_node_id_with_owner(id, owner).node_id
                     } else {
-                        self.lower_node_id(id)
+                        self.lower_node_id(id).node_id
                     }
                 }
             }
@@ -2621,8 +2659,10 @@ fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr
     }
 
     fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
+        let LoweredNodeId { node_id, hir_id } = self.next_id();
         hir::Expr {
-            id: self.next_id(),
+            id: node_id,
+            hir_id,
             node,
             span,
             attrs,
@@ -2639,13 +2679,13 @@ fn stmt_let_pat(&mut self,
             pat,
             ty: None,
             init: ex,
-            id: self.next_id(),
+            id: self.next_id().node_id,
             span: sp,
             attrs: ThinVec::new(),
             source,
         });
         let decl = respan(sp, hir::DeclLocal(local));
-        respan(sp, hir::StmtDecl(P(decl), self.next_id()))
+        respan(sp, hir::StmtDecl(P(decl), self.next_id().node_id))
     }
 
     fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
@@ -2665,10 +2705,13 @@ fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
 
     fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
                  -> hir::Block {
+        let LoweredNodeId { node_id, hir_id } = self.next_id();
+
         hir::Block {
             stmts,
             expr,
-            id: self.next_id(),
+            id: node_id,
+            hir_id,
             rules: hir::DefaultBlock,
             span,
             targeted_by_break: false,
@@ -2712,18 +2755,22 @@ fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
 
     fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation)
                               -> P<hir::Pat> {
-        let id = self.next_id();
+        let LoweredNodeId { node_id, hir_id } = self.next_id();
         let parent_def = self.parent_def.unwrap();
         let def_id = {
             let defs = self.resolver.definitions();
             let def_path_data = DefPathData::Binding(name);
-            let def_index = defs
-                .create_def_with_parent(parent_def, id, def_path_data, REGULAR_SPACE, Mark::root());
+            let def_index = defs.create_def_with_parent(parent_def,
+                                                        node_id,
+                                                        def_path_data,
+                                                        REGULAR_SPACE,
+                                                        Mark::root());
             DefId::local(def_index)
         };
 
         P(hir::Pat {
-            id,
+            id: node_id,
+            hir_id,
             node: hir::PatKind::Binding(bm,
                                         def_id,
                                         Spanned {
@@ -2740,8 +2787,10 @@ fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
     }
 
     fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
+        let LoweredNodeId { node_id, hir_id } = self.next_id();
         P(hir::Pat {
-            id: self.next_id(),
+            id: node_id,
+            hir_id,
             node: pat,
             span,
         })
@@ -2770,11 +2819,13 @@ fn signal_block_expr(&mut self,
                          rule: hir::BlockCheckMode,
                          attrs: ThinVec<Attribute>)
                          -> hir::Expr {
-        let id = self.next_id();
+        let LoweredNodeId { node_id, hir_id } = self.next_id();
+
         let block = P(hir::Block {
             rules: rule,
             span,
-            id,
+            id: node_id,
+            hir_id,
             stmts,
             expr: Some(expr),
             targeted_by_break: false,
@@ -2799,7 +2850,7 @@ fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
 
                     // The original ID is taken by the `PolyTraitRef`,
                     // so the `Ty` itself needs a different one.
-                    id = self.next_id();
+                    id = self.next_id().node_id;
 
                     hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span))
                 } else {
@@ -2813,7 +2864,7 @@ fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
 
     fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
         hir::Lifetime {
-            id: self.next_id(),
+            id: self.next_id().node_id,
             span,
             name: keywords::Invalid.name()
         }
index cdd5a6e3da7f1a6ff9d6a90abffaf6be1a787bb3..d3e3998360b602c114be14ae0b171769f9001e04 100644 (file)
@@ -465,6 +465,10 @@ pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
         self.node_to_hir_id[node_id]
     }
 
+    pub fn find_node_for_hir_id(&self, hir_id: hir::HirId) -> ast::NodeId {
+        self.node_to_hir_id.binary_search(&hir_id).unwrap()
+    }
+
     /// Add a definition with a parent definition.
     pub fn create_root_def(&mut self,
                            crate_name: &str,
index 45b1d6c184101bc2511be389378070dacd0cf715..3b73647f0eb0edde45a8570c27d70112634ad636 100644 (file)
@@ -357,6 +357,7 @@ fn dep_node(&self, id0: NodeId) -> DepNode {
         }
     }
 
+    #[inline]
     pub fn definitions(&self) -> &Definitions {
         &self.definitions
     }
@@ -377,6 +378,7 @@ pub fn def_path(&self, def_id: DefId) -> DefPath {
         self.definitions.def_path(def_id.index)
     }
 
+    #[inline]
     pub fn local_def_id(&self, node: NodeId) -> DefId {
         self.opt_local_def_id(node).unwrap_or_else(|| {
             bug!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
@@ -384,14 +386,21 @@ pub fn local_def_id(&self, node: NodeId) -> DefId {
         })
     }
 
+    #[inline]
     pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
         self.definitions.opt_local_def_id(node)
     }
 
+    #[inline]
     pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
         self.definitions.as_local_node_id(def_id)
     }
 
+    #[inline]
+    pub fn node_to_hir_id(&self, node_id: NodeId) -> HirId {
+        self.definitions.node_to_hir_id(node_id)
+    }
+
     fn entry_count(&self) -> usize {
         self.map.len()
     }
index efe0504aa18c4525236bbc453f6cd504673a3ec2..a2be74b552234350f7d9afe2e55ad2ef962a2675 100644 (file)
@@ -129,9 +129,11 @@ fn index(self) -> usize {
 
 pub const DUMMY_HIR_ID: HirId = HirId {
     owner: CRATE_DEF_INDEX,
-    local_id: ItemLocalId(!0)
+    local_id: DUMMY_ITEM_LOCAL_ID,
 };
 
+pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId(!0);
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub struct Lifetime {
     pub id: NodeId,
@@ -547,6 +549,7 @@ pub struct Block {
     /// without a semicolon, if any
     pub expr: Option<P<Expr>>,
     pub id: NodeId,
+    pub hir_id: HirId,
     /// Distinguishes between `unsafe { ... }` and `{ ... }`
     pub rules: BlockCheckMode,
     pub span: Span,
@@ -560,6 +563,7 @@ pub struct Block {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
 pub struct Pat {
     pub id: NodeId,
+    pub hir_id: HirId,
     pub node: PatKind,
     pub span: Span,
 }
@@ -986,6 +990,7 @@ pub struct Expr {
     pub span: Span,
     pub node: Expr_,
     pub attrs: ThinVec<Attribute>,
+    pub hir_id: HirId,
 }
 
 impl fmt::Debug for Expr {
@@ -1423,6 +1428,7 @@ pub struct InlineAsm {
 pub struct Arg {
     pub pat: P<Pat>,
     pub id: NodeId,
+    pub hir_id: HirId,
 }
 
 /// Represents the header (not the body) of a function declaration
index b344084f580bf37e52e7a08af1f433b62191860d..fca70de704f39c8df7ebbf62de4fba7587f8289a 100644 (file)
@@ -359,6 +359,7 @@ fn hash_stable<W: StableHasherResult>(&self,
             ref stmts,
             ref expr,
             id,
+            hir_id: _,
             rules,
             span,
             targeted_by_break,
@@ -423,6 +424,7 @@ fn hash_stable<W: StableHasherResult>(&self,
 
         let hir::Pat {
             id,
+            hir_id: _,
             ref node,
             ref span
         } = *self;
@@ -551,6 +553,7 @@ fn hash_stable<W: StableHasherResult>(&self,
         hcx.while_hashing_hir_bodies(true, |hcx| {
             let hir::Expr {
                 id,
+                hir_id: _,
                 ref span,
                 ref node,
                 ref attrs
@@ -1021,7 +1024,8 @@ fn hash_stable<W: StableHasherResult>(&self,
 
 impl_stable_hash_for!(struct hir::Arg {
     pat,
-    id
+    id,
+    hir_id
 });
 
 impl_stable_hash_for!(struct hir::Body {
index 8a37d7bab4445c9314b23a49ce04aeb20132aa78..37ef7e8cbfa3bfb1be89a42142d41a7d8998c693 100644 (file)
@@ -618,6 +618,7 @@ fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
                                           hasher: &mut StableHasher<W>) {
         let ty::TypeckTables {
+            local_id_root: _,
             ref type_dependent_defs,
             ref node_types,
             ref node_substs,
@@ -637,7 +638,9 @@ fn hash_stable<W: StableHasherResult>(&self,
         } = *self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs);
+            ich::hash_stable_hashmap(hcx, hasher, type_dependent_defs, |_, item_local_id| {
+                *item_local_id
+            });
             ich::hash_stable_nodemap(hcx, hasher, node_types);
             ich::hash_stable_nodemap(hcx, hasher, node_substs);
             ich::hash_stable_nodemap(hcx, hasher, adjustments);
index bf79becfe4a1077582efab02196ef529a4330c24..6aa84a97503300fcdefcc58c6eaee3f7f3a5ed93 100644 (file)
@@ -358,8 +358,8 @@ pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
 impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
     /// Used only by `rustc_typeck` during body type-checking/inference,
     /// will initialize `in_progress_tables` with fresh `TypeckTables`.
-    pub fn with_fresh_in_progress_tables(mut self) -> Self {
-        self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty()));
+    pub fn with_fresh_in_progress_tables(mut self, table_owner: DefId) -> Self {
+        self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty(table_owner)));
         self
     }
 
index 6ee06dc0a8163775af63b54ef02a158aa2e4091d..cd06806ca6017d7e79946c08f6a0601a427f9da3 100644 (file)
@@ -43,7 +43,7 @@
 use syntax_pos::{MultiSpan, Span};
 use errors::DiagnosticBuilder;
 use hir;
-use hir::def_id::LOCAL_CRATE;
+use hir::def_id::{DefId, LOCAL_CRATE};
 use hir::intravisit as hir_visit;
 use syntax::visit as ast_visit;
 
@@ -986,7 +986,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
 
     let mut cx = LateContext {
         tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &ty::TypeckTables::empty(DefId::invalid()),
         param_env: ty::ParamEnv::empty(Reveal::UserFacing),
         access_levels,
         lint_sess: LintSession::new(&tcx.sess.lint_store),
index 4e08bc90c7c3a5064bf80005a566bfdbc26e3bcc..4cf27981e1b68f87b631481ab0d5af15ea5f2b99 100644 (file)
@@ -94,7 +94,7 @@ fn handle_definition(&mut self, def: Def) {
         }
     }
 
-    fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
+    fn lookup_and_handle_method(&mut self, id: hir::ItemLocalId) {
         self.check_def_id(self.tables.type_dependent_defs[&id].def_id());
     }
 
@@ -119,6 +119,8 @@ fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
 
     fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def,
                                   pats: &[codemap::Spanned<hir::FieldPat>]) {
+
+
         let variant = match self.tables.node_id_to_type(lhs.id).sty {
             ty::TyAdt(adt, _) => adt.variant_of_def(def),
             _ => span_bug!(lhs.span, "non-ADT in struct pattern")
@@ -235,11 +237,11 @@ fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         match expr.node {
             hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => {
-                let def = self.tables.qpath_def(qpath, expr.id);
+                let def = self.tables.qpath_def(qpath, expr.hir_id);
                 self.handle_definition(def);
             }
             hir::ExprMethodCall(..) => {
-                self.lookup_and_handle_method(expr.id);
+                self.lookup_and_handle_method(expr.hir_id.local_id);
             }
             hir::ExprField(ref lhs, ref name) => {
                 self.handle_field_access(&lhs, name.node);
@@ -282,7 +284,7 @@ fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
                 self.handle_field_pattern_match(pat, path.def, fields);
             }
             PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => {
-                let def = self.tables.qpath_def(qpath, pat.id);
+                let def = self.tables.qpath_def(qpath, pat.hir_id);
                 self.handle_definition(def);
             }
             _ => ()
@@ -425,7 +427,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut symbol_visitor = MarkSymbolVisitor {
         worklist,
         tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &ty::TypeckTables::empty(DefId::invalid()),
         live_symbols: box FxHashSet(),
         struct_has_extern_repr: false,
         ignore_non_const_paths: false,
index fcf366788b22394a1901ccbc2e54bfae531076fe..e8ecf9c21cd357ef0407b5585d913aadadf7b7c9 100644 (file)
@@ -19,6 +19,7 @@
 use syntax_pos::Span;
 use hir::{self, PatKind};
 use hir::def::Def;
+use hir::def_id::DefId;
 use hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap};
 
 #[derive(Copy, Clone)]
@@ -165,7 +166,7 @@ fn visit_block(&mut self, block: &'tcx hir::Block) {
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         match expr.node {
             hir::ExprMethodCall(..) => {
-                let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
+                let def_id = self.tables.type_dependent_defs[&expr.hir_id.local_id].def_id();
                 let sig = self.tcx.fn_sig(def_id);
                 debug!("effect: method call case, signature is {:?}",
                         sig);
@@ -262,7 +263,7 @@ fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut visitor = EffectCheckVisitor {
         tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &ty::TypeckTables::empty(DefId::invalid()),
         body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID },
         unsafe_context: UnsafeContext::new(SafeContext),
     };
index 87e933e85e2289526a507535e5adb867f6abf905..80abe87470c2f8ac0b674390d7687697e0845029 100644 (file)
@@ -537,7 +537,7 @@ fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
             }
             ty::TyError => { }
             _ => {
-                let def_id = self.mc.tables.type_dependent_defs[&call.id].def_id();
+                let def_id = self.mc.tables.type_dependent_defs[&call.hir_id.local_id].def_id();
                 match OverloadedCallType::from_method_id(self.tcx(), def_id) {
                     FnMutOverloadedCall => {
                         let call_scope_r = self.tcx().node_scope_region(call.id);
@@ -863,7 +863,7 @@ fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: Mat
                 PatKind::Struct(ref qpath, ..) => qpath,
                 _ => return
             };
-            let def = mc.tables.qpath_def(qpath, pat.id);
+            let def = mc.tables.qpath_def(qpath, pat.hir_id);
             match def {
                 Def::Variant(variant_did) |
                 Def::VariantCtor(variant_did, ..) => {
index d29622b4a8159a028a351d98e01c31d293a27ccc..83278bd88e92d0e3b0305de5d48262b96208a6bb 100644 (file)
@@ -146,7 +146,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         let def = if let hir::ExprPath(ref qpath) = expr.node {
-            self.tables.qpath_def(qpath, expr.id)
+            self.tables.qpath_def(qpath, expr.hir_id)
         } else {
             Def::Err
         };
index b4993aafc4c9ed379f692e6848b1e74d4890e4b7..c6773250bde98cd5b2250ac2b270e557e38d7ae6 100644 (file)
@@ -604,7 +604,7 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
           }
 
           hir::ExprPath(ref qpath) => {
-            let def = self.tables.qpath_def(qpath, expr.id);
+            let def = self.tables.qpath_def(qpath, expr.hir_id);
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
@@ -1124,7 +1124,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResul
 
         match pat.node {
           PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
-            let def = self.tables.qpath_def(qpath, pat.id);
+            let def = self.tables.qpath_def(qpath, pat.hir_id);
             let (cmt, expected_len) = match def {
                 Def::Err => {
                     debug!("access to unresolvable pattern {:?}", pat);
@@ -1161,7 +1161,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResul
 
           PatKind::Struct(ref qpath, ref field_pats, _) => {
             // {f1: p1, ..., fN: pN}
-            let def = self.tables.qpath_def(qpath, pat.id);
+            let def = self.tables.qpath_def(qpath, pat.hir_id);
             let cmt = match def {
                 Def::Err => {
                     debug!("access to unresolvable pattern {:?}", pat);
index df828c8d8e71a7adc1de4dfb24e813adf39291b3..98f82a51267fea4423bbd01b028831364d9723a4 100644 (file)
@@ -107,10 +107,10 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         let def = match expr.node {
             hir::ExprPath(ref qpath) => {
-                Some(self.tables.qpath_def(qpath, expr.id))
+                Some(self.tables.qpath_def(qpath, expr.hir_id))
             }
             hir::ExprMethodCall(..) => {
-                Some(self.tables.type_dependent_defs[&expr.id])
+                Some(self.tables.type_dependent_defs[&expr.hir_id.local_id])
             }
             _ => None
         };
@@ -375,7 +375,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
     });
     let mut reachable_context = ReachableContext {
         tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &ty::TypeckTables::empty(DefId::invalid()),
         reachable_symbols: NodeSet(),
         worklist: Vec::new(),
         any_library,
index 6b9cbabf20e977887e59021f15c8b52f0b9775d7..46bb13c89ba7849efa7c83995525c77591c00752 100644 (file)
@@ -14,7 +14,7 @@
 use errors::DiagnosticBuilder;
 use session::Session;
 use middle;
-use hir::TraitMap;
+use hir::{TraitMap};
 use hir::def::{Def, ExportMap};
 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use hir::map as hir_map;
@@ -42,7 +42,7 @@
 use ty::maps;
 use ty::steal::Steal;
 use ty::BindingMode;
-use util::nodemap::{NodeMap, NodeSet, DefIdSet};
+use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap};
 use util::nodemap::{FxHashMap, FxHashSet};
 use rustc_data_structures::accumulate_vec::AccumulateVec;
 
@@ -209,9 +209,12 @@ pub struct CommonTypes<'tcx> {
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct TypeckTables<'tcx> {
+    /// The HirId::owner all ItemLocalIds in this table are relative to.
+    pub local_id_root: DefId,
+
     /// Resolved definitions for `<T>::X` associated paths and
     /// method calls, including those of overloaded operators.
-    pub type_dependent_defs: NodeMap<Def>,
+    pub type_dependent_defs: ItemLocalMap<Def>,
 
     /// Stores the types for various nodes in the AST.  Note that this table
     /// is not guaranteed to be populated until after typeck.  See
@@ -271,9 +274,10 @@ pub struct TypeckTables<'tcx> {
 }
 
 impl<'tcx> TypeckTables<'tcx> {
-    pub fn empty() -> TypeckTables<'tcx> {
+    pub fn empty(local_id_root: DefId) -> TypeckTables<'tcx> {
         TypeckTables {
-            type_dependent_defs: NodeMap(),
+            local_id_root,
+            type_dependent_defs: ItemLocalMap(),
             node_types: FxHashMap(),
             node_substs: NodeMap(),
             adjustments: NodeMap(),
@@ -291,11 +295,12 @@ pub fn empty() -> TypeckTables<'tcx> {
     }
 
     /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
-    pub fn qpath_def(&self, qpath: &hir::QPath, id: NodeId) -> Def {
+    pub fn qpath_def(&self, qpath: &hir::QPath, id: hir::HirId) -> Def {
         match *qpath {
             hir::QPath::Resolved(_, ref path) => path.def,
             hir::QPath::TypeRelative(..) => {
-                self.type_dependent_defs.get(&id).cloned().unwrap_or(Def::Err)
+                self.validate_hir_id(id);
+                self.type_dependent_defs.get(&id.local_id).cloned().unwrap_or(Def::Err)
             }
         }
     }
@@ -373,7 +378,8 @@ pub fn is_method_call(&self, expr: &hir::Expr) -> bool {
             return false;
         }
 
-        match self.type_dependent_defs.get(&expr.id) {
+        self.validate_hir_id(expr.hir_id);
+        match self.type_dependent_defs.get(&expr.hir_id.local_id) {
             Some(&Def::Method(_)) => true,
             _ => false
         }
@@ -382,6 +388,30 @@ pub fn is_method_call(&self, expr: &hir::Expr) -> bool {
     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
         self.upvar_capture_map[&upvar_id]
     }
+
+    /// Validate that a NodeId can safely be converted to an ItemLocalId for
+    /// this table.
+    #[inline]
+    pub fn validate_hir_id(&self, hir_id: hir::HirId) {
+        #[cfg(debug_assertions)]
+        {
+            if self.local_id_root.is_local() {
+                if hir_id.owner != self.local_id_root.index {
+                    ty::tls::with(|tcx| {
+                        let node_id = tcx.hir
+                                         .definitions()
+                                         .find_node_for_hir_id(hir_id);
+
+                        bug!("node {} with HirId::owner {:?} cannot be placed in \
+                              TypeckTables with local_id_root {:?}",
+                              tcx.hir.node_to_string(node_id),
+                              DefId::local(hir_id.owner),
+                              self.local_id_root)
+                    });
+                }
+            }
+        }
+    }
 }
 
 impl<'tcx> CommonTypes<'tcx> {
index b03011fcb216dbc4e783f695fde007bc384936b5..c397371c5c7672021fcca82928b05eb20ad49199 100644 (file)
@@ -13,6 +13,7 @@
 #![allow(non_snake_case)]
 
 use hir::def_id::DefId;
+use hir::ItemLocalId;
 use syntax::ast;
 
 pub use rustc_data_structures::fx::FxHashMap;
 
 pub type NodeMap<T> = FxHashMap<ast::NodeId, T>;
 pub type DefIdMap<T> = FxHashMap<DefId, T>;
+pub type ItemLocalMap<T> = FxHashMap<ItemLocalId, T>;
 
 pub type NodeSet = FxHashSet<ast::NodeId>;
 pub type DefIdSet = FxHashSet<DefId>;
 
 pub fn NodeMap<T>() -> NodeMap<T> { FxHashMap() }
 pub fn DefIdMap<T>() -> DefIdMap<T> { FxHashMap() }
+pub fn ItemLocalMap<T>() -> ItemLocalMap<T> { FxHashMap() }
 pub fn NodeSet() -> NodeSet { FxHashSet() }
 pub fn DefIdSet() -> DefIdSet { FxHashSet() }
 
index eb45fd9c0e0a44246c9fd8e558bac1aac050e9cd..cce511daf8ae7970882c6770a953d96561fcd853 100644 (file)
@@ -276,7 +276,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
       }
       hir::ExprPath(ref qpath) => {
         let substs = cx.tables.node_substs(e.id).subst(tcx, cx.substs);
-          match cx.tables.qpath_def(qpath, e.id) {
+          match cx.tables.qpath_def(qpath, e.hir_id) {
               Def::Const(def_id) |
               Def::AssociatedConst(def_id) => {
                     match tcx.at(e.span).const_eval(cx.param_env.and((def_id, substs))) {
index f37a112a596ac57e3f24fd0fc57ca7fe617fc8b6..30183ca2daf71ef9caebf47d5ea56e59329034af 100644 (file)
@@ -321,7 +321,7 @@ pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::Path(ref qpath) => {
-                return self.lower_path(qpath, pat.id, pat.id, pat.span);
+                return self.lower_path(qpath, (pat.id, pat.hir_id), pat.id, pat.span);
             }
 
             PatKind::Ref(ref subpattern, _) |
@@ -417,7 +417,7 @@ pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => {
-                let def = self.tables.qpath_def(qpath, pat.id);
+                let def = self.tables.qpath_def(qpath, pat.hir_id);
                 let adt_def = match ty.sty {
                     ty::TyAdt(adt_def, _) => adt_def,
                     _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"),
@@ -436,7 +436,7 @@ pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
             }
 
             PatKind::Struct(ref qpath, ref fields, _) => {
-                let def = self.tables.qpath_def(qpath, pat.id);
+                let def = self.tables.qpath_def(qpath, pat.hir_id);
                 let adt_def = match ty.sty {
                     ty::TyAdt(adt_def, _) => adt_def,
                     _ => {
@@ -590,12 +590,12 @@ fn lower_variant_or_leaf(
 
     fn lower_path(&mut self,
                   qpath: &hir::QPath,
-                  id: ast::NodeId,
+                  (id, hir_id): (ast::NodeId, hir::HirId),
                   pat_id: ast::NodeId,
                   span: Span)
                   -> Pattern<'tcx> {
         let ty = self.tables.node_id_to_type(id);
-        let def = self.tables.qpath_def(qpath, id);
+        let def = self.tables.qpath_def(qpath, hir_id);
         let kind = match def {
             Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                 let substs = self.tables.node_substs(id);
@@ -696,7 +696,7 @@ fn lower_const_expr(&mut self,
                     _ => bug!()
                 };
                 let ty = self.tables.node_id_to_type(callee.id);
-                let def = self.tables.qpath_def(qpath, callee.id);
+                let def = self.tables.qpath_def(qpath, callee.hir_id);
                 match def {
                     Def::Fn(..) | Def::Method(..) => self.lower_lit(expr),
                     _ => {
@@ -712,7 +712,7 @@ fn lower_const_expr(&mut self,
             }
 
             hir::ExprStruct(ref qpath, ref fields, None) => {
-                let def = self.tables.qpath_def(qpath, expr.id);
+                let def = self.tables.qpath_def(qpath, expr.hir_id);
                 let adt_def = match pat_ty.sty {
                     ty::TyAdt(adt_def, _) => adt_def,
                     _ => {
@@ -755,7 +755,7 @@ fn lower_const_expr(&mut self,
             }
 
             hir::ExprPath(ref qpath) => {
-                return self.lower_path(qpath, expr.id, pat_id, span);
+                return self.lower_path(qpath, (expr.id, expr.hir_id), pat_id, span);
             }
 
             _ => self.lower_lit(expr)
index 1f44378c9e6466f590f1c06aec59f9ef39d3e9a0..bc9bfa4049723fccdce3fc7aef4277a455a8b1d9 100644 (file)
@@ -196,6 +196,16 @@ pub fn resize(&mut self, new_len: usize, value: T) {
     }
 }
 
+impl<I: Idx, T: Ord> IndexVec<I, T> {
+    #[inline]
+    pub fn binary_search(&self, value: &T) -> Result<I, I> {
+        match self.raw.binary_search(value) {
+            Ok(i) => Ok(Idx::new(i)),
+            Err(i) => Err(Idx::new(i)),
+        }
+    }
+}
+
 impl<I: Idx, T> Index<I> for IndexVec<I, T> {
     type Output = T;
 
index 269363fdd2f98e270d3c2a991f4aec2c5d45ad33..51f5cc4f249f26268ed488ed5761f90c9529a772 100644 (file)
@@ -45,6 +45,7 @@
 use std::path::Path;
 use std::str::FromStr;
 
+use rustc::hir::def_id::DefId;
 use rustc::hir::map as hir_map;
 use rustc::hir::map::blocks;
 use rustc::hir;
@@ -232,7 +233,7 @@ fn call_with_pp_support_hir<'tcx, A, F>(&self,
                                                                  arenas,
                                                                  id,
                                                                  |tcx, _, _, _| {
-                    let empty_tables = ty::TypeckTables::empty();
+                    let empty_tables = ty::TypeckTables::empty(DefId::invalid());
                     let annotation = TypedAnnotation {
                         tcx: tcx,
                         tables: Cell::new(&empty_tables)
index 88432e64290316a85ef0bf6b35398fcea7feda13..85ec606e87efd993fa5ac78cb054c5eaf196c24f 100644 (file)
@@ -896,7 +896,7 @@ fn expr_refers_to_this_fn(cx: &LateContext, fn_id: ast::NodeId, id: ast::NodeId)
             match cx.tcx.hir.get(id) {
                 hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
                     let def = if let hir::ExprPath(ref qpath) = callee.node {
-                        cx.tables.qpath_def(qpath, callee.id)
+                        cx.tables.qpath_def(qpath, callee.hir_id)
                     } else {
                         return false;
                     };
@@ -934,7 +934,8 @@ fn expr_refers_to_this_method(cx: &LateContext,
 
             // Check for method calls and overloaded operators.
             if cx.tables.is_method_call(expr) {
-                let def_id = cx.tables.type_dependent_defs[&id].def_id();
+                let local_id = cx.tcx.hir.definitions().node_to_hir_id(id).local_id;
+                let def_id = cx.tables.type_dependent_defs[&local_id].def_id();
                 let substs = cx.tables.node_substs(id);
                 if method_call_refers_to_method(cx, method, def_id, substs, id) {
                     return true;
@@ -945,7 +946,7 @@ fn expr_refers_to_this_method(cx: &LateContext,
             match expr.node {
                 hir::ExprCall(ref callee, _) => {
                     let def = if let hir::ExprPath(ref qpath) = callee.node {
-                        cx.tables.qpath_def(qpath, callee.id)
+                        cx.tables.qpath_def(qpath, callee.hir_id)
                     } else {
                         return false;
                     };
@@ -1179,7 +1180,7 @@ fn get_transmute_from_to<'a, 'tcx>
              expr: &hir::Expr)
              -> Option<(&'tcx ty::TypeVariants<'tcx>, &'tcx ty::TypeVariants<'tcx>)> {
             let def = if let hir::ExprPath(ref qpath) = expr.node {
-                cx.tables.qpath_def(qpath, expr.id)
+                cx.tables.qpath_def(qpath, expr.hir_id)
             } else {
                 return None;
             };
index 06a0c4ff213da72149dd3e7edb24f6037fa7fb42..3effc29d67e2db9e18a1843863b08eb579272320 100644 (file)
@@ -450,7 +450,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         }
 
         hir::ExprPath(ref qpath) => {
-            let def = cx.tables().qpath_def(qpath, expr.id);
+            let def = cx.tables().qpath_def(qpath, expr.hir_id);
             convert_path_expr(cx, expr, def)
         }
 
@@ -580,7 +580,8 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                  -> Expr<'tcx> {
     let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
     let (def_id, substs) = custom_callee.unwrap_or_else(|| {
-        (cx.tables().type_dependent_defs[&expr.id].def_id(),
+        cx.tables().validate_hir_id(expr.hir_id);
+        (cx.tables().type_dependent_defs[&expr.hir_id.local_id].def_id(),
          cx.tables().node_substs(expr.id))
     });
     Expr {
index 8443cc8267d1c87dc1fad2fe439cbd846db361ab..b3a1509972a041acdbcee5b92d41b93c16fa6af1 100644 (file)
@@ -329,7 +329,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
         hir::ExprPath(ref qpath) => {
-            let def = v.tables.qpath_def(qpath, e.id);
+            let def = v.tables.qpath_def(qpath, e.hir_id);
             match def {
                 Def::VariantCtor(..) | Def::StructCtor(..) |
                 Def::Fn(..) | Def::Method(..) => {}
@@ -365,7 +365,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
             // The callee is an arbitrary expression, it doesn't necessarily have a definition.
             let def = if let hir::ExprPath(ref qpath) = callee.node {
-                v.tables.qpath_def(qpath, callee.id)
+                v.tables.qpath_def(qpath, callee.hir_id)
             } else {
                 Def::Err
             };
@@ -387,7 +387,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
         hir::ExprMethodCall(..) => {
-            let def_id = v.tables.type_dependent_defs[&e.id].def_id();
+            v.tables.validate_hir_id(e.hir_id);
+            let def_id = v.tables.type_dependent_defs[&e.hir_id.local_id].def_id();
             match v.tcx.associated_item(def_id).container {
                 ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty),
                 ty::TraitContainer(_) => v.promotable = false
@@ -471,7 +472,7 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir.krate().visit_all_item_likes(&mut CheckCrateVisitor {
         tcx: tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &ty::TypeckTables::empty(DefId::invalid()),
         in_fn: false,
         promotable: false,
         mut_rvalue_borrows: NodeSet(),
index 9fa5fea20d915885d4e3ab06194751fe79efa6ad..c1cab0cc8f744d1de90835e7630be8d0c59c95b9 100644 (file)
@@ -473,6 +473,7 @@ struct NamePrivacyVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
     current_item: ast::NodeId,
+    empty_tables: &'a ty::TypeckTables<'tcx>,
 }
 
 impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
@@ -489,6 +490,22 @@ fn check_field(&mut self, span: Span, def: &'tcx ty::AdtDef, field: &'tcx ty::Fi
     }
 }
 
+// Set the correct TypeckTables for the given `item_id` (or an empty table if
+// there is no TypeckTables for the item).
+fn update_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                           item_id: ast::NodeId,
+                           tables: &mut &'a ty::TypeckTables<'tcx>,
+                           empty_tables: &'a ty::TypeckTables<'tcx>)
+                           -> &'a ty::TypeckTables<'tcx> {
+    let def_id = tcx.hir.local_def_id(item_id);
+
+    if tcx.has_typeck_tables(def_id) {
+        replace(tables, tcx.typeck_tables_of(def_id))
+    } else {
+        replace(tables, empty_tables)
+    }
+}
+
 impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
@@ -505,14 +522,28 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let orig_current_item = replace(&mut self.current_item, item.id);
+        let orig_tables = update_tables(self.tcx, item.id, &mut self.tables, self.empty_tables);
         intravisit::walk_item(self, item);
         self.current_item = orig_current_item;
+        self.tables = orig_tables;
+    }
+
+    fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
+        let orig_tables = update_tables(self.tcx, ti.id, &mut self.tables, self.empty_tables);
+        intravisit::walk_trait_item(self, ti);
+        self.tables = orig_tables;
+    }
+
+    fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
+        let orig_tables = update_tables(self.tcx, ii.id, &mut self.tables, self.empty_tables);
+        intravisit::walk_impl_item(self, ii);
+        self.tables = orig_tables;
     }
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         match expr.node {
             hir::ExprStruct(ref qpath, ref fields, ref base) => {
-                let def = self.tables.qpath_def(qpath, expr.id);
+                let def = self.tables.qpath_def(qpath, expr.hir_id);
                 let adt = self.tables.expr_ty(expr).ty_adt_def().unwrap();
                 let variant = adt.variant_of_def(def);
                 if let Some(ref base) = *base {
@@ -539,7 +570,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
     fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
         match pat.node {
             PatKind::Struct(ref qpath, ref fields, _) => {
-                let def = self.tables.qpath_def(qpath, pat.id);
+                let def = self.tables.qpath_def(qpath, pat.hir_id);
                 let adt = self.tables.pat_ty(pat).ty_adt_def().unwrap();
                 let variant = adt.variant_of_def(def);
                 for field in fields {
@@ -564,6 +595,7 @@ struct TypePrivacyVisitor<'a, 'tcx: 'a> {
     tables: &'a ty::TypeckTables<'tcx>,
     current_item: DefId,
     span: Span,
+    empty_tables: &'a ty::TypeckTables<'tcx>,
 }
 
 impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
@@ -716,7 +748,8 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
             }
             hir::ExprMethodCall(_, span, _) => {
                 // Method calls have to be checked specially.
-                let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
+                self.tables.validate_hir_id(expr.hir_id);
+                let def_id = self.tables.type_dependent_defs[&expr.hir_id.local_id].def_id();
                 self.span = span;
                 if self.tcx.type_of(def_id).visit_with(self) {
                     return;
@@ -732,7 +765,9 @@ fn visit_qpath(&mut self, qpath: &'tcx hir::QPath, id: ast::NodeId, span: Span)
         // Inherent associated constants don't have self type in substs,
         // we have to check it additionally.
         if let hir::QPath::TypeRelative(..) = *qpath {
-            if let Some(def) = self.tables.type_dependent_defs.get(&id).cloned() {
+            let hir_id = self.tcx.hir.node_to_hir_id(id);
+            self.tables.validate_hir_id(hir_id);
+            if let Some(def) = self.tables.type_dependent_defs.get(&hir_id.local_id).cloned() {
                 if let Some(assoc_item) = self.tcx.opt_associated_item(def.def_id()) {
                     if let ty::ImplContainer(impl_def_id) = assoc_item.container {
                         if self.tcx.type_of(impl_def_id).visit_with(self) {
@@ -770,6 +805,10 @@ fn visit_local(&mut self, local: &'tcx hir::Local) {
     // Check types in item interfaces
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let orig_current_item = self.current_item;
+        let orig_tables = update_tables(self.tcx,
+                                        item.id,
+                                        &mut self.tables,
+                                        self.empty_tables);
 
         match item.node {
             hir::ItemExternCrate(..) | hir::ItemMod(..) |
@@ -829,8 +868,21 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
 
         self.current_item = self.tcx.hir.local_def_id(item.id);
         intravisit::walk_item(self, item);
+        self.tables = orig_tables;
         self.current_item = orig_current_item;
     }
+
+    fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
+        let orig_tables = update_tables(self.tcx, ti.id, &mut self.tables, self.empty_tables);
+        intravisit::walk_trait_item(self, ti);
+        self.tables = orig_tables;
+    }
+
+    fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
+        let orig_tables = update_tables(self.tcx, ii.id, &mut self.tables, self.empty_tables);
+        intravisit::walk_impl_item(self, ii);
+        self.tables = orig_tables;
+    }
 }
 
 impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
@@ -1606,11 +1658,15 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let krate = tcx.hir.krate();
 
+    let empty_tables = ty::TypeckTables::empty(DefId::invalid());
+
+
     // Check privacy of names not checked in previous compilation stages.
     let mut visitor = NamePrivacyVisitor {
         tcx: tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &empty_tables,
         current_item: CRATE_NODE_ID,
+        empty_tables: &empty_tables,
     };
     intravisit::walk_crate(&mut visitor, krate);
 
@@ -1618,9 +1674,10 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // inferred types of expressions and patterns.
     let mut visitor = TypePrivacyVisitor {
         tcx: tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &empty_tables,
         current_item: DefId::local(CRATE_DEF_INDEX),
         span: krate.span,
+        empty_tables: &empty_tables,
     };
     intravisit::walk_crate(&mut visitor, krate);
 
index 1dd0df4108fc6dc5708c0079c1ec19d033c7934e..d46d8624a12cab52c80697259ad423dbebc37edc 100644 (file)
@@ -550,7 +550,8 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
                 }
             }
             ast::ExprKind::MethodCall(..) => {
-                let method_id = self.tables.type_dependent_defs[&expr.id].def_id();
+                let local_id = self.tcx.hir.definitions().node_to_hir_id(expr.id).local_id;
+                let method_id = self.tables.type_dependent_defs[&local_id].def_id();
                 let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
                     ty::ImplContainer(_) => (Some(method_id), None),
                     ty::TraitContainer(_) => (None, Some(method_id)),
@@ -586,7 +587,8 @@ pub fn get_path_def(&self, id: NodeId) -> HirDef {
             Node::NodePat(&hir::Pat { node: hir::PatKind::Path(ref qpath), .. }) |
             Node::NodePat(&hir::Pat { node: hir::PatKind::Struct(ref qpath, ..), .. }) |
             Node::NodePat(&hir::Pat { node: hir::PatKind::TupleStruct(ref qpath, ..), .. }) => {
-                self.tables.qpath_def(qpath, id)
+                let hir_id = self.tcx.hir.node_to_hir_id(id);
+                self.tables.qpath_def(qpath, hir_id)
             }
 
             Node::NodeLocal(&hir::Pat { node: hir::PatKind::Binding(_, def_id, ..), .. }) => {
@@ -975,7 +977,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(tcx: TyCtxt<'l, 'tcx, 'tcx>,
 
     let save_ctxt = SaveContext {
         tcx: tcx,
-        tables: &ty::TypeckTables::empty(),
+        tables: &ty::TypeckTables::empty(DefId::invalid()),
         analysis: analysis,
         span_utils: SpanUtils::new(&tcx.sess),
         config: find_config(config),
index a0801a7486654580f86ef2e6a8e5717fba2c6342..cdf1c3b235b67a6dcd23e7aede8612110d5be747 100644 (file)
@@ -222,7 +222,7 @@ fn confirm_builtin_call(&self,
 
                 if let hir::ExprCall(ref expr, _) = call_expr.node {
                     let def = if let hir::ExprPath(ref qpath) = expr.node {
-                        self.tables.borrow().qpath_def(qpath, expr.id)
+                        self.tables.borrow().qpath_def(qpath, expr.hir_id)
                     } else {
                         Def::Err
                     };
@@ -314,7 +314,7 @@ fn confirm_overloaded_call(&self,
                                                            TupleArgumentsFlag::TupleArguments,
                                                            expected);
 
-        self.write_method_call(call_expr.id, method_callee);
+        self.write_method_call((call_expr.id, call_expr.hir_id), method_callee);
         output_type
     }
 }
@@ -364,7 +364,8 @@ pub fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
                 adjustments.extend(autoref);
                 fcx.apply_adjustments(self.callee_expr, adjustments);
 
-                fcx.write_method_call(self.call_expr.id, method_callee);
+                fcx.write_method_call((self.call_expr.id, self.call_expr.hir_id),
+                                      method_callee);
             }
             None => {
                 span_bug!(self.call_expr.span,
index b6a5ce0a6ce5adeef49a88d7733fa6a329da2ea0..a6f904b0c96c48f0e437acee9fbb94d4755c20a1 100644 (file)
@@ -513,7 +513,7 @@ fn convert_lvalue_op_to_mutable(&self,
             None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed")
         };
         debug!("convert_lvalue_op_to_mutable: method={:?}", method);
-        self.write_method_call(expr.id, method);
+        self.write_method_call((expr.id, expr.hir_id), method);
 
         let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty {
             (r, mt.mutbl)
index 697d9de931a86068973df2c5358193846905d77e..885472a76a92f6977433a2c4eb2369a6f2c4ca30 100644 (file)
@@ -572,8 +572,16 @@ pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
 impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
     pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
                  -> InheritedBuilder<'a, 'gcx, 'tcx> {
+        let hir_id_root = if def_id.is_local() {
+            let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+            let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
+            DefId::local(hir_id.owner)
+        } else {
+            def_id
+        };
+
         InheritedBuilder {
-            infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(),
+            infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
             def_id,
         }
     }
@@ -840,7 +848,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     });
     let body = tcx.hir.body(body_id);
 
-    Inherited::build(tcx, def_id).enter(|inh| {
+    let tables = Inherited::build(tcx, def_id).enter(|inh| {
         let param_env = tcx.param_env(def_id);
         let fcx = if let Some(decl) = fn_decl {
             let fn_sig = tcx.fn_sig(def_id);
@@ -887,7 +895,13 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
 
         fcx.resolve_type_vars_in_body(body)
-    })
+    });
+
+    // Consistency check our TypeckTables instance can hold all ItemLocalIds
+    // it will need to hold.
+    assert_eq!(tables.local_id_root,
+               DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner));
+    tables
 }
 
 fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
@@ -1804,8 +1818,16 @@ pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
         }
     }
 
-    pub fn write_method_call(&self, node_id: ast::NodeId, method: MethodCallee<'tcx>) {
-        self.tables.borrow_mut().type_dependent_defs.insert(node_id, Def::Method(method.def_id));
+    // The NodeId and the ItemLocalId must identify the same item. We just pass
+    // both of them for consistency checking.
+    pub fn write_method_call(&self,
+                             (node_id, hir_id): (ast::NodeId, hir::HirId),
+                             method: MethodCallee<'tcx>) {
+        {
+            let mut tables = self.tables.borrow_mut();
+            tables.validate_hir_id(hir_id);
+            tables.type_dependent_defs.insert(hir_id.local_id, Def::Method(method.def_id));
+        }
         self.write_substs(node_id, method.substs);
     }
 
@@ -2254,7 +2276,7 @@ fn try_index_step(&self,
                 }
                 self.apply_adjustments(base_expr, adjustments);
 
-                self.write_method_call(expr.id, method);
+                self.write_method_call((expr.id, expr.hir_id), method);
                 (input_ty, self.make_overloaded_lvalue_return_type(method).ty)
             });
             if result.is_some() {
@@ -2794,7 +2816,7 @@ fn check_method_call(&self,
                                               expr,
                                               rcvr) {
             Ok(method) => {
-                self.write_method_call(expr.id, method);
+                self.write_method_call((expr.id, expr.hir_id), method);
                 Ok(method)
             }
             Err(error) => {
@@ -3499,7 +3521,7 @@ fn check_expr_kind(&self,
                                 }]);
                             }
                             oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
-                            self.write_method_call(expr.id, method);
+                            self.write_method_call((expr.id, expr.hir_id), method);
                         } else {
                             type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
                                                "type `{}` cannot be dereferenced",
@@ -4000,7 +4022,10 @@ fn finish_resolving_struct_path(&self,
                                                                    ty, def, segment);
 
                 // Write back the new resolution.
-                self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
+                let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+                let mut tables = self.tables.borrow_mut();
+                tables.validate_hir_id(hir_id);
+                tables.type_dependent_defs.insert(hir_id.local_id, def);
 
                 (def, ty)
             }
@@ -4041,7 +4066,10 @@ pub fn resolve_ty_and_def_ufcs<'b>(&self,
         };
 
         // Write back the new resolution.
-        self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
+        let hir_id = self.tcx.hir.node_to_hir_id(node_id);
+        let mut tables = self.tables.borrow_mut();
+        tables.validate_hir_id(hir_id);
+        tables.type_dependent_defs.insert(hir_id.local_id, def);
         (def, Some(ty), slice::ref_slice(&**item_segment))
     }
 
index c1711491ee48ca2427d0dbfc4f49d3dee71d160b..71457377b10888aeabf6cce04f5be5fb28586205 100644 (file)
@@ -214,7 +214,7 @@ fn check_overloaded_binop(&self,
                             .or_insert(vec![]).push(autoref);
                     }
                 }
-                self.write_method_call(expr.id, method);
+                self.write_method_call((expr.id, expr.hir_id), method);
 
                 method.sig.output()
             }
@@ -340,7 +340,7 @@ pub fn check_user_unop(&self,
         assert!(op.is_by_value());
         match self.lookup_op_method(operand_ty, &[], Op::Unary(op, ex.span)) {
             Ok(method) => {
-                self.write_method_call(ex.id, method);
+                self.write_method_call((ex.id, ex.hir_id), method);
                 method.sig.output()
             }
             Err(()) => {
index 9e5cf5137c21f9f18c66d153c40f7e2cba5b620c..93d0e6e976a700d9ba2657e3cb36a43897dcfa1d 100644 (file)
@@ -14,6 +14,7 @@
 
 use check::FnCtxt;
 use rustc::hir;
+use rustc::hir::def_id::DefId;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::infer::{InferCtxt};
 use rustc::ty::{self, Ty, TyCtxt};
@@ -34,7 +35,7 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body)
 
         let mut wbcx = WritebackCx::new(self, body);
         for arg in &body.arguments {
-            wbcx.visit_node_id(arg.pat.span, arg.id);
+            wbcx.visit_node_id(arg.pat.span, (arg.id, arg.hir_id));
         }
         wbcx.visit_body(body);
         wbcx.visit_upvar_borrow_map();
@@ -74,10 +75,13 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
 
 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, body: &'gcx hir::Body)
-        -> WritebackCx<'cx, 'gcx, 'tcx> {
+        -> WritebackCx<'cx, 'gcx, 'tcx>
+    {
+        let owner = fcx.tcx.hir.definitions().node_to_hir_id(body.id().node_id);
+
         WritebackCx {
             fcx: fcx,
-            tables: ty::TypeckTables::empty(),
+            tables: ty::TypeckTables::empty(DefId::local(owner.owner)),
             body: body
         }
     }
@@ -105,7 +109,8 @@ fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
 
                 if inner_ty.is_scalar() {
                     let mut tables = self.fcx.tables.borrow_mut();
-                    tables.type_dependent_defs.remove(&e.id);
+                    tables.validate_hir_id(e.hir_id);
+                    tables.type_dependent_defs.remove(&e.hir_id.local_id);
                     tables.node_substs.remove(&e.id);
                 }
             }
@@ -119,7 +124,8 @@ fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
 
                 if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
                     let mut tables = self.fcx.tables.borrow_mut();
-                    tables.type_dependent_defs.remove(&e.id);
+                    tables.validate_hir_id(e.hir_id);
+                    tables.type_dependent_defs.remove(&e.hir_id.local_id);
                     tables.node_substs.remove(&e.id);
 
                     match e.node {
@@ -157,12 +163,12 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
     fn visit_expr(&mut self, e: &'gcx hir::Expr) {
         self.fix_scalar_builtin_expr(e);
 
-        self.visit_node_id(e.span, e.id);
+        self.visit_node_id(e.span, (e.id, e.hir_id));
 
         if let hir::ExprClosure(_, _, body, _) = e.node {
             let body = self.fcx.tcx.hir.body(body);
             for arg in &body.arguments {
-                self.visit_node_id(e.span, arg.id);
+                self.visit_node_id(e.span, (arg.id, arg.hir_id));
             }
 
             self.visit_body(body);
@@ -172,7 +178,7 @@ fn visit_expr(&mut self, e: &'gcx hir::Expr) {
     }
 
     fn visit_block(&mut self, b: &'gcx hir::Block) {
-        self.visit_node_id(b.span, b.id);
+        self.visit_node_id(b.span, (b.id, b.hir_id));
         intravisit::walk_block(self, b);
     }
 
@@ -186,7 +192,7 @@ fn visit_pat(&mut self, p: &'gcx hir::Pat) {
             _ => {}
         };
 
-        self.visit_node_id(p.span, p.id);
+        self.visit_node_id(p.span, (p.id, p.hir_id));
         intravisit::walk_pat(self, p);
     }
 
@@ -277,10 +283,17 @@ fn visit_anon_types(&mut self) {
         }
     }
 
-    fn visit_node_id(&mut self, span: Span, node_id: ast::NodeId) {
-        // Export associated path extensions and method resultions.
-        if let Some(def) = self.fcx.tables.borrow_mut().type_dependent_defs.remove(&node_id) {
-            self.tables.type_dependent_defs.insert(node_id, def);
+    fn visit_node_id(&mut self,
+                     span: Span,
+                     (node_id, hir_id): (ast::NodeId, hir::HirId)) {
+        {
+            let mut fcx_tables = self.fcx.tables.borrow_mut();
+            fcx_tables.validate_hir_id(hir_id);
+            // Export associated path extensions and method resultions.
+            if let Some(def) = fcx_tables.type_dependent_defs.remove(&hir_id.local_id) {
+                self.tables.validate_hir_id(hir_id);
+                self.tables.type_dependent_defs.insert(hir_id.local_id, def);
+            }
         }
 
         // Resolve any borrowings for the node with id `node_id`