diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 421a81c0d2342..356d8209ce55c 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -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 @@ impl<'a> LoweringContext<'a> { fn lower_node_id_generic(&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 @@ impl<'a> LoweringContext<'a> { 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(&mut self, owner: NodeId, f: F) @@ -323,7 +341,7 @@ impl<'a> LoweringContext<'a> { /// 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { }; 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 @@ impl<'a> LoweringContext<'a> { // Otherwise, the base path is an implicit `Self` type path, // e.g. `Vec` in `Vec::new` or `::Item` in // `::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 @@ impl<'a> LoweringContext<'a> { } // 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); } @@ -886,8 +904,10 @@ impl<'a> LoweringContext<'a> { } fn lower_local(&mut self, l: &Local) -> P { + let LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id); P(hir::Local { - id: self.lower_node_id(l.id), + id: node_id, + hir_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 +925,10 @@ impl<'a> LoweringContext<'a> { } 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 +991,7 @@ impl<'a> LoweringContext<'a> { } 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 +1009,7 @@ impl<'a> LoweringContext<'a> { 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 +1081,7 @@ impl<'a> LoweringContext<'a> { 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 +1120,7 @@ impl<'a> LoweringContext<'a> { 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 +1136,16 @@ impl<'a> LoweringContext<'a> { .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 +1156,7 @@ impl<'a> LoweringContext<'a> { }; 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 +1171,7 @@ impl<'a> LoweringContext<'a> { 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 +1220,11 @@ impl<'a> LoweringContext<'a> { } } + 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 +1274,7 @@ impl<'a> LoweringContext<'a> { 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 +1412,7 @@ impl<'a> LoweringContext<'a> { 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 +1473,7 @@ impl<'a> LoweringContext<'a> { 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 +1565,7 @@ impl<'a> LoweringContext<'a> { }); Some(hir::Item { - id: self.lower_node_id(i.id), + id: self.lower_node_id(i.id).node_id, name, attrs, node, @@ -1552,7 +1577,7 @@ impl<'a> LoweringContext<'a> { 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 +1655,11 @@ impl<'a> LoweringContext<'a> { } fn lower_pat(&mut self, p: &Pat) -> P { + 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 +1841,7 @@ impl<'a> LoweringContext<'a> { 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 +1911,15 @@ impl<'a> LoweringContext<'a> { // 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 +2018,11 @@ impl<'a> LoweringContext<'a> { 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 +2269,7 @@ impl<'a> LoweringContext<'a> { 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 +2289,7 @@ impl<'a> LoweringContext<'a> { 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 +2301,10 @@ impl<'a> LoweringContext<'a> { // `[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 +2443,11 @@ impl<'a> LoweringContext<'a> { 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 +2460,7 @@ impl<'a> LoweringContext<'a> { 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 +2471,22 @@ impl<'a> LoweringContext<'a> { 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 +2517,9 @@ impl<'a> LoweringContext<'a> { 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 +2661,10 @@ impl<'a> LoweringContext<'a> { } fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec) -> 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, @@ -2635,17 +2677,20 @@ impl<'a> LoweringContext<'a> { pat: P, source: hir::LocalSource) -> hir::Stmt { + let LoweredNodeId { node_id, hir_id } = self.next_id(); + let local = P(hir::Local { pat, ty: None, init: ex, - id: self.next_id(), + id: node_id, + hir_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) @@ -2665,10 +2710,13 @@ impl<'a> LoweringContext<'a> { fn block_all(&mut self, span: Span, stmts: hir::HirVec, expr: Option>) -> 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 +2760,22 @@ impl<'a> LoweringContext<'a> { fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation) -> P { - 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 +2792,10 @@ impl<'a> LoweringContext<'a> { } fn pat(&mut self, span: Span, pat: hir::PatKind) -> P { + 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 +2824,13 @@ impl<'a> LoweringContext<'a> { rule: hir::BlockCheckMode, attrs: ThinVec) -> 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 +2855,7 @@ impl<'a> LoweringContext<'a> { // 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 +2869,7 @@ impl<'a> LoweringContext<'a> { 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() } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index cdd5a6e3da7f1..b371366bc5d55 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -434,18 +434,22 @@ impl Definitions { DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p)) } + #[inline] pub fn opt_def_index(&self, node: ast::NodeId) -> Option { self.node_to_def_index.get(&node).cloned() } + #[inline] pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { self.opt_def_index(node).map(DefId::local) } + #[inline] pub fn local_def_id(&self, node: ast::NodeId) -> DefId { self.opt_local_def_id(node).unwrap() } + #[inline] pub fn as_local_node_id(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { let space_index = def_id.index.address_space().index(); @@ -461,10 +465,27 @@ impl Definitions { } } + #[inline] 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 + .iter() + .position(|x| *x == hir_id) + .map(|idx| ast::NodeId::new(idx)) + .unwrap() + } + + #[inline] + pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId { + let space_index = def_index.address_space().index(); + let array_index = def_index.as_array_index(); + let node_id = self.def_index_to_node[space_index][array_index]; + self.node_to_hir_id[node_id] + } + /// Add a definition with a parent definition. pub fn create_root_def(&mut self, crate_name: &str, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 45b1d6c184101..99ed4736a512d 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -357,6 +357,7 @@ impl<'hir> Map<'hir> { } } + #[inline] pub fn definitions(&self) -> &Definitions { &self.definitions } @@ -377,6 +378,7 @@ impl<'hir> Map<'hir> { 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,31 @@ impl<'hir> Map<'hir> { }) } + #[inline] pub fn opt_local_def_id(&self, node: NodeId) -> Option { self.definitions.opt_local_def_id(node) } + #[inline] pub fn as_local_node_id(&self, def_id: DefId) -> Option { 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) + } + + #[inline] + pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> HirId { + self.definitions.def_index_to_hir_id(def_index) + } + + #[inline] + pub fn def_index_to_node_id(&self, def_index: DefIndex) -> NodeId { + self.definitions.as_local_node_id(DefId::local(def_index)).unwrap() + } + fn entry_count(&self) -> usize { self.map.len() } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index efe0504aa18c4..1831814b0f4c4 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -129,9 +129,11 @@ pub const CRATE_HIR_ID: HirId = HirId { 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>, 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, } @@ -897,6 +901,7 @@ pub struct Local { /// Initializer expression to set the value, if any pub init: Option>, pub id: NodeId, + pub hir_id: HirId, pub span: Span, pub attrs: ThinVec, pub source: LocalSource, @@ -986,6 +991,7 @@ pub struct Expr { pub span: Span, pub node: Expr_, pub attrs: ThinVec, + pub hir_id: HirId, } impl fmt::Debug for Expr { @@ -1423,6 +1429,7 @@ pub struct InlineAsm { pub struct Arg { pub pat: P, pub id: NodeId, + pub hir_id: HirId, } /// Represents the header (not the body) of a function declaration diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 8ce1b39d934d1..218483232d673 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -14,7 +14,7 @@ use hir::map::DefPathHash; use ich::{self, CachingCodemapView}; use session::config::DebugInfoLevel::NoDebugInfo; use ty; -use util::nodemap::NodeMap; +use util::nodemap::{NodeMap, ItemLocalMap}; use std::hash as std_hash; use std::collections::{HashMap, HashSet, BTreeMap}; @@ -358,6 +358,18 @@ pub fn hash_stable_nodemap<'a, 'tcx, 'gcx, V, W>( }); } +pub fn hash_stable_itemlocalmap<'a, 'tcx, 'gcx, V, W>( + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher, + map: &ItemLocalMap) + where V: HashStable>, + W: StableHasherResult, +{ + hash_stable_hashmap(hcx, hasher, map, |_, local_id| { + *local_id + }); +} + pub fn hash_stable_btreemap<'a, 'tcx, 'gcx, K, V, SK, F, W>( hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index b344084f580bf..4c70816c0b833 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -359,6 +359,7 @@ impl<'a, 'gcx, 'tcx> HashStable> for hir::B ref stmts, ref expr, id, + hir_id: _, rules, span, targeted_by_break, @@ -423,6 +424,7 @@ impl<'a, 'gcx, 'tcx> HashStable> for hir::P let hir::Pat { id, + hir_id: _, ref node, ref span } = *self; @@ -504,6 +506,7 @@ impl_stable_hash_for!(struct hir::Local { ty, init, id, + hir_id, span, attrs, source @@ -551,6 +554,7 @@ impl<'a, 'gcx, 'tcx> HashStable> for hir::E hcx.while_hashing_hir_bodies(true, |hcx| { let hir::Expr { id, + hir_id: _, ref span, ref node, ref attrs @@ -1021,7 +1025,8 @@ impl_stable_hash_for!(enum hir::Stmt_ { impl_stable_hash_for!(struct hir::Arg { pat, - id + id, + hir_id }); impl_stable_hash_for!(struct hir::Body { diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 8a37d7bab4445..45b2a4a1e9667 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -11,7 +11,7 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::ty in no particular order. -use ich::{self, StableHashingContext, NodeIdHashingMode}; +use ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use std::hash as std_hash; @@ -611,64 +611,6 @@ impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> { ty }); - -impl<'a, 'gcx, 'tcx> HashStable> -for ty::TypeckTables<'gcx> { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher) { - let ty::TypeckTables { - ref type_dependent_defs, - ref node_types, - ref node_substs, - ref adjustments, - ref pat_binding_modes, - ref upvar_capture_map, - ref closure_tys, - ref closure_kinds, - ref liberated_fn_sigs, - ref fru_field_types, - - ref cast_kinds, - - ref used_trait_imports, - tainted_by_errors, - ref free_region_map, - } = *self; - - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs); - ich::hash_stable_nodemap(hcx, hasher, node_types); - ich::hash_stable_nodemap(hcx, hasher, node_substs); - ich::hash_stable_nodemap(hcx, hasher, adjustments); - ich::hash_stable_nodemap(hcx, hasher, pat_binding_modes); - ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| { - let ty::UpvarId { - var_id, - closure_expr_id - } = *up_var_id; - - let var_def_id = hcx.tcx().hir.local_def_id(var_id); - let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id); - (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id)) - }); - - ich::hash_stable_nodemap(hcx, hasher, closure_tys); - ich::hash_stable_nodemap(hcx, hasher, closure_kinds); - ich::hash_stable_nodemap(hcx, hasher, liberated_fn_sigs); - ich::hash_stable_nodemap(hcx, hasher, fru_field_types); - ich::hash_stable_nodemap(hcx, hasher, cast_kinds); - - ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| { - hcx.def_path_hash(*def_id) - }); - - tainted_by_errors.hash_stable(hcx, hasher); - free_region_map.hash_stable(hcx, hasher); - }) - } -} - impl_stable_hash_for!(enum ty::fast_reject::SimplifiedType { BoolSimplifiedType, CharSimplifiedType, diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index 5b23809085053..dcf84be0eeb3a 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -14,7 +14,7 @@ pub use self::fingerprint::Fingerprint; pub use self::caching_codemap_view::CachingCodemapView; pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_hashmap, hash_stable_hashset, hash_stable_nodemap, - hash_stable_btreemap}; + hash_stable_btreemap, hash_stable_itemlocalmap}; mod fingerprint; mod caching_codemap_view; mod hcx; diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 9f70b4834ddc5..b5390da7e852d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -913,7 +913,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } infer::UpvarRegion(ref upvar_id, _) => { format!(" for capture of `{}` by closure", - self.tcx.local_var_name_str(upvar_id.var_id).to_string()) + self.tcx.local_var_name_str_def_index(upvar_id.var_id)) } }; diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index a684881c0912a..22d9a9e313b77 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -8,13 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use hir::{self, Local, Pat, Body}; +use hir::{self, Local, Pat, Body, HirId}; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use infer::InferCtxt; use infer::type_variable::TypeVariableOrigin; use ty::{self, Ty, TyInfer, TyVar}; - -use syntax::ast::NodeId; use syntax_pos::Span; struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { @@ -26,7 +24,7 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { } impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { - fn node_matches_type(&mut self, node_id: NodeId) -> bool { + fn node_matches_type(&mut self, node_id: HirId) -> bool { let ty_opt = self.infcx.in_progress_tables.and_then(|tables| { tables.borrow().node_id_to_type_opt(node_id) }); @@ -56,7 +54,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { } fn visit_local(&mut self, local: &'gcx Local) { - if self.found_local_pattern.is_none() && self.node_matches_type(local.id) { + if self.found_local_pattern.is_none() && self.node_matches_type(local.hir_id) { self.found_local_pattern = Some(&*local.pat); } intravisit::walk_local(self, local); @@ -64,7 +62,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { fn visit_body(&mut self, body: &'gcx Body) { for argument in &body.arguments { - if self.found_arg_pattern.is_none() && self.node_matches_type(argument.id) { + if self.found_arg_pattern.is_none() && self.node_matches_type(argument.hir_id) { self.found_arg_pattern = Some(&*argument.pat); } } diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 963c14c48c829..87047d0df144c 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -45,8 +45,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_note(span, &format!("...so that closure can access `{}`", self.tcx - .local_var_name_str(upvar_id.var_id) - .to_string())); + .local_var_name_str_def_index(upvar_id.var_id))); } infer::InfStackClosure(span) => { err.span_note(span, "...so that closure does not outlive its stack frame"); @@ -176,18 +175,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { E0313, "lifetime of borrowed pointer outlives lifetime \ of captured variable `{}`...", - self.tcx.local_var_name_str(upvar_id.var_id)); + self.tcx + .local_var_name_str_def_index(upvar_id.var_id)); self.tcx.note_and_explain_region(&mut err, "...the borrowed pointer is valid for ", sub, "..."); self.tcx - .note_and_explain_region(&mut err, - &format!("...but `{}` is only valid for ", - self.tcx - .local_var_name_str(upvar_id.var_id)), - sup, - ""); + .note_and_explain_region( + &mut err, + &format!("...but `{}` is only valid for ", + self.tcx.local_var_name_str_def_index(upvar_id.var_id)), + sup, + ""); err } infer::InfStackClosure(span) => { diff --git a/src/librustc/infer/error_reporting/util.rs b/src/librustc/infer/error_reporting/util.rs index 14fe8e699c7f2..c8f78367420e6 100644 --- a/src/librustc/infer/error_reporting/util.rs +++ b/src/librustc/infer/error_reporting/util.rs @@ -46,7 +46,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .iter() .enumerate() .filter_map(|(index, arg)| { - let ty = tables.borrow().node_id_to_type(arg.id); + let ty = tables.borrow().node_id_to_type(arg.hir_id); let mut found_anon_region = false; let new_arg_ty = self.tcx .fold_regions(&ty, &mut false, |r, _| if *r == *anon_region { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index bf79becfe4a10..186eab724db36 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -358,8 +358,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { 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(Some(table_owner)))); self } @@ -1331,9 +1331,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { { if let Some(tables) = self.in_progress_tables { if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { + let hir_id = self.tcx.hir.node_to_hir_id(id); return tables.borrow() - .closure_kinds - .get(&id) + .closure_kinds() + .get(hir_id) .cloned() .map(|(kind, _)| kind); } @@ -1353,7 +1354,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn fn_sig(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> { if let Some(tables) = self.in_progress_tables { if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { - if let Some(&ty) = tables.borrow().closure_tys.get(&id) { + let hir_id = self.tcx.hir.node_to_hir_id(id); + if let Some(&ty) = tables.borrow().closure_tys().get(hir_id) { return ty; } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6ee06dc0a8163..930e8e7509083 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -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(None), param_env: ty::ParamEnv::empty(Reveal::UserFacing), access_levels, lint_sess: LintSession::new(&tcx.sess.lint_store), diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 4e08bc90c7c3a..8a2b115e58d3d 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -94,8 +94,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } - fn lookup_and_handle_method(&mut self, id: ast::NodeId) { - self.check_def_id(self.tables.type_dependent_defs[&id].def_id()); + fn lookup_and_handle_method(&mut self, id: hir::HirId) { + self.check_def_id(self.tables.type_dependent_defs()[id].def_id()); } fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) { @@ -119,7 +119,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def, pats: &[codemap::Spanned]) { - let variant = match self.tables.node_id_to_type(lhs.id).sty { + let variant = match self.tables.node_id_to_type(lhs.hir_id).sty { ty::TyAdt(adt, _) => adt.variant_of_def(def), _ => span_bug!(lhs.span, "non-ADT in struct pattern") }; @@ -235,11 +235,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { 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); } hir::ExprField(ref lhs, ref name) => { self.handle_field_access(&lhs, name.node); @@ -282,7 +282,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { 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 +425,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(None), live_symbols: box FxHashSet(), struct_has_extern_repr: false, ignore_non_const_paths: false, diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index fcf366788b223..98934d6070328 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -165,7 +165,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { 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].def_id(); let sig = self.tcx.fn_sig(def_id); debug!("effect: method call case, signature is {:?}", sig); @@ -262,7 +262,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut visitor = EffectCheckVisitor { tcx, - tables: &ty::TypeckTables::empty(), + tables: &ty::TypeckTables::empty(None), body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID }, unsafe_context: UnsafeContext::new(SafeContext), }; diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 87e933e85e228..324f9a6e9061f 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -296,7 +296,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { debug!("consume_body(body={:?})", body); for arg in &body.arguments { - let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.id)); + let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.hir_id)); let fn_body_scope_r = self.tcx().node_scope_region(body.value.id); let arg_cmt = self.mc.cat_rvalue( @@ -537,7 +537,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } 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].def_id(); match OverloadedCallType::from_method_id(self.tcx(), def_id) { FnMutOverloadedCall => { let call_scope_r = self.tcx().node_scope_region(call.id); @@ -797,7 +797,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pat); return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |cmt_pat, pat| { if let PatKind::Binding(..) = pat.node { - let bm = *self.mc.tables.pat_binding_modes.get(&pat.id) + let bm = *self.mc.tables.pat_binding_modes().get(pat.hir_id) .expect("missing binding mode"); match bm { ty::BindByReference(..) => @@ -823,10 +823,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| { if let PatKind::Binding(_, def_id, ..) = pat.node { debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode); - let bm = *mc.tables.pat_binding_modes.get(&pat.id).expect("missing binding mode"); + let bm = *mc.tables.pat_binding_modes().get(pat.hir_id) + .expect("missing binding mode"); // pat_ty: the type of the binding being produced. - let pat_ty = return_if_err!(mc.node_ty(pat.id)); + let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); // Each match binding is effectively an assignment to the // binding being produced. @@ -863,7 +864,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { 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, ..) => { @@ -887,10 +888,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.tcx().with_freevars(closure_expr.id, |freevars| { for freevar in freevars { - let def_id = freevar.def.def_id(); - let id_var = self.tcx().hir.as_local_node_id(def_id).unwrap(); - let upvar_id = ty::UpvarId { var_id: id_var, - closure_expr_id: closure_expr.id }; + let var_def_id = freevar.def.def_id(); + debug_assert!(var_def_id.is_local()); + let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id); + let upvar_id = ty::UpvarId { + var_id: var_def_id.index, + closure_expr_id: closure_def_id.index + }; let upvar_capture = self.mc.tables.upvar_capture(upvar_id); let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id, fn_decl_span, @@ -923,8 +927,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { -> mc::McResult> { // Create the cmt for the variable being borrowed, from the // caller's perspective - let var_id = self.tcx().hir.as_local_node_id(upvar_def.def_id()).unwrap(); - let var_ty = self.mc.node_ty(var_id)?; + let var_node_id = self.tcx().hir.as_local_node_id(upvar_def.def_id()).unwrap(); + let var_hir_id = self.tcx().hir.node_to_hir_id(var_node_id); + let var_ty = self.mc.node_ty(var_hir_id)?; self.mc.cat_def(closure_id, closure_span, var_ty, upvar_def) } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index d29622b4a8159..0a4e5094cde77 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -146,13 +146,13 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, '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 }; if let Def::Fn(did) = def { if self.def_id_is_transmute(did) { - let typ = self.tables.node_id_to_type(expr.id); + let typ = self.tables.node_id_to_type(expr.hir_id); let sig = typ.fn_sig(self.tcx); let from = sig.inputs().skip_binder()[0]; let to = *sig.output().skip_binder(); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index b4993aafc4c9e..1f3f9fce85424 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -70,7 +70,7 @@ pub use self::Note::*; use self::Aliasability::*; use middle::region::RegionMaps; -use hir::def_id::DefId; +use hir::def_id::{DefId, DefIndex}; use hir::map as hir_map; use infer::InferCtxt; use hir::def::{Def, CtorKind}; @@ -190,7 +190,7 @@ pub type cmt<'tcx> = Rc>; pub enum ImmutabilityBlame<'tcx> { ImmLocal(ast::NodeId), - ClosureEnv(ast::NodeId), + ClosureEnv(DefIndex), LocalDeref(ast::NodeId), AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef) } @@ -334,7 +334,9 @@ impl MutabilityCategory { let ret = match tcx.hir.get(id) { hir_map::NodeLocal(p) => match p.node { PatKind::Binding(..) => { - let bm = *tables.pat_binding_modes.get(&p.id).expect("missing binding mode"); + let bm = *tables.pat_binding_modes() + .get(p.hir_id) + .expect("missing binding mode"); if bm == ty::BindByValue(hir::MutMutable) { McDeclared } else { @@ -435,7 +437,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } fn resolve_type_vars_or_error(&self, - id: ast::NodeId, + id: hir::HirId, ty: Option>) -> McResult> { match ty { @@ -451,33 +453,41 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // FIXME None if self.is_tainted_by_errors() => Err(()), None => { + let id = self.tcx.hir.definitions().find_node_for_hir_id(id); bug!("no type for node {}: {} in mem_categorization", id, self.tcx.hir.node_to_string(id)); } } } - pub fn node_ty(&self, id: ast::NodeId) -> McResult> { - self.resolve_type_vars_or_error(id, self.tables.node_id_to_type_opt(id)) + pub fn node_ty(&self, + hir_id: hir::HirId) + -> McResult> { + self.resolve_type_vars_or_error(hir_id, + self.tables.node_id_to_type_opt(hir_id)) } pub fn expr_ty(&self, expr: &hir::Expr) -> McResult> { - self.resolve_type_vars_or_error(expr.id, self.tables.expr_ty_opt(expr)) + self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr)) } pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult> { - self.resolve_type_vars_or_error(expr.id, self.tables.expr_ty_adjusted_opt(expr)) + self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr)) } fn pat_ty(&self, pat: &hir::Pat) -> McResult> { - let base_ty = self.node_ty(pat.id)?; + let base_ty = self.node_ty(pat.hir_id)?; // FIXME (Issue #18207): This code detects whether we are // looking at a `ref x`, and if so, figures out what the type // *being borrowed* is. But ideally we would put in a more // fundamental fix to this conflated use of the node id. let ret_ty = match pat.node { PatKind::Binding(..) => { - let bm = *self.tables.pat_binding_modes.get(&pat.id).expect("missing binding mode"); + let bm = *self.tables + .pat_binding_modes() + .get(pat.hir_id) + .expect("missing binding mode"); + if let ty::BindByReference(_) = bm { // a bind-by-ref means that the base_ty will be the type of the ident itself, // but what we want here is the type of the underlying value being borrowed. @@ -604,7 +614,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, '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) } @@ -684,6 +694,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { fn_node_id: ast::NodeId) -> McResult> { + let fn_hir_id = self.tcx.hir.node_to_hir_id(fn_node_id); + // An upvar can have up to 3 components. We translate first to a // `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the // field from the environment. @@ -707,14 +719,20 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk // FnOnce | copied | upvar -> &'up bk - let kind = match self.tables.closure_kinds.get(&fn_node_id) { + let kind = match self.tables.closure_kinds().get(fn_hir_id) { Some(&(kind, _)) => kind, None => span_bug!(span, "missing closure kind") }; - let upvar_id = ty::UpvarId { var_id, - closure_expr_id: fn_node_id }; - let var_ty = self.node_ty(var_id)?; + let closure_expr_def_index = self.tcx.hir.local_def_id(fn_node_id).index; + let var_def_index = self.tcx.hir.local_def_id(var_id).index; + + let upvar_id = ty::UpvarId { + var_id: var_def_index, + closure_expr_id: closure_expr_def_index + }; + let var_hir_id = self.tcx.hir.node_to_hir_id(var_id); + let var_ty = self.node_ty(var_hir_id)?; // Mutability of original variable itself let var_mutbl = MutabilityCategory::from_local(self.tcx, self.tables, var_id); @@ -749,8 +767,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // If this is a by-ref capture, then the upvar we loaded is // actually a reference, so we have to add an implicit deref // for that. - let upvar_id = ty::UpvarId { var_id, - closure_expr_id: fn_node_id }; let upvar_capture = self.tables.upvar_capture(upvar_id); let cmt_result = match upvar_capture { ty::UpvarCapture::ByValue => { @@ -788,7 +804,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: self.tcx.hir.local_def_id(upvar_id.closure_expr_id), + scope: DefId::local(upvar_id.closure_expr_id), bound_region: ty::BrEnv })); @@ -1124,7 +1140,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { 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 +1177,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { 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); diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index df828c8d8e71a..1e2bb6627afc9 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -107,10 +107,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { 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]) } _ => 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(None), reachable_symbols: NodeSet(), worklist: Vec::new(), any_library, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f0fc6998c9e51..c5b0f11b823a1 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -682,7 +682,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Additional context information explaining why the closure only implements // a particular trait. if let Some(tables) = self.in_progress_tables { - match tables.borrow().closure_kinds.get(&node_id) { + let tables = tables.borrow(); + let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id); + match tables.closure_kinds().get(closure_hir_id) { Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => { err.span_note(span, &format!( "closure is `FnOnce` because it moves the \ diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6b9cbabf20e97..6e8a7ca35a842 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -14,12 +14,13 @@ use dep_graph::DepGraph; 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; use hir::map::DefPathHash; use lint::{self, Lint}; +use ich::{self, StableHashingContext, NodeIdHashingMode}; use middle::free_region::FreeRegionMap; use middle::lang_items; use middle::resolve_lifetime; @@ -42,15 +43,18 @@ use ty::inhabitedness::DefIdForest; 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; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; use arena::{TypedArena, DroplessArena}; use rustc_data_structures::indexed_vec::IndexVec; use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::cmp::Ordering; +use std::collections::hash_map::{self, Entry}; use std::hash::{Hash, Hasher}; use std::mem; use std::ops::Deref; @@ -207,54 +211,151 @@ pub struct CommonTypes<'tcx> { pub re_erased: Region<'tcx>, } +pub struct LocalTableInContext<'a, V: 'a> { + local_id_root: Option, + data: &'a ItemLocalMap +} + +/// Validate that the given HirId (respectively its `local_id` part) can be +/// safely used as a key in the tables of a TypeckTable. For that to be +/// the case, the HirId must have the same `owner` as all the other IDs in +/// this table (signified by `local_id_root`). Otherwise the HirId +/// would be in a different frame of reference and using its `local_id` +/// would result in lookup errors, or worse, in silently wrong data being +/// stored/returned. +fn validate_hir_id_for_typeck_tables(local_id_root: Option, + hir_id: hir::HirId, + mut_access: bool) { + if cfg!(debug_assertions) { + if let Some(local_id_root) = local_id_root { + if hir_id.owner != 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), + local_id_root) + }); + } + } else { + // We use "Null Object" TypeckTables in some of the analysis passes. + // These are just expected to be empty and their `local_id_root` is + // `None`. Therefore we cannot verify whether a given `HirId` would + // be a valid key for the given table. Instead we make sure that + // nobody tries to write to such a Null Object table. + if mut_access { + bug!("access to invalid TypeckTables") + } + } + } +} + +impl<'a, V> LocalTableInContext<'a, V> { + pub fn contains_key(&self, id: hir::HirId) -> bool { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.data.contains_key(&id.local_id) + } + + pub fn get(&self, id: hir::HirId) -> Option<&V> { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.data.get(&id.local_id) + } + + pub fn iter(&self) -> hash_map::Iter { + self.data.iter() + } +} + +impl<'a, V> ::std::ops::Index for LocalTableInContext<'a, V> { + type Output = V; + + fn index(&self, key: hir::HirId) -> &V { + self.get(key).expect("LocalTableInContext: key not found") + } +} + +pub struct LocalTableInContextMut<'a, V: 'a> { + local_id_root: Option, + data: &'a mut ItemLocalMap +} + +impl<'a, V> LocalTableInContextMut<'a, V> { + pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> { + validate_hir_id_for_typeck_tables(self.local_id_root, id, true); + self.data.get_mut(&id.local_id) + } + + pub fn entry(&mut self, id: hir::HirId) -> Entry { + validate_hir_id_for_typeck_tables(self.local_id_root, id, true); + self.data.entry(id.local_id) + } + + pub fn insert(&mut self, id: hir::HirId, val: V) -> Option { + validate_hir_id_for_typeck_tables(self.local_id_root, id, true); + self.data.insert(id.local_id, val) + } + + pub fn remove(&mut self, id: hir::HirId) -> Option { + validate_hir_id_for_typeck_tables(self.local_id_root, id, true); + self.data.remove(&id.local_id) + } +} + #[derive(RustcEncodable, RustcDecodable)] pub struct TypeckTables<'tcx> { + /// The HirId::owner all ItemLocalIds in this table are relative to. + pub local_id_root: Option, + /// Resolved definitions for `::X` associated paths and /// method calls, including those of overloaded operators. - pub type_dependent_defs: NodeMap, + type_dependent_defs: ItemLocalMap, /// Stores the types for various nodes in the AST. Note that this table /// is not guaranteed to be populated until after typeck. See /// typeck::check::fn_ctxt for details. - pub node_types: NodeMap>, + node_types: ItemLocalMap>, /// Stores the type parameters which were substituted to obtain the type /// of this node. This only applies to nodes that refer to entities /// parameterized by type parameters, such as generic fns, types, or /// other items. - pub node_substs: NodeMap<&'tcx Substs<'tcx>>, + node_substs: ItemLocalMap<&'tcx Substs<'tcx>>, - pub adjustments: NodeMap>>, + adjustments: ItemLocalMap>>, // Stores the actual binding mode for all instances of hir::BindingAnnotation. - pub pat_binding_modes: NodeMap, + pat_binding_modes: ItemLocalMap, /// Borrows pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>, /// Records the type of each closure. - pub closure_tys: NodeMap>, + closure_tys: ItemLocalMap>, /// Records the kind of each closure and the span and name of the variable /// that caused the closure to be this kind. - pub closure_kinds: NodeMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>, + closure_kinds: ItemLocalMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>, /// For each fn, records the "liberated" types of its arguments /// and return type. Liberated means that all bound regions /// (including late-bound regions) are replaced with free /// equivalents. This table is not used in trans (since regions /// are erased there) and hence is not serialized to metadata. - pub liberated_fn_sigs: NodeMap>, + liberated_fn_sigs: ItemLocalMap>, /// For each FRU expression, record the normalized types of the fields /// of the struct - this is needed because it is non-trivial to /// normalize while preserving regions. This table is used only in /// MIR construction and hence is not serialized to metadata. - pub fru_field_types: NodeMap>>, + fru_field_types: ItemLocalMap>>, /// Maps a cast expression to its kind. This is keyed on the /// *from* expression of the cast, not the cast itself. - pub cast_kinds: NodeMap, + cast_kinds: ItemLocalMap, /// Set of trait imports actually used in the method resolution. /// This is used for warning unused imports. @@ -271,19 +372,20 @@ pub struct TypeckTables<'tcx> { } impl<'tcx> TypeckTables<'tcx> { - pub fn empty() -> TypeckTables<'tcx> { + pub fn empty(local_id_root: Option) -> TypeckTables<'tcx> { TypeckTables { - type_dependent_defs: NodeMap(), - node_types: FxHashMap(), - node_substs: NodeMap(), - adjustments: NodeMap(), - pat_binding_modes: NodeMap(), + local_id_root, + type_dependent_defs: ItemLocalMap(), + node_types: ItemLocalMap(), + node_substs: ItemLocalMap(), + adjustments: ItemLocalMap(), + pat_binding_modes: ItemLocalMap(), upvar_capture_map: FxHashMap(), - closure_tys: NodeMap(), - closure_kinds: NodeMap(), - liberated_fn_sigs: NodeMap(), - fru_field_types: NodeMap(), - cast_kinds: NodeMap(), + closure_tys: ItemLocalMap(), + closure_kinds: ItemLocalMap(), + liberated_fn_sigs: ItemLocalMap(), + fru_field_types: ItemLocalMap(), + cast_kinds: ItemLocalMap(), used_trait_imports: DefIdSet(), tainted_by_errors: false, free_region_map: FreeRegionMap::new(), @@ -291,41 +393,87 @@ impl<'tcx> 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) + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.type_dependent_defs.get(&id.local_id).cloned().unwrap_or(Def::Err) } } } - pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> { + pub fn type_dependent_defs(&self) -> LocalTableInContext { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.type_dependent_defs + } + } + + pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.type_dependent_defs + } + } + + pub fn node_types(&self) -> LocalTableInContext> { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.node_types + } + } + + pub fn node_types_mut(&mut self) -> LocalTableInContextMut> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.node_types + } + } + + pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> { match self.node_id_to_type_opt(id) { Some(ty) => ty, None => { bug!("node_id_to_type: no type for node `{}`", - tls::with(|tcx| tcx.hir.node_to_string(id))) + tls::with(|tcx| { + let id = tcx.hir.definitions().find_node_for_hir_id(id); + tcx.hir.node_to_string(id) + })) } } } - pub fn node_id_to_type_opt(&self, id: NodeId) -> Option> { - self.node_types.get(&id).cloned() + pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option> { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.node_types.get(&id.local_id).cloned() + } + + pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<&'tcx Substs<'tcx>> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.node_substs + } + } + + pub fn node_substs(&self, id: hir::HirId) -> &'tcx Substs<'tcx> { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.node_substs.get(&id.local_id).cloned().unwrap_or(Substs::empty()) } - pub fn node_substs(&self, id: NodeId) -> &'tcx Substs<'tcx> { - self.node_substs.get(&id).cloned().unwrap_or(Substs::empty()) + pub fn node_substs_opt(&self, id: hir::HirId) -> Option<&'tcx Substs<'tcx>> { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.node_substs.get(&id.local_id).cloned() } // Returns the type of a pattern as a monotype. Like @expr_ty, this function // doesn't provide type parameter substitutions. pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> { - self.node_id_to_type(pat.id) + self.node_id_to_type(pat.hir_id) } pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option> { - self.node_id_to_type_opt(pat.id) + self.node_id_to_type_opt(pat.hir_id) } // Returns the type of an expression as a monotype. @@ -339,16 +487,32 @@ impl<'tcx> TypeckTables<'tcx> { // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize" // instead of "fn(ty) -> T with T = isize". pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> { - self.node_id_to_type(expr.id) + self.node_id_to_type(expr.hir_id) } pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option> { - self.node_id_to_type_opt(expr.id) + self.node_id_to_type_opt(expr.hir_id) + } + + pub fn adjustments(&self) -> LocalTableInContext>> { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.adjustments + } + } + + pub fn adjustments_mut(&mut self) + -> LocalTableInContextMut>> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.adjustments + } } pub fn expr_adjustments(&self, expr: &hir::Expr) -> &[ty::adjustment::Adjustment<'tcx>] { - self.adjustments.get(&expr.id).map_or(&[], |a| &a[..]) + validate_hir_id_for_typeck_tables(self.local_id_root, expr.hir_id, false); + self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..]) } /// Returns the type of `expr`, considering any `Adjustment` @@ -373,15 +537,169 @@ impl<'tcx> TypeckTables<'tcx> { return false; } - match self.type_dependent_defs.get(&expr.id) { + match self.type_dependent_defs().get(expr.hir_id) { Some(&Def::Method(_)) => true, _ => false } } + pub fn pat_binding_modes(&self) -> LocalTableInContext { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.pat_binding_modes + } + } + + pub fn pat_binding_modes_mut(&mut self) + -> LocalTableInContextMut { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.pat_binding_modes + } + } + pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> { self.upvar_capture_map[&upvar_id] } + + pub fn closure_tys(&self) -> LocalTableInContext> { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.closure_tys + } + } + + pub fn closure_tys_mut(&mut self) + -> LocalTableInContextMut> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.closure_tys + } + } + + pub fn closure_kinds(&self) -> LocalTableInContext<(ty::ClosureKind, + Option<(Span, ast::Name)>)> { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.closure_kinds + } + } + + pub fn closure_kinds_mut(&mut self) + -> LocalTableInContextMut<(ty::ClosureKind, Option<(Span, ast::Name)>)> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.closure_kinds + } + } + + pub fn liberated_fn_sigs(&self) -> LocalTableInContext> { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.liberated_fn_sigs + } + } + + pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.liberated_fn_sigs + } + } + + pub fn fru_field_types(&self) -> LocalTableInContext>> { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.fru_field_types + } + } + + pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut>> { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.fru_field_types + } + } + + pub fn cast_kinds(&self) -> LocalTableInContext { + LocalTableInContext { + local_id_root: self.local_id_root, + data: &self.cast_kinds + } + } + + pub fn cast_kinds_mut(&mut self) -> LocalTableInContextMut { + LocalTableInContextMut { + local_id_root: self.local_id_root, + data: &mut self.cast_kinds + } + } +} + +impl<'a, 'gcx, 'tcx> HashStable> for TypeckTables<'gcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher) { + let ty::TypeckTables { + local_id_root, + ref type_dependent_defs, + ref node_types, + ref node_substs, + ref adjustments, + ref pat_binding_modes, + ref upvar_capture_map, + ref closure_tys, + ref closure_kinds, + ref liberated_fn_sigs, + ref fru_field_types, + + ref cast_kinds, + + ref used_trait_imports, + tainted_by_errors, + ref free_region_map, + } = *self; + + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + ich::hash_stable_itemlocalmap(hcx, hasher, type_dependent_defs); + ich::hash_stable_itemlocalmap(hcx, hasher, node_types); + ich::hash_stable_itemlocalmap(hcx, hasher, node_substs); + ich::hash_stable_itemlocalmap(hcx, hasher, adjustments); + ich::hash_stable_itemlocalmap(hcx, hasher, pat_binding_modes); + ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| { + let ty::UpvarId { + var_id, + closure_expr_id + } = *up_var_id; + + let local_id_root = + local_id_root.expect("trying to hash invalid TypeckTables"); + + let var_def_id = DefId { + krate: local_id_root.krate, + index: var_id, + }; + let closure_def_id = DefId { + krate: local_id_root.krate, + index: closure_expr_id, + }; + (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id)) + }); + + ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys); + ich::hash_stable_itemlocalmap(hcx, hasher, closure_kinds); + ich::hash_stable_itemlocalmap(hcx, hasher, liberated_fn_sigs); + ich::hash_stable_itemlocalmap(hcx, hasher, fru_field_types); + ich::hash_stable_itemlocalmap(hcx, hasher, cast_kinds); + + ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| { + hcx.def_path_hash(*def_id) + }); + + tainted_by_errors.hash_stable(hcx, hasher); + free_region_map.hash_stable(hcx, hasher); + }) + } } impl<'tcx> CommonTypes<'tcx> { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 28a73f4a4d387..af322fc72d899 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -572,8 +572,8 @@ impl Slice { /// by the upvar) and the id of the closure expression. #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub struct UpvarId { - pub var_id: NodeId, - pub closure_expr_id: NodeId, + pub var_id: DefIndex, + pub closure_expr_id: DefIndex, } #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)] @@ -1983,6 +1983,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + pub fn local_var_name_str_def_index(self, def_index: DefIndex) -> InternedString { + let node_id = self.hir.as_local_node_id(DefId::local(def_index)).unwrap(); + self.local_var_name_str(node_id) + } + pub fn expr_is_lval(self, expr: &hir::Expr) -> bool { match expr.node { hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index b03011fcb216d..c397371c5c767 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -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; @@ -20,12 +21,14 @@ pub use rustc_data_structures::fx::FxHashSet; pub type NodeMap = FxHashMap; pub type DefIdMap = FxHashMap; +pub type ItemLocalMap = FxHashMap; pub type NodeSet = FxHashSet; pub type DefIdSet = FxHashSet; pub fn NodeMap() -> NodeMap { FxHashMap() } pub fn DefIdMap() -> DefIdMap { FxHashMap() } +pub fn ItemLocalMap() -> ItemLocalMap { FxHashMap() } pub fn NodeSet() -> NodeSet { FxHashSet() } pub fn DefIdSet() -> DefIdSet { FxHashSet() } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d9c99ccd50843..184fd75135e47 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -864,9 +864,9 @@ impl<'tcx> fmt::Display for ty::TyS<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "UpvarId({};`{}`;{})", + write!(f, "UpvarId({:?};`{}`;{:?})", self.var_id, - ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)), + ty::tls::with(|tcx| tcx.local_var_name_str_def_index(self.var_id)), self.closure_expr_id) } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 3d669aa81df6e..35af83c8ae23a 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -155,7 +155,9 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { } fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) { - let ty = self.bccx.tables.node_id_to_type(id); + let ty = self.bccx + .tables + .node_id_to_type(self.bccx.tcx.hir.node_to_hir_id(id)); gather_moves::gather_decl(self.bccx, &self.move_data, id, ty); } } @@ -447,7 +449,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } None } - LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => { + LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => { + let local_id = self.tcx().hir.def_index_to_node_id(var_id); self.tcx().used_mut_nodes.borrow_mut().insert(local_id); None } diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index cceb4a7b3cc21..bfd883be84876 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -93,11 +93,11 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec { LpInterior(Option, InteriorKind), } -pub fn closure_to_block(closure_id: ast::NodeId, - tcx: TyCtxt) -> ast::NodeId { +fn closure_to_block(closure_id: DefIndex, + tcx: TyCtxt) -> ast::NodeId { + let closure_id = tcx.hir.def_index_to_node_id(closure_id); match tcx.hir.get(closure_id) { hir_map::NodeExpr(expr) => match expr.node { hir::ExprClosure(.., body_id, _) => { @@ -598,8 +599,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { let need_note = match lp.ty.sty { ty::TypeVariants::TyClosure(id, _) => { let node_id = self.tcx.hir.as_local_node_id(id).unwrap(); + let hir_id = self.tcx.hir.node_to_hir_id(node_id); if let Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) = - self.tables.closure_kinds.get(&node_id) + self.tables.closure_kinds().get(hir_id) { err.span_note(span, &format!( "closure cannot be invoked more than once because \ @@ -843,7 +845,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } else { "consider changing this closure to take self by mutable reference" }; - err.span_help(self.tcx.hir.span(id), help); + let node_id = self.tcx.hir.def_index_to_node_id(id); + err.span_help(self.tcx.hir.span(node_id), help); err } _ => { @@ -899,8 +902,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { }; match pat.node { - hir::PatKind::Binding(..) => - *self.tables.pat_binding_modes.get(&pat.id).expect("missing binding mode"), + hir::PatKind::Binding(..) => { + *self.tables + .pat_binding_modes() + .get(pat.hir_id) + .expect("missing binding mode") + } _ => bug!("local is not a binding: {:?}", pat) } } @@ -1174,7 +1181,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { _ => bug!() }; if kind == ty::ClosureKind::Fn { - db.span_help(self.tcx.hir.span(upvar_id.closure_expr_id), + let closure_node_id = + self.tcx.hir.def_index_to_node_id(upvar_id.closure_expr_id); + db.span_help(self.tcx.hir.span(closure_node_id), "consider changing this closure to take \ self by mutable reference"); } @@ -1207,7 +1216,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { loan_path: &LoanPath<'tcx>, out: &mut String) { match loan_path.kind { - LpUpvar(ty::UpvarId{ var_id: id, closure_expr_id: _ }) | + LpUpvar(ty::UpvarId { var_id: id, closure_expr_id: _ }) => { + out.push_str(&self.tcx.local_var_name_str_def_index(id)); + } LpVar(id) => { out.push_str(&self.tcx.local_var_name_str(id)); } @@ -1345,8 +1356,11 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { } LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => { - let s = ty::tls::with(|tcx| tcx.hir.node_to_string(var_id)); - write!(f, "$({} captured by id={})", s, closure_expr_id) + let s = ty::tls::with(|tcx| { + let var_node_id = tcx.hir.def_index_to_node_id(var_id); + tcx.hir.node_to_string(var_node_id) + }); + write!(f, "$({} captured by id={:?})", s, closure_expr_id) } LpDowncast(ref lp, variant_def_id) => { @@ -1377,7 +1391,10 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> { } LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => { - let s = ty::tls::with(|tcx| tcx.hir.node_to_user_string(var_id)); + let s = ty::tls::with(|tcx| { + let var_node_id = tcx.hir.def_index_to_node_id(var_id); + tcx.hir.node_to_string(var_node_id) + }); write!(f, "$({} captured by closure)", s) } diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index a3f8aae472cae..ea7deef472425 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -188,7 +188,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { // Then, if the match has no arms, check whether the scrutinee // is uninhabited. - let pat_ty = self.tables.node_id_to_type(scrut.id); + let pat_ty = self.tables.node_id_to_type(scrut.hir_id); let module = self.tcx.hir.get_module_parent(scrut.id); if inlined_arms.is_empty() { let scrutinee_is_uninhabited = if self.tcx.sess.features.borrow().never_type { @@ -217,7 +217,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { .flat_map(|arm| &arm.0) .map(|pat| vec![pat.0]) .collect(); - let scrut_ty = self.tables.node_id_to_type(scrut.id); + let scrut_ty = self.tables.node_id_to_type(scrut.hir_id); check_exhaustive(cx, scrut_ty, scrut.span, &matrix); }) } @@ -269,7 +269,11 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) { pat.walk(|p| { if let PatKind::Binding(_, _, name, None) = p.node { - let bm = *cx.tables.pat_binding_modes.get(&p.id).expect("missing binding mode"); + let bm = *cx.tables + .pat_binding_modes() + .get(p.hir_id) + .expect("missing binding mode"); + if bm != ty::BindByValue(hir::MutImmutable) { // Nothing to check. return true; @@ -458,7 +462,11 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, let mut by_ref_span = None; for pat in pats { pat.each_binding(|_, id, span, _path| { - let bm = *cx.tables.pat_binding_modes.get(&id).expect("missing binding mode"); + let hir_id = cx.tcx.hir.node_to_hir_id(id); + let bm = *cx.tables + .pat_binding_modes() + .get(hir_id) + .expect("missing binding mode"); if let ty::BindByReference(..) = bm { by_ref_span = Some(span); } @@ -491,10 +499,13 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, for pat in pats { pat.walk(|p| { if let PatKind::Binding(_, _, _, ref sub) = p.node { - let bm = *cx.tables.pat_binding_modes.get(&p.id).expect("missing binding mode"); + let bm = *cx.tables + .pat_binding_modes() + .get(p.hir_id) + .expect("missing binding mode"); match bm { ty::BindByValue(..) => { - let pat_ty = cx.tables.node_id_to_type(p.id); + let pat_ty = cx.tables.node_id_to_type(p.hir_id); if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index eb45fd9c0e0a4..c0a050cb6b43c 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -275,8 +275,8 @@ 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) { + let substs = cx.tables.node_substs(e.hir_id).subst(tcx, cx.substs); + 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))) { diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index f37a112a596ac..d151e817040a9 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -303,7 +303,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> { - let mut ty = self.tables.node_id_to_type(pat.id); + let mut ty = self.tables.node_id_to_type(pat.hir_id); let kind = match pat.node { PatKind::Wild => PatternKind::Wild, @@ -321,7 +321,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } PatKind::Path(ref qpath) => { - return self.lower_path(qpath, pat.id, pat.id, pat.span); + return self.lower_path(qpath, pat.hir_id, pat.id, pat.span); } PatKind::Ref(ref subpattern, _) | @@ -330,7 +330,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } PatKind::Slice(ref prefix, ref slice, ref suffix) => { - let ty = self.tables.node_id_to_type(pat.id); + let ty = self.tables.node_id_to_type(pat.hir_id); match ty.sty { ty::TyRef(_, mt) => PatternKind::Deref { @@ -355,7 +355,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } PatKind::Tuple(ref subpatterns, ddpos) => { - let ty = self.tables.node_id_to_type(pat.id); + let ty = self.tables.node_id_to_type(pat.hir_id); match ty.sty { ty::TyTuple(ref tys, _) => { let subpatterns = @@ -376,13 +376,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatKind::Binding(_, def_id, ref ident, ref sub) => { let id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - let var_ty = self.tables.node_id_to_type(pat.id); + let var_ty = self.tables.node_id_to_type(pat.hir_id); let region = match var_ty.sty { ty::TyRef(r, _) => Some(r), _ => None, }; - let bm = *self.tables.pat_binding_modes.get(&pat.id) - .expect("missing binding mode"); + let bm = *self.tables.pat_binding_modes().get(pat.hir_id) + .expect("missing binding mode"); let (mutability, mode) = match bm { ty::BindByValue(hir::MutMutable) => (Mutability::Mut, BindingMode::ByValue), @@ -417,7 +417,7 @@ impl<'a, 'tcx> PatternContext<'a, '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 @@ impl<'a, 'tcx> PatternContext<'a, '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,7 +590,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { fn lower_path(&mut self, qpath: &hir::QPath, - id: ast::NodeId, + id: hir::HirId, pat_id: ast::NodeId, span: Span) -> Pattern<'tcx> { @@ -695,8 +695,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { hir::ExprPath(ref qpath) => qpath, _ => bug!() }; - let ty = self.tables.node_id_to_type(callee.id); - let def = self.tables.qpath_def(qpath, callee.id); + let ty = self.tables.node_id_to_type(callee.hir_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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } 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 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } hir::ExprPath(ref qpath) => { - return self.lower_path(qpath, expr.id, pat_id, span); + return self.lower_path(qpath, expr.hir_id, pat_id, span); } _ => self.lower_lit(expr) diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 1f44378c9e646..bc9bfa4049723 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -196,6 +196,16 @@ impl IndexVec { } } +impl IndexVec { + #[inline] + pub fn binary_search(&self, value: &T) -> Result { + match self.raw.binary_search(value) { + Ok(i) => Ok(Idx::new(i)), + Err(i) => Err(Idx::new(i)), + } + } +} + impl Index for IndexVec { type Output = T; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 269363fdd2f98..828136d6b7e4c 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -232,7 +232,7 @@ impl PpSourceMode { arenas, id, |tcx, _, _, _| { - let empty_tables = ty::TypeckTables::empty(); + let empty_tables = ty::TypeckTables::empty(None); let annotation = TypedAnnotation { tcx: tcx, tables: Cell::new(&empty_tables) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 88432e6429031..cef35be59cd10 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { } fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { - let ty = cx.tables.node_id_to_type(e.id); + let ty = cx.tables.node_id_to_type(e.hir_id); self.check_heap_type(cx, e.span, ty); } } @@ -896,7 +896,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { 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,8 +934,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { // 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 substs = cx.tables.node_substs(id); + let hir_id = cx.tcx.hir.definitions().node_to_hir_id(id); + let def_id = cx.tables.type_dependent_defs()[hir_id].def_id(); + let substs = cx.tables.node_substs(hir_id); if method_call_refers_to_method(cx, method, def_id, substs, id) { return true; } @@ -945,13 +946,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { 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; }; match def { Def::Method(def_id) => { - let substs = cx.tables.node_substs(callee.id); + let substs = cx.tables.node_substs(callee.hir_id); method_call_refers_to_method(cx, method, def_id, substs, id) } _ => false, @@ -1179,7 +1180,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { 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; }; @@ -1187,7 +1188,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { if !def_id_is_transmute(cx, did) { return None; } - let sig = cx.tables.node_id_to_type(expr.id).fn_sig(cx.tcx); + let sig = cx.tables.node_id_to_type(expr.hir_id).fn_sig(cx.tcx); let from = sig.inputs().skip_binder()[0]; let to = *sig.output().skip_binder(); return Some((&from.sty, &to.sty)); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index aca98df9cc998..cdf0996796085 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } if binop.node.is_shift() { - let opt_ty_bits = match cx.tables.node_id_to_type(l.id).sty { + let opt_ty_bits = match cx.tables.node_id_to_type(l.hir_id).sty { ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)), ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)), _ => None, @@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } hir::ExprLit(ref lit) => { - match cx.tables.node_id_to_type(e.id).sty { + match cx.tables.node_id_to_type(e.hir_id).sty { ty::TyInt(t) => { match lit.node { ast::LitKind::Int(v, ast::LitIntType::Signed(_)) | @@ -285,7 +285,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { // Normalize the binop so that the literal is always on the RHS in // the comparison let norm_binop = if swap { rev_binop(binop) } else { binop }; - match cx.tables.node_id_to_type(expr.id).sty { + match cx.tables.node_id_to_type(expr.hir_id).sty { ty::TyInt(int_ty) => { let (min, max) = int_ty_range(int_ty); let lit_val: i128 = match lit.node { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index ba17df4cdca4b..9b90360109ee2 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -45,7 +45,8 @@ impl UnusedMut { let mut mutables = FxHashMap(); for p in pats { p.each_binding(|_, id, span, path1| { - let bm = match cx.tables.pat_binding_modes.get(&id) { + let hir_id = cx.tcx.hir.node_to_hir_id(id); + let bm = match cx.tables.pat_binding_modes().get(hir_id) { Some(&bm) => bm, None => span_bug!(span, "missing binding mode"), }; @@ -154,12 +155,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let maybe_def = match expr.node { hir::ExprCall(ref callee, _) => { match callee.node { - hir::ExprPath(ref qpath) => Some(cx.tables.qpath_def(qpath, callee.id)), + hir::ExprPath(ref qpath) => Some(cx.tables.qpath_def(qpath, callee.hir_id)), _ => None } }, hir::ExprMethodCall(..) => { - cx.tables.type_dependent_defs.get(&expr.id).cloned() + cx.tables.type_dependent_defs().get(expr.hir_id).cloned() }, _ => { None } }; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 3353fb9a5b49c..14392ae70e4e3 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -90,7 +90,8 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t } else if let MirSource::Fn(id) = src { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) - let fn_sig = cx.tables().liberated_fn_sigs[&id].clone(); + let fn_hir_id = tcx.hir.node_to_hir_id(id); + let fn_sig = cx.tables().liberated_fn_sigs()[fn_hir_id].clone(); let ty = tcx.type_of(tcx.hir.local_def_id(id)); let mut abi = fn_sig.abi; @@ -202,7 +203,8 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, closure_expr_id: ast::NodeId, body_id: hir::BodyId) -> Ty<'tcx> { - let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id); + let closure_expr_hir_id = tcx.hir.node_to_hir_id(closure_expr_id); + let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_hir_id); let closure_def_id = tcx.hir.local_def_id(closure_expr_id); let region = ty::ReFree(ty::FreeRegion { @@ -365,10 +367,12 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, // Gather the upvars of a closure, if any. let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| { freevars.iter().map(|fv| { - let var_id = tcx.hir.as_local_node_id(fv.def.def_id()).unwrap(); + let var_def_id = fv.def.def_id(); + let var_node_id = tcx.hir.as_local_node_id(var_def_id).unwrap(); + let closure_expr_id = tcx.hir.local_def_id(fn_id).index; let capture = hir.tables().upvar_capture(ty::UpvarId { - var_id: var_id, - closure_expr_id: fn_id + var_id: var_def_id.index, + closure_expr_id, }); let by_ref = match capture { ty::UpvarCapture::ByValue => false, @@ -378,7 +382,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, debug_name: keywords::Invalid.name(), by_ref: by_ref }; - if let Some(hir::map::NodeLocal(pat)) = tcx.hir.find(var_id) { + if let Some(hir::map::NodeLocal(pat)) = tcx.hir.find(var_node_id) { if let hir::PatKind::Binding(_, _, ref ident, _) = pat.node { decl.debug_name = ident.node; } diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index c91326f6d8746..fa54925c6e75e 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -95,7 +95,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { - let block_ty = cx.tables().node_id_to_type(block.id); + let block_ty = cx.tables().node_id_to_type(block.hir_id); let temp_lifetime = cx.region_maps.temporary_scope(block.id); let expr = Expr { ty: block_ty, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 06a0c4ff213da..5b3e4b1ddc37a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -217,7 +217,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, None }; if let Some((adt_def, index)) = adt_data { - let substs = cx.tables().node_substs(fun.id); + let substs = cx.tables().node_substs(fun.hir_id); let field_refs = args.iter() .enumerate() .map(|(idx, e)| { @@ -236,7 +236,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } else { ExprKind::Call { - ty: cx.tables().node_id_to_type(fun.id), + ty: cx.tables().node_id_to_type(fun.hir_id), fun: fun.to_ref(), args: args.to_ref(), } @@ -389,7 +389,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, base: base.as_ref().map(|base| { FruInfo { base: base.to_ref(), - field_types: cx.tables().fru_field_types[&expr.id].clone(), + field_types: cx.tables() + .fru_field_types()[expr.hir_id] + .clone(), } }), } @@ -450,7 +452,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) } @@ -548,7 +550,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprCast(ref source, _) => { // Check to see if this cast is a "coercion cast", where the cast is actually done // using a coercion (or is a no-op). - if let Some(&TyCastKind::CoercionCast) = cx.tables().cast_kinds.get(&source.id) { + if let Some(&TyCastKind::CoercionCast) = cx.tables() + .cast_kinds() + .get(source.hir_id) { // Convert the lexpr to a vexpr. ExprKind::Use { source: source.to_ref() } } else { @@ -580,8 +584,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().node_substs(expr.id)) + (cx.tables().type_dependent_defs()[expr.hir_id].def_id(), + cx.tables().node_substs(expr.hir_id)) }); Expr { temp_lifetime: temp_lifetime, @@ -619,7 +623,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, def: Def) -> ExprKind<'tcx> { - let substs = cx.tables().node_substs(expr.id); + let substs = cx.tables().node_substs(expr.hir_id); match def { // A regular function, constructor function or a constant. Def::Fn(def_id) | @@ -641,7 +645,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Def::StructCtor(def_id, CtorKind::Const) | Def::VariantCtor(def_id, CtorKind::Const) => { - match cx.tables().node_id_to_type(expr.id).sty { + match cx.tables().node_id_to_type(expr.hir_id).sty { // A unit struct/variant which is used as a value. // We return a completely different ExprKind here to account for this special case. ty::TyAdt(adt_def, substs) => { @@ -677,16 +681,18 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::VarRef { id: node_id } } - Def::Upvar(def_id, index, closure_expr_id) => { - let id_var = cx.tcx.hir.as_local_node_id(def_id).unwrap(); + Def::Upvar(var_def_id, index, closure_expr_id) => { + let id_var = cx.tcx.hir.as_local_node_id(var_def_id).unwrap(); debug!("convert_var(upvar({:?}, {:?}, {:?}))", id_var, index, closure_expr_id); - let var_ty = cx.tables().node_id_to_type(id_var); + let var_ty = cx.tables() + .node_id_to_type(cx.tcx.hir.node_to_hir_id(id_var)); // FIXME free regions in closures are not right - let closure_ty = cx.tables().node_id_to_type(closure_expr_id); + let closure_ty = cx.tables() + .node_id_to_type(cx.tcx.hir.node_to_hir_id(closure_expr_id)); // FIXME we're just hard-coding the idea that the // signature will be &self or &mut self and hence will @@ -759,8 +765,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // ...but the upvar might be an `&T` or `&mut T` capture, at which // point we need an implicit deref let upvar_id = ty::UpvarId { - var_id: id_var, - closure_expr_id: closure_expr_id, + var_id: var_def_id.index, + closure_expr_id: closure_def_id.index, }; match cx.tables().upvar_capture(upvar_id) { ty::UpvarCapture::ByValue => field_kind, @@ -871,14 +877,16 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, freevar: &hir::Freevar, freevar_ty: Ty<'tcx>) -> ExprRef<'tcx> { - let id_var = cx.tcx.hir.as_local_node_id(freevar.def.def_id()).unwrap(); + let var_def_id = freevar.def.def_id(); + let var_node_id = cx.tcx.hir.as_local_node_id(var_def_id).unwrap(); let upvar_id = ty::UpvarId { - var_id: id_var, - closure_expr_id: closure_expr.id, + var_id: var_def_id.index, + closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).index, }; let upvar_capture = cx.tables().upvar_capture(upvar_id); let temp_lifetime = cx.region_maps.temporary_scope(closure_expr.id); - let var_ty = cx.tables().node_id_to_type(id_var); + let var_ty = cx.tables() + .node_id_to_type(cx.tcx.hir.node_to_hir_id(var_node_id)); let captured_var = Expr { temp_lifetime: temp_lifetime, ty: var_ty, diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 8443cc8267d1c..9185f73974cd7 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -219,7 +219,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { let outer = self.promotable; self.promotable = true; - let node_ty = self.tables.node_id_to_type(ex.id); + let node_ty = self.tables.node_id_to_type(ex.hir_id); check_expr(self, ex, node_ty); check_adjustments(self, ex); @@ -297,7 +297,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node v.promotable = false; } hir::ExprUnary(op, ref inner) => { - match v.tables.node_id_to_type(inner.id).sty { + match v.tables.node_id_to_type(inner.hir_id).sty { ty::TyRawPtr(_) => { assert!(op == hir::UnDeref); @@ -307,7 +307,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprBinary(op, ref lhs, _) => { - match v.tables.node_id_to_type(lhs.id).sty { + match v.tables.node_id_to_type(lhs.hir_id).sty { ty::TyRawPtr(_) => { assert!(op.node == hir::BiEq || op.node == hir::BiNe || op.node == hir::BiLe || op.node == hir::BiLt || @@ -320,7 +320,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } hir::ExprCast(ref from, _) => { debug!("Checking const cast(id={})", from.id); - match v.tables.cast_kinds.get(&from.id) { + match v.tables.cast_kinds().get(from.hir_id) { None => span_bug!(e.span, "no kind for cast"), Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => { v.promotable = false; @@ -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,7 @@ 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(); + let def_id = v.tables.type_dependent_defs()[e.hir_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 +471,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(None), in_fn: false, promotable: false, mut_rvalue_borrows: NodeSet(), diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9fa5fea20d915..76a8850291f8d 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> { } } +// 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 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { 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> { @@ -607,7 +639,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> { } // Take node ID of an expression or pattern and check its type for privacy. - fn check_expr_pat_type(&mut self, id: ast::NodeId, span: Span) -> bool { + fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool { self.span = span; if let Some(ty) = self.tables.node_id_to_type_opt(id) { if ty.visit_with(self) { @@ -617,7 +649,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> { if self.tables.node_substs(id).visit_with(self) { return true; } - if let Some(adjustments) = self.tables.adjustments.get(&id) { + if let Some(adjustments) = self.tables.adjustments().get(id) { for adjustment in adjustments { if adjustment.target.visit_with(self) { return true; @@ -703,20 +735,20 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { // Check types of expressions fn visit_expr(&mut self, expr: &'tcx hir::Expr) { - if self.check_expr_pat_type(expr.id, expr.span) { + if self.check_expr_pat_type(expr.hir_id, expr.span) { // Do not check nested expressions if the error already happened. return; } match expr.node { hir::ExprAssign(.., ref rhs) | hir::ExprMatch(ref rhs, ..) => { // Do not report duplicate errors for `x = y` and `match x { ... }`. - if self.check_expr_pat_type(rhs.id, rhs.span) { + if self.check_expr_pat_type(rhs.hir_id, rhs.span) { return; } } hir::ExprMethodCall(_, span, _) => { // Method calls have to be checked specially. - let def_id = self.tables.type_dependent_defs[&expr.id].def_id(); + let def_id = self.tables.type_dependent_defs()[expr.hir_id].def_id(); self.span = span; if self.tcx.type_of(def_id).visit_with(self) { return; @@ -732,7 +764,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { // 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); + if let Some(def) = self.tables.type_dependent_defs().get(hir_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) { @@ -748,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { // Check types of patterns fn visit_pat(&mut self, pattern: &'tcx hir::Pat) { - if self.check_expr_pat_type(pattern.id, pattern.span) { + if self.check_expr_pat_type(pattern.hir_id, pattern.span) { // Do not check nested patterns if the error already happened. return; } @@ -758,7 +791,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { fn visit_local(&mut self, local: &'tcx hir::Local) { if let Some(ref init) = local.init { - if self.check_expr_pat_type(init.id, init.span) { + if self.check_expr_pat_type(init.hir_id, init.span) { // Do not report duplicate errors for `let x = y`. return; } @@ -770,6 +803,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { // 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 +866,21 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { 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> { @@ -1605,12 +1655,14 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, assert_eq!(krate, LOCAL_CRATE); let krate = tcx.hir.krate(); + let empty_tables = ty::TypeckTables::empty(None); // 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 +1670,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); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 4740f9a0d5a59..f89d59b5a4492 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -345,7 +345,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { collector.visit_pat(&arg.pat); let span_utils = self.span.clone(); for &(id, ref p, ..) in &collector.collected_paths { - let typ = match self.save_ctxt.tables.node_types.get(&id) { + let hir_id = self.tcx.hir.node_to_hir_id(id); + let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) { Some(s) => s.to_string(), None => continue, }; @@ -499,12 +500,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { item: &'l ast::Item, typ: &'l ast::Ty, expr: &'l ast::Expr) { - if let Some(var_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(var_data, DefData, item.span); - self.dumper.dump_def(item.vis == ast::Visibility::Public, var_data); - } - self.visit_ty(&typ); - self.visit_expr(expr); + self.nest_tables(item.id, |v| { + if let Some(var_data) = v.save_ctxt.get_item_data(item) { + down_cast_data!(var_data, DefData, item.span); + v.dumper.dump_def(item.vis == ast::Visibility::Public, var_data); + } + v.visit_ty(&typ); + v.visit_expr(expr); + }); } fn process_assoc_const(&mut self, @@ -893,7 +896,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { match p.node { PatKind::Struct(ref _path, ref fields, _) => { // FIXME do something with _path? - let adt = match self.save_ctxt.tables.node_id_to_type_opt(p.id) { + let hir_id = self.tcx.hir.node_to_hir_id(p.id); + let adt = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) { Some(ty) => ty.ty_adt_def().unwrap(), None => { visit::walk_pat(self, p); @@ -935,7 +939,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ast::Mutability::Immutable => value.to_string(), _ => String::new(), }; - let typ = match self.save_ctxt.tables.node_types.get(&id) { + let hir_id = self.tcx.hir.node_to_hir_id(id); + let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) { Some(typ) => { let typ = typ.to_string(); if !value.is_empty() { @@ -1466,8 +1471,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } else { "".to_string() }; - let typ = self.save_ctxt.tables.node_types - .get(&id).map(|t| t.to_string()).unwrap_or(String::new()); + let hir_id = self.tcx.hir.node_to_hir_id(id); + let typ = self.save_ctxt + .tables + .node_id_to_type_opt(hir_id) + .map(|t| t.to_string()) + .unwrap_or(String::new()); value.push_str(": "); value.push_str(&typ); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 1dd0df4108fc6..c3d071d27d6ef 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -550,7 +550,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } ast::ExprKind::MethodCall(..) => { - let method_id = self.tables.type_dependent_defs[&expr.id].def_id(); + let expr_hir_id = self.tcx.hir.definitions().node_to_hir_id(expr.id); + let method_id = self.tables.type_dependent_defs()[expr_hir_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 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { 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(None), analysis: analysis, span_utils: SpanUtils::new(&tcx.sess), config: find_config(config), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index eaff8e7b8ace7..b49b9377e8c56 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -118,8 +118,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // identical to what could be scraped from the HIR, but this will change with // default binding modes (#42640). let bm = ty::BindingMode::convert(ba); - self.inh.tables.borrow_mut().pat_binding_modes.insert(pat.id, bm); - + self.inh + .tables + .borrow_mut() + .pat_binding_modes_mut() + .insert(pat.hir_id, bm); let typ = self.local_ty(pat.span, pat.id); match bm { ty::BindByReference(mutbl) => { @@ -323,7 +326,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - self.write_ty(pat.id, ty); + self.write_ty(pat.hir_id, ty); // (*) In most of the cases above (literals and constants being // the exception), we relate types using strict equality, evewn diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index a0801a7486654..460e2858b22ec 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -222,7 +222,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { TupleArgumentsFlag::TupleArguments, expected); - self.write_method_call(call_expr.id, method_callee); + self.write_method_call(call_expr.hir_id, method_callee); output_type } } @@ -364,7 +364,8 @@ impl<'a, 'gcx, 'tcx> DeferredCallResolution<'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.hir_id, + method_callee); } None => { span_bug!(self.call_expr.span, diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 5f256eab9a9c8..b18b11f3d9069 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -330,12 +330,13 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } else if self.try_coercion_cast(fcx) { self.trivial_cast_lint(fcx); debug!(" -> CoercionCast"); - fcx.tables.borrow_mut().cast_kinds.insert(self.expr.id, CastKind::CoercionCast); + fcx.tables.borrow_mut().cast_kinds_mut().insert(self.expr.hir_id, + CastKind::CoercionCast); } else { match self.do_check(fcx) { Ok(k) => { debug!(" -> {:?}", k); - fcx.tables.borrow_mut().cast_kinds.insert(self.expr.id, k); + fcx.tables.borrow_mut().cast_kinds_mut().insert(self.expr.hir_id, k); } Err(e) => self.report_cast_error(fcx, e), }; diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 802eee91efcf3..61795a7e623d3 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -102,12 +102,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { sig, opt_kind); - self.tables.borrow_mut().closure_tys.insert(expr.id, sig); - match opt_kind { - Some(kind) => { - self.tables.borrow_mut().closure_kinds.insert(expr.id, (kind, None)); + { + let mut tables = self.tables.borrow_mut(); + tables.closure_tys_mut().insert(expr.hir_id, sig); + match opt_kind { + Some(kind) => { + tables.closure_kinds_mut().insert(expr.hir_id, (kind, None)); + } + None => {} } - None => {} } closure_type diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 934a4f9b29689..53f3d811fae4f 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -844,7 +844,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // First try to coerce the new expression to the type of the previous ones, // but only if the new expression has no coercion already applied to it. let mut first_error = None; - if !self.tables.borrow().adjustments.contains_key(&new.id) { + if !self.tables.borrow().adjustments().contains_key(new.hir_id) { let result = self.commit_if_ok(|_| coerce.coerce(new_ty, prev_ty)); match result { Ok(ok) => { @@ -866,7 +866,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Adjustment { kind: Adjust::Deref(_), .. }, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl_adj)), .. } ] => { - match self.node_ty(expr.id).sty { + match self.node_ty(expr.hir_id).sty { ty::TyRef(_, mt_orig) => { // Reborrow that we can safely ignore, because // the next adjustment can only be a Deref diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index b6a5ce0a6ce5a..355e6cdbbe074 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -445,11 +445,14 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Fix up the autoderefs. Autorefs can only occur immediately preceding // overloaded lvalue ops, and will be fixed by them in order to get // the correct region. - let mut source = self.node_ty(expr.id); + let mut source = self.node_ty(expr.hir_id); // Do not mutate adjustments in place, but rather take them, // and replace them after mutating them, to avoid having the // tables borrowed during (`deref_mut`) method resolution. - let previous_adjustments = self.tables.borrow_mut().adjustments.remove(&expr.id); + let previous_adjustments = self.tables + .borrow_mut() + .adjustments_mut() + .remove(expr.hir_id); if let Some(mut adjustments) = previous_adjustments { let pref = LvaluePreference::PreferMutLvalue; for adjustment in &mut adjustments { @@ -466,12 +469,12 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { } source = adjustment.target; } - self.tables.borrow_mut().adjustments.insert(expr.id, adjustments); + self.tables.borrow_mut().adjustments_mut().insert(expr.hir_id, adjustments); } match expr.node { hir::ExprIndex(ref base_expr, ref index_expr) => { - let index_expr_ty = self.node_ty(index_expr.id); + let index_expr_ty = self.node_ty(index_expr.hir_id); self.convert_lvalue_op_to_mutable( LvalueOp::Index, expr, base_expr, &[index_expr_ty]); } @@ -498,7 +501,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { } let base_ty = self.tables.borrow().expr_adjustments(base_expr).last() - .map_or_else(|| self.node_ty(expr.id), |adj| adj.target); + .map_or_else(|| self.node_ty(expr.hir_id), |adj| adj.target); let base_ty = self.resolve_type_vars_if_possible(&base_ty); // Need to deref because overloaded lvalue ops take self by-reference. @@ -513,7 +516,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { 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.hir_id, method); let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty { (r, mt.mutbl) @@ -523,8 +526,11 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Convert the autoref in the base expr to mutable with the correct // region and mutability. - let base_expr_ty = self.node_ty(base_expr.id); - if let Some(adjustments) = self.tables.borrow_mut().adjustments.get_mut(&base_expr.id) { + let base_expr_ty = self.node_ty(base_expr.hir_id); + if let Some(adjustments) = self.tables + .borrow_mut() + .adjustments_mut() + .get_mut(base_expr.hir_id) { let mut source = base_expr_ty; for adjustment in &mut adjustments[..] { if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 7bf671d5e9f93..5de4a35bdc724 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -820,7 +820,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let closure_id = match step.self_ty.sty { ty::TyClosure(def_id, _) => { if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { - id + self.tcx.hir.node_to_hir_id(id) } else { continue; } @@ -828,11 +828,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { _ => continue, }; - let closure_kinds = &self.tables.borrow().closure_kinds; - let closure_kind = match closure_kinds.get(&closure_id) { - Some(&(k, _)) => k, - None => { - return Err(MethodError::ClosureAmbiguity(trait_def_id)); + let closure_kind = { + match self.tables.borrow().closure_kinds().get(closure_id) { + Some(&(k, _)) => k, + None => { + return Err(MethodError::ClosureAmbiguity(trait_def_id)); + } } }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 697d9de931a86..826e8de860b9e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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, } } @@ -735,7 +743,8 @@ fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureKind { let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); - tcx.typeck_tables_of(def_id).closure_kinds[&node_id].0 + let hir_id = tcx.hir.node_to_hir_id(node_id); + tcx.typeck_tables_of(def_id).closure_kinds()[hir_id].0 } fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -840,7 +849,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 +896,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, + Some(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) { @@ -1010,10 +1025,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation); } - fcx.write_ty(arg.id, arg_ty); + fcx.write_ty(arg.hir_id, arg_ty); } - inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig); + let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id); + inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig); fcx.check_return_expr(&body.value); @@ -1793,10 +1809,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } #[inline] - pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) { - debug!("write_ty({}, {:?}) in fcx {}", - node_id, self.resolve_type_vars_if_possible(&ty), self.tag()); - self.tables.borrow_mut().node_types.insert(node_id, ty); + pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) { + debug!("write_ty({:?}, {:?}) in fcx {}", + id, self.resolve_type_vars_if_possible(&ty), self.tag()); + self.tables.borrow_mut().node_types_mut().insert(id, ty); if ty.references_error() { self.has_errors.set(true); @@ -1804,19 +1820,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, '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)); - self.write_substs(node_id, method.substs); + // 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, + hir_id: hir::HirId, + method: MethodCallee<'tcx>) { + self.tables + .borrow_mut() + .type_dependent_defs_mut() + .insert(hir_id, Def::Method(method.def_id)); + self.write_substs(hir_id, method.substs); } - pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) { + pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) { if !substs.is_noop() { - debug!("write_substs({}, {:?}) in fcx {}", + debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag()); - self.tables.borrow_mut().node_substs.insert(node_id, substs); + self.tables.borrow_mut().node_substs_mut().insert(node_id, substs); } } @@ -1827,7 +1850,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return; } - match self.tables.borrow_mut().adjustments.entry(expr.id) { + match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) { Entry::Vacant(entry) => { entry.insert(adj); }, Entry::Occupied(mut entry) => { debug!(" - composing on top of {:?}", entry.get()); @@ -1980,13 +2003,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { t } - pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { - match self.tables.borrow().node_types.get(&id) { + pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { + match self.tables.borrow().node_types().get(id) { Some(&t) => t, None if self.err_count_since_creation() != 0 => self.tcx.types.err, None => { + let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id); bug!("no type for node {}: {} in fcx {}", - id, self.tcx.hir.node_to_string(id), + node_id, self.tcx.hir.node_to_string(node_id), self.tag()); } } @@ -2254,7 +2278,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } self.apply_adjustments(base_expr, adjustments); - self.write_method_call(expr.id, method); + self.write_method_call(expr.hir_id, method); (input_ty, self.make_overloaded_lvalue_return_type(method).ty) }); if result.is_some() { @@ -2643,7 +2667,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // While we don't allow *arbitrary* coercions here, we *do* allow // coercions from ! to `expected`. if ty.is_never() { - assert!(!self.tables.borrow().adjustments.contains_key(&expr.id), + assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id), "expression with never type wound up being adjusted"); let adj_ty = self.next_diverging_ty_var( TypeVariableOrigin::AdjustmentType(expr.span)); @@ -2794,7 +2818,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr, rcvr) { Ok(method) => { - self.write_method_call(expr.id, method); + self.write_method_call(expr.hir_id, method); Ok(method) } Err(error) => { @@ -3368,7 +3392,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fru_field_types = adt.struct_variant().fields.iter().map(|f| { self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs)) }).collect(); - self.tables.borrow_mut().fru_field_types.insert(expr.id, fru_field_types); + + self.tables + .borrow_mut() + .fru_field_types_mut() + .insert(expr.hir_id, fru_field_types); } _ => { span_err!(self.tcx.sess, base_expr.span, E0436, @@ -3426,7 +3454,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Record the type, which applies it effects. // We need to do this after the warning above, so that // we don't warn for the diverging expression itself. - self.write_ty(expr.id, ty); + self.write_ty(expr.hir_id, ty); // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); @@ -3499,7 +3527,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }]); } oprnd_t = self.make_overloaded_lvalue_return_type(method).ty; - self.write_method_call(expr.id, method); + self.write_method_call(expr.hir_id, method); } else { type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614, "type `{}` cannot be dereferenced", @@ -3577,7 +3605,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // We always require that the type provided as the value for // a type parameter outlives the moment of instantiation. - let substs = self.tables.borrow().node_substs(expr.id); + let substs = self.tables.borrow().node_substs(expr.hir_id); self.add_wf_bounds(substs, expr); ty @@ -4000,7 +4028,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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); + self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def); (def, ty) } @@ -4041,7 +4070,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // 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); + self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def); (def, Some(ty), slice::ref_slice(&**item_segment)) } @@ -4073,19 +4103,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn check_decl_local(&self, local: &'gcx hir::Local) { let t = self.local_ty(local.span, local.id); - self.write_ty(local.id, t); + self.write_ty(local.hir_id, t); if let Some(ref init) = local.init { let init_ty = self.check_decl_initializer(local, &init); if init_ty.references_error() { - self.write_ty(local.id, init_ty); + self.write_ty(local.hir_id, init_ty); } } self.check_pat(&local.pat, t); - let pat_ty = self.node_ty(local.pat.id); + let pat_ty = self.node_ty(local.pat.hir_id); if pat_ty.references_error() { - self.write_ty(local.id, pat_ty); + self.write_ty(local.hir_id, pat_ty); } } @@ -4237,7 +4267,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty = self.tcx.types.err } - self.write_ty(blk.id, ty); + self.write_ty(blk.hir_id, ty); *self.ps.borrow_mut() = prev; ty @@ -4415,7 +4445,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::StmtSemi(ref e, _) => e, _ => return, }; - let last_expr_ty = self.node_ty(last_expr.id); + let last_expr_ty = self.node_ty(last_expr.hir_id); if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() { return; } @@ -4558,7 +4588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let nid = self.tcx.hir.as_local_node_id(def_id).unwrap(); let ty = self.local_ty(span, nid); let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(node_id, ty); + self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty); return ty; } _ => {} @@ -4690,7 +4720,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("instantiate_value_path: type of {:?} is {:?}", node_id, ty_substituted); - self.write_substs(node_id, substs); + self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs); ty_substituted } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index c1711491ee48c..a4e1fdaf39e29 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -210,11 +210,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // some cases applied on the RHS, on top of which we need // to autoref, which is not allowed by apply_adjustments. // self.apply_adjustments(rhs_expr, vec![autoref]); - self.tables.borrow_mut().adjustments.entry(rhs_expr.id) - .or_insert(vec![]).push(autoref); + self.tables + .borrow_mut() + .adjustments_mut() + .entry(rhs_expr.hir_id) + .or_insert(vec![]) + .push(autoref); } } - self.write_method_call(expr.id, method); + self.write_method_call(expr.hir_id, method); method.sig.output() } @@ -340,7 +344,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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.hir_id, method); method.sig.output() } Err(()) => { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 9b7ecc194ca88..b187075a36d27 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } /// Try to resolve the type for the given node. - fn resolve_node_type(&self, id: ast::NodeId) -> Ty<'tcx> { + fn resolve_node_type(&self, id: hir::HirId) -> Ty<'tcx> { let t = self.node_ty(id); self.resolve_type(t) } @@ -309,8 +309,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let old_call_site_scope = self.set_call_site_scope(Some(call_site)); let fn_sig = { - let fn_sig_map = &self.tables.borrow().liberated_fn_sigs; - match fn_sig_map.get(&id) { + let fn_hir_id = self.tcx.hir.node_to_hir_id(id); + match self.tables.borrow().liberated_fn_sigs().get(fn_hir_id) { Some(f) => f.clone(), None => { bug!("No fn-sig entry for id={}", id); @@ -338,8 +338,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("visit_fn_body body.id {:?} call_site_scope: {:?}", body.id(), call_site_scope); let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope)); + let body_hir_id = self.tcx.hir.node_to_hir_id(body_id.node_id); self.type_of_node_must_outlive(infer::CallReturn(span), - body_id.node_id, + body_hir_id, call_site_region); self.region_bound_pairs.truncate(old_region_bounds_pairs_len); @@ -613,9 +614,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let var_region = self.tcx.mk_region(ty::ReScope(var_scope)); let origin = infer::BindingTypeIsNotValidAtDecl(span); - self.type_of_node_must_outlive(origin, id, var_region); + let hir_id = self.tcx.hir.node_to_hir_id(id); + self.type_of_node_must_outlive(origin, hir_id, var_region); - let typ = self.resolve_node_type(id); + let typ = self.resolve_node_type(hir_id); let _ = dropck::check_safety_of_destructor_if_necessary( self, typ, span, var_scope); }) @@ -664,7 +666,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // No matter what, the type of each expression must outlive the // scope of that expression. This also guarantees basic WF. - let expr_ty = self.resolve_node_type(expr.id); + let expr_ty = self.resolve_node_type(expr.hir_id); // the region corresponding to this expression let expr_region = self.tcx.node_scope_region(expr.id); self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span), @@ -686,7 +688,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { infer::ParameterOrigin::OverloadedOperator }; - let substs = self.tables.borrow().node_substs(expr.id); + let substs = self.tables.borrow().node_substs(expr.hir_id); self.substs_wf_in_scope(origin, substs, expr.span, expr_region); // Arguments (sub-expressions) are checked via `constrain_call`, below. } @@ -709,7 +711,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { expr, self.repeating_scope); match expr.node { hir::ExprPath(_) => { - let substs = self.tables.borrow().node_substs(expr.id); + let substs = self.tables.borrow().node_substs(expr.hir_id); let origin = infer::ParameterOrigin::Path; self.substs_wf_in_scope(origin, substs, expr.span, expr_region); } @@ -718,7 +720,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { if is_method_call { self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e)); } else { - self.constrain_callee(callee.id, expr, &callee); + self.constrain_callee(&callee); self.constrain_call(expr, None, args.iter().map(|e| &*e)); } @@ -812,7 +814,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // adjustments*. // // FIXME(#6268) nested method calls requires that this rule change - let ty0 = self.resolve_node_type(expr.id); + let ty0 = self.resolve_node_type(expr.hir_id); self.type_must_outlive(infer::AddrOf(expr.span), ty0, expr_region); intravisit::walk_expr(self, expr); } @@ -849,7 +851,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { ret_expr.id, call_site_scope); let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap())); self.type_of_node_must_outlive(infer::CallReturn(ret_expr.span), - ret_expr.id, + ret_expr.hir_id, call_site_region); intravisit::walk_expr(self, expr); } @@ -870,8 +872,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { cast_expr, source_expr); - let source_ty = self.resolve_node_type(source_expr.id); - let target_ty = self.resolve_node_type(cast_expr.id); + let source_ty = self.resolve_node_type(source_expr.hir_id); + let target_ty = self.resolve_node_type(cast_expr.hir_id); self.walk_cast(cast_expr, source_ty, target_ty); } @@ -915,11 +917,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.set_repeating_scope(repeating_scope); } - fn constrain_callee(&mut self, - callee_id: ast::NodeId, - _call_expr: &hir::Expr, - _callee_expr: &hir::Expr) { - let callee_ty = self.resolve_node_type(callee_id); + fn constrain_callee(&mut self, callee_expr: &hir::Expr) { + let callee_ty = self.resolve_node_type(callee_expr.hir_id); match callee_ty.sty { ty::TyFnDef(..) | ty::TyFnPtr(_) => { } _ => { @@ -962,14 +961,16 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // ensure that any regions appearing in the argument type are // valid for at least the lifetime of the function: self.type_of_node_must_outlive(infer::CallArg(arg_expr.span), - arg_expr.id, callee_region); + arg_expr.hir_id, + callee_region); } // as loop above, but for receiver if let Some(r) = receiver { debug!("receiver: {:?}", r); self.type_of_node_must_outlive(infer::CallRcvr(r.span), - r.id, callee_region); + r.hir_id, + callee_region); } } @@ -1038,7 +1039,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // // FIXME(#6268) remove to support nested method calls self.type_of_node_must_outlive(infer::AutoBorrow(expr.span), - expr.id, expr_region); + expr.hir_id, + expr_region); } cmt = self.with_mc(|mc| mc.cat_expr_adjusted(expr, cmt, &adjustment))?; @@ -1109,21 +1111,25 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// adjustments) are valid for at least `minimum_lifetime` fn type_of_node_must_outlive(&mut self, origin: infer::SubregionOrigin<'tcx>, - id: ast::NodeId, + hir_id: hir::HirId, minimum_lifetime: ty::Region<'tcx>) { // Try to resolve the type. If we encounter an error, then typeck // is going to fail anyway, so just stop here and let typeck // report errors later on in the writeback phase. - let ty0 = self.resolve_node_type(id); - let ty = self.tables.borrow().adjustments.get(&id) - .and_then(|adj| adj.last()) - .map_or(ty0, |adj| adj.target); + let ty0 = self.resolve_node_type(hir_id); + + let ty = self.tables + .borrow() + .adjustments() + .get(hir_id) + .and_then(|adj| adj.last()) + .map_or(ty0, |adj| adj.target); let ty = self.resolve_type(ty); debug!("constrain_regions_in_type_of_node(\ - ty={}, ty0={}, id={}, minimum_lifetime={:?})", + ty={}, ty0={}, id={:?}, minimum_lifetime={:?})", ty, ty0, - id, minimum_lifetime); + hir_id, minimum_lifetime); self.type_must_outlive(origin, ty, minimum_lifetime); } @@ -1137,7 +1143,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("link_addr_of: cmt={:?}", cmt); - self.link_region_from_node_type(expr.span, expr.id, mutability, cmt); + self.link_region_from_node_type(expr.span, expr.hir_id, mutability, cmt); } /// Computes the guarantors for any ref bindings in a `let` and @@ -1173,7 +1179,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) { debug!("regionck::link_fn_args(body_scope={:?})", body_scope); for arg in args { - let arg_ty = self.node_ty(arg.id); + let arg_ty = self.node_ty(arg.hir_id); let re_scope = self.tcx.mk_region(ty::ReScope(body_scope)); let arg_cmt = self.with_mc(|mc| { mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty) @@ -1197,10 +1203,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { match sub_pat.node { // `ref x` pattern PatKind::Binding(..) => { - let bm = *mc.tables.pat_binding_modes.get(&sub_pat.id) - .expect("missing binding mode"); + let bm = *mc.tables.pat_binding_modes().get(sub_pat.hir_id) + .expect("missing binding mode"); if let ty::BindByReference(mutbl) = bm { - self.link_region_from_node_type(sub_pat.span, sub_pat.id, + self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id, mutbl, sub_cmt); } } @@ -1236,7 +1242,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// which must be some reference (`&T`, `&str`, etc). fn link_region_from_node_type(&self, span: Span, - id: ast::NodeId, + id: hir::HirId, mutbl: hir::Mutability, cmt_borrowed: mc::cmt<'tcx>) { debug!("link_region_from_node_type(id={:?}, mutbl={:?}, cmt_borrowed={:?})", diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 59ca896b347f1..6db5c5b1cb0af 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -50,8 +50,9 @@ use rustc::infer::UpvarRegion; use syntax::ast; use syntax_pos::Span; use rustc::hir; +use rustc::hir::def_id::DefIndex; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::util::nodemap::NodeMap; +use rustc::util::nodemap::FxHashMap; use std::collections::hash_map::Entry; @@ -78,7 +79,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> { hir::ExprClosure(cc, _, body_id, _) => { let body = self.fcx.tcx.hir.body(body_id); self.visit_body(body); - self.fcx.analyze_closure(expr.id, expr.span, body, cc); + self.fcx.analyze_closure((expr.id, expr.hir_id), expr.span, body, cc); } _ => { } @@ -90,7 +91,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn analyze_closure(&self, - id: ast::NodeId, + (closure_node_id, closure_hir_id): (ast::NodeId, hir::HirId), span: Span, body: &hir::Body, capture_clause: hir::CaptureClause) { @@ -98,23 +99,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { * Analysis starting point. */ - debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id()); + debug!("analyze_closure(id={:?}, body.id={:?})", closure_node_id, body.id()); - let infer_kind = match self.tables.borrow_mut().closure_kinds.entry(id) { + let infer_kind = match self.tables + .borrow_mut() + .closure_kinds_mut() + .entry(closure_hir_id) { Entry::Occupied(_) => false, Entry::Vacant(entry) => { - debug!("check_closure: adding closure {:?} as Fn", id); + debug!("check_closure: adding closure {:?} as Fn", closure_node_id); entry.insert((ty::ClosureKind::Fn, None)); true } }; - self.tcx.with_freevars(id, |freevars| { + let closure_def_id = self.tcx.hir.local_def_id(closure_node_id); + + self.tcx.with_freevars(closure_node_id, |freevars| { for freevar in freevars { - let def_id = freevar.def.def_id(); - let var_node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - let upvar_id = ty::UpvarId { var_id: var_node_id, - closure_expr_id: id }; + let var_def_id = freevar.def.def_id(); + let upvar_id = ty::UpvarId { + var_id: var_def_id.index, + closure_expr_id: closure_def_id.index, + }; debug!("seed upvar_id {:?}", upvar_id); let capture_kind = match capture_clause { @@ -139,7 +146,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let region_maps = &self.tcx.region_maps(body_owner_def_id); let mut delegate = InferBorrowKind { fcx: self, - adjust_closure_kinds: NodeMap(), + adjust_closure_kinds: FxHashMap(), adjust_upvar_captures: ty::UpvarCaptureMap::default(), }; euv::ExprUseVisitor::with_infer(&mut delegate, @@ -151,8 +158,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Write the adjusted values back into the main tables. if infer_kind { - if let Some(kind) = delegate.adjust_closure_kinds.remove(&id) { - self.tables.borrow_mut().closure_kinds.insert(id, kind); + if let Some(kind) = delegate.adjust_closure_kinds + .remove(&closure_def_id.index) { + self.tables + .borrow_mut() + .closure_kinds_mut() + .insert(closure_hir_id, kind); } } self.tables.borrow_mut().upvar_capture_map.extend( @@ -172,20 +183,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // inference algorithm will reject it). // Extract the type variables UV0...UVn. - let (def_id, closure_substs) = match self.node_ty(id).sty { + let (def_id, closure_substs) = match self.node_ty(closure_hir_id).sty { ty::TyClosure(def_id, substs) => (def_id, substs), ref t => { span_bug!( span, "type of closure expr {:?} is not a closure {:?}", - id, t); + closure_node_id, t); } }; // Equate the type variables with the actual types. - let final_upvar_tys = self.final_upvar_tys(id); + let final_upvar_tys = self.final_upvar_tys(closure_node_id); debug!("analyze_closure: id={:?} closure_substs={:?} final_upvar_tys={:?}", - id, closure_substs, final_upvar_tys); + closure_node_id, closure_substs, final_upvar_tys); for (upvar_ty, final_upvar_ty) in closure_substs.upvar_tys(def_id, self.tcx).zip(final_upvar_tys) { @@ -195,7 +206,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If we are also inferred the closure kind here, // process any deferred resolutions. if infer_kind { - let closure_def_id = self.tcx.hir.local_def_id(id); let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id); for deferred_call_resolution in deferred_call_resolutions { @@ -212,19 +222,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // This may change if abstract return types of some sort are // implemented. let tcx = self.tcx; + let closure_def_index = tcx.hir.local_def_id(closure_id).index; + tcx.with_freevars(closure_id, |freevars| { freevars.iter().map(|freevar| { - let def_id = freevar.def.def_id(); - let var_id = tcx.hir.as_local_node_id(def_id).unwrap(); - let freevar_ty = self.node_ty(var_id); + let var_def_id = freevar.def.def_id(); + let var_node_id = tcx.hir.as_local_node_id(var_def_id).unwrap(); + let freevar_ty = self.node_ty(tcx.hir.node_to_hir_id(var_node_id)); let upvar_id = ty::UpvarId { - var_id: var_id, - closure_expr_id: closure_id + var_id: var_def_id.index, + closure_expr_id: closure_def_index, }; let capture = self.tables.borrow().upvar_capture(upvar_id); debug!("var_id={:?} freevar_ty={:?} capture={:?}", - var_id, freevar_ty, capture); + var_node_id, freevar_ty, capture); match capture { ty::UpvarCapture::ByValue => freevar_ty, @@ -242,7 +254,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { struct InferBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - adjust_closure_kinds: NodeMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>, + adjust_closure_kinds: FxHashMap)>, adjust_upvar_captures: ty::UpvarCaptureMap<'tcx>, } @@ -281,7 +293,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_closure_kind(upvar_id.closure_expr_id, ty::ClosureKind::FnOnce, guarantor.span, - tcx.hir.name(upvar_id.var_id)); + var_name(tcx, upvar_id.var_id)); self.adjust_upvar_captures.insert(upvar_id, ty::UpvarCapture::ByValue); } @@ -295,7 +307,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_closure_kind(upvar_id.closure_expr_id, ty::ClosureKind::FnOnce, guarantor.span, - tcx.hir.name(upvar_id.var_id)); + var_name(tcx, upvar_id.var_id)); } mc::NoteNone => { } @@ -400,7 +412,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_closure_kind(upvar_id.closure_expr_id, ty::ClosureKind::FnMut, cmt.span, - tcx.hir.name(upvar_id.var_id)); + var_name(tcx, upvar_id.var_id)); true } @@ -411,7 +423,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_closure_kind(upvar_id.closure_expr_id, ty::ClosureKind::FnMut, cmt.span, - tcx.hir.name(upvar_id.var_id)); + var_name(tcx, upvar_id.var_id)); true } @@ -460,17 +472,21 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { } fn adjust_closure_kind(&mut self, - closure_id: ast::NodeId, + closure_id: DefIndex, new_kind: ty::ClosureKind, upvar_span: Span, var_name: ast::Name) { - debug!("adjust_closure_kind(closure_id={}, new_kind={:?}, upvar_span={:?}, var_name={})", + debug!("adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})", closure_id, new_kind, upvar_span, var_name); let closure_kind = self.adjust_closure_kinds.get(&closure_id).cloned() - .or_else(|| self.fcx.tables.borrow().closure_kinds.get(&closure_id).cloned()); + .or_else(|| { + let closure_id = self.fcx.tcx.hir.def_index_to_hir_id(closure_id); + self.fcx.tables.borrow().closure_kinds().get(closure_id).cloned() + }); + if let Some((existing_kind, _)) = closure_kind { - debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}", + debug!("adjust_closure_kind: closure_id={:?}, existing_kind={:?}, new_kind={:?}", closure_id, existing_kind, new_kind); match (existing_kind, new_kind) { @@ -560,3 +576,8 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_upvar_borrow_kind_for_mut(assignee_cmt); } } + +fn var_name(tcx: ty::TyCtxt, var_def_index: DefIndex) -> ast::Name { + let var_node_id = tcx.hir.def_index_to_node_id(var_def_index); + tcx.hir.name(var_node_id) +} diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 9e5cf5137c21f..a363e47a14f29 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -14,6 +14,7 @@ use check::FnCtxt; use rustc::hir; +use rustc::hir::def_id::{DefId, DefIndex}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::infer::{InferCtxt}; use rustc::ty::{self, Ty, TyCtxt}; @@ -34,7 +35,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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.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(Some(DefId::local(owner.owner))), body: body } } @@ -86,10 +90,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { self.fcx.tcx } - fn write_ty_to_tables(&mut self, node_id: ast::NodeId, ty: Ty<'gcx>) { - debug!("write_ty_to_tables({}, {:?})", node_id, ty); + fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) { + debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty); assert!(!ty.needs_infer()); - self.tables.node_types.insert(node_id, ty); + self.tables.node_types_mut().insert(hir_id, ty); } // Hacky hack: During type-checking, we treat *all* operators @@ -100,37 +104,38 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { match e.node { hir::ExprUnary(hir::UnNeg, ref inner) | hir::ExprUnary(hir::UnNot, ref inner) => { - let inner_ty = self.fcx.node_ty(inner.id); + let inner_ty = self.fcx.node_ty(inner.hir_id); let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty); if inner_ty.is_scalar() { let mut tables = self.fcx.tables.borrow_mut(); - tables.type_dependent_defs.remove(&e.id); - tables.node_substs.remove(&e.id); + tables.type_dependent_defs_mut().remove(e.hir_id); + tables.node_substs_mut().remove(e.hir_id); } } hir::ExprBinary(ref op, ref lhs, ref rhs) | hir::ExprAssignOp(ref op, ref lhs, ref rhs) => { - let lhs_ty = self.fcx.node_ty(lhs.id); + let lhs_ty = self.fcx.node_ty(lhs.hir_id); let lhs_ty = self.fcx.resolve_type_vars_if_possible(&lhs_ty); - let rhs_ty = self.fcx.node_ty(rhs.id); + let rhs_ty = self.fcx.node_ty(rhs.hir_id); let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty); 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.node_substs.remove(&e.id); + tables.type_dependent_defs_mut().remove(e.hir_id); + tables.node_substs_mut().remove(e.hir_id); match e.node { hir::ExprBinary(..) => { if !op.node.is_by_value() { - tables.adjustments.get_mut(&lhs.id).map(|a| a.pop()); - tables.adjustments.get_mut(&rhs.id).map(|a| a.pop()); + let mut adjustments = tables.adjustments_mut(); + adjustments.get_mut(lhs.hir_id).map(|a| a.pop()); + adjustments.get_mut(rhs.hir_id).map(|a| a.pop()); } }, hir::ExprAssignOp(..) => { - tables.adjustments.get_mut(&lhs.id).map(|a| a.pop()); + tables.adjustments_mut().get_mut(lhs.hir_id).map(|a| a.pop()); }, _ => {}, } @@ -157,12 +162,12 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { 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.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.hir_id); } self.visit_body(body); @@ -172,21 +177,25 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { } fn visit_block(&mut self, b: &'gcx hir::Block) { - self.visit_node_id(b.span, b.id); + self.visit_node_id(b.span, b.hir_id); intravisit::walk_block(self, b); } fn visit_pat(&mut self, p: &'gcx hir::Pat) { match p.node { hir::PatKind::Binding(..) => { - let bm = *self.fcx.tables.borrow().pat_binding_modes.get(&p.id) - .expect("missing binding mode"); - self.tables.pat_binding_modes.insert(p.id, bm); + let bm = *self.fcx + .tables + .borrow() + .pat_binding_modes() + .get(p.hir_id) + .expect("missing binding mode"); + self.tables.pat_binding_modes_mut().insert(p.hir_id, bm); } _ => {} }; - self.visit_node_id(p.span, p.id); + self.visit_node_id(p.span, p.hir_id); intravisit::walk_pat(self, p); } @@ -194,7 +203,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { intravisit::walk_local(self, l); let var_ty = self.fcx.local_ty(l.span, l.id); let var_ty = self.resolve(&var_ty, &l.span); - self.write_ty_to_tables(l.id, var_ty); + self.write_ty_to_tables(l.hir_id, var_ty); } } @@ -218,19 +227,42 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } fn visit_closures(&mut self) { - for (&id, closure_ty) in self.fcx.tables.borrow().closure_tys.iter() { - let closure_ty = self.resolve(closure_ty, &id); - self.tables.closure_tys.insert(id, closure_ty); + let fcx_tables = self.fcx.tables.borrow(); + debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); + let common_local_id_root = fcx_tables.local_id_root.unwrap(); + + for (&id, closure_ty) in fcx_tables.closure_tys().iter() { + let hir_id = hir::HirId { + owner: common_local_id_root.index, + local_id: id, + }; + let closure_ty = self.resolve(closure_ty, &hir_id); + self.tables.closure_tys_mut().insert(hir_id, closure_ty); } - for (&id, &closure_kind) in self.fcx.tables.borrow().closure_kinds.iter() { - self.tables.closure_kinds.insert(id, closure_kind); + for (&id, &closure_kind) in fcx_tables.closure_kinds().iter() { + let hir_id = hir::HirId { + owner: common_local_id_root.index, + local_id: id, + }; + self.tables.closure_kinds_mut().insert(hir_id, closure_kind); } } fn visit_cast_types(&mut self) { - self.tables.cast_kinds.extend( - self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value))); + let fcx_tables = self.fcx.tables.borrow(); + let fcx_cast_kinds = fcx_tables.cast_kinds(); + debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); + let mut self_cast_kinds = self.tables.cast_kinds_mut(); + let common_local_id_root = fcx_tables.local_id_root.unwrap(); + + for (&local_id, &cast_kind) in fcx_cast_kinds.iter() { + let hir_id = hir::HirId { + owner: common_local_id_root.index, + local_id, + }; + self_cast_kinds.insert(hir_id, cast_kind); + } } fn visit_free_region_map(&mut self) { @@ -273,60 +305,85 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } }); - self.tables.node_types.insert(node_id, outside_ty); + let hir_id = self.tcx().hir.node_to_hir_id(node_id); + self.tables.node_types_mut().insert(hir_id, outside_ty); } } - fn visit_node_id(&mut self, span: Span, node_id: ast::NodeId) { + fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) { // 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); + if let Some(def) = self.fcx + .tables + .borrow_mut() + .type_dependent_defs_mut() + .remove(hir_id) { + self.tables.type_dependent_defs_mut().insert(hir_id, def); } // Resolve any borrowings for the node with id `node_id` - self.visit_adjustments(span, node_id); + self.visit_adjustments(span, hir_id); // Resolve the type of the node with id `node_id` - let n_ty = self.fcx.node_ty(node_id); + let n_ty = self.fcx.node_ty(hir_id); let n_ty = self.resolve(&n_ty, &span); - self.write_ty_to_tables(node_id, n_ty); - debug!("Node {} has type {:?}", node_id, n_ty); + self.write_ty_to_tables(hir_id, n_ty); + debug!("Node {:?} has type {:?}", hir_id, n_ty); // Resolve any substitutions - if let Some(&substs) = self.fcx.tables.borrow().node_substs.get(&node_id) { + if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) { let substs = self.resolve(&substs, &span); - debug!("write_substs_to_tcx({}, {:?})", node_id, substs); + debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs); assert!(!substs.needs_infer()); - self.tables.node_substs.insert(node_id, substs); + self.tables.node_substs_mut().insert(hir_id, substs); } } - fn visit_adjustments(&mut self, span: Span, node_id: ast::NodeId) { - let adjustment = self.fcx.tables.borrow_mut().adjustments.remove(&node_id); + fn visit_adjustments(&mut self, span: Span, hir_id: hir::HirId) { + let adjustment = self.fcx + .tables + .borrow_mut() + .adjustments_mut() + .remove(hir_id); match adjustment { None => { - debug!("No adjustments for node {}", node_id); + debug!("No adjustments for node {:?}", hir_id); } Some(adjustment) => { let resolved_adjustment = self.resolve(&adjustment, &span); - debug!("Adjustments for node {}: {:?}", node_id, resolved_adjustment); - self.tables.adjustments.insert(node_id, resolved_adjustment); + debug!("Adjustments for node {:?}: {:?}", hir_id, resolved_adjustment); + self.tables.adjustments_mut().insert(hir_id, resolved_adjustment); } } } fn visit_liberated_fn_sigs(&mut self) { - for (&node_id, fn_sig) in self.fcx.tables.borrow().liberated_fn_sigs.iter() { - let fn_sig = self.resolve(fn_sig, &node_id); - self.tables.liberated_fn_sigs.insert(node_id, fn_sig.clone()); + let fcx_tables = self.fcx.tables.borrow(); + debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); + let common_local_id_root = fcx_tables.local_id_root.unwrap(); + + for (&local_id, fn_sig) in fcx_tables.liberated_fn_sigs().iter() { + let hir_id = hir::HirId { + owner: common_local_id_root.index, + local_id, + }; + let fn_sig = self.resolve(fn_sig, &hir_id); + self.tables.liberated_fn_sigs_mut().insert(hir_id, fn_sig.clone()); } } fn visit_fru_field_types(&mut self) { - for (&node_id, ftys) in self.fcx.tables.borrow().fru_field_types.iter() { - let ftys = self.resolve(ftys, &node_id); - self.tables.fru_field_types.insert(node_id, ftys); + let fcx_tables = self.fcx.tables.borrow(); + debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); + let common_local_id_root = fcx_tables.local_id_root.unwrap(); + + for (&local_id, ftys) in fcx_tables.fru_field_types().iter() { + let hir_id = hir::HirId { + owner: common_local_id_root.index, + local_id, + }; + let ftys = self.resolve(ftys, &hir_id); + self.tables.fru_field_types_mut().insert(hir_id, ftys); } } @@ -356,6 +413,20 @@ impl Locatable for ast::NodeId { fn to_span(&self, tcx: &TyCtxt) -> Span { tcx.hir.span(*self) } } +impl Locatable for DefIndex { + fn to_span(&self, tcx: &TyCtxt) -> Span { + let node_id = tcx.hir.def_index_to_node_id(*self); + tcx.hir.span(node_id) + } +} + +impl Locatable for hir::HirId { + fn to_span(&self, tcx: &TyCtxt) -> Span { + let node_id = tcx.hir.definitions().find_node_for_hir_id(*self); + tcx.hir.span(node_id) + } +} + /////////////////////////////////////////////////////////////////////////// // The Resolver. This is the type folding engine that detects // unresolved types and so forth. diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fba32dbb889d9..91b41eb33a17d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1187,7 +1187,8 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => { let owner = tcx.hir.get_parent_did(node_id); - tcx.typeck_tables_of(owner).node_id_to_type(node_id) + let hir_id = tcx.hir.node_to_hir_id(node_id); + tcx.typeck_tables_of(owner).node_id_to_type(hir_id) } x => { @@ -1238,8 +1239,8 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, )) } - NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => { - tcx.typeck_tables_of(def_id).closure_tys[&node_id] + NodeExpr(&hir::Expr { node: hir::ExprClosure(..), hir_id, .. }) => { + tcx.typeck_tables_of(def_id).closure_tys()[hir_id] } x => {