From 454533f5d93421eb2532fc6ee0fcd3007142cff6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 7 Aug 2017 15:50:13 +0200 Subject: [PATCH] Use ItemLocalId as key for closure_tys and closure_kinds in TypeckTables. --- src/librustc/ich/impls_ty.rs | 4 ++-- src/librustc/infer/mod.rs | 13 +++++++++---- src/librustc/middle/mem_categorization.rs | 5 ++++- src/librustc/traits/error_reporting.rs | 5 ++++- src/librustc/ty/context.rs | 8 ++++---- src/librustc_borrowck/borrowck/mod.rs | 4 +++- src/librustc_typeck/check/closure.rs | 14 +++++++++----- src/librustc_typeck/check/method/probe.rs | 15 +++++++++------ src/librustc_typeck/check/mod.rs | 3 ++- src/librustc_typeck/check/upvar.rs | 12 +++++++++--- src/librustc_typeck/check/writeback.rs | 20 +++++++++++++++++--- src/librustc_typeck/collect.rs | 6 ++++-- 12 files changed, 76 insertions(+), 33 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 21d797d1e9a7..eec73937e2ca 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -654,8 +654,8 @@ for ty::TypeckTables<'gcx> { (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_itemlocalmap(hcx, hasher, closure_tys); + ich::hash_stable_itemlocalmap(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); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 6aa84a975033..727b0af2f547 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1331,9 +1331,11 @@ 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) { - return tables.borrow() - .closure_kinds - .get(&id) + let tables = tables.borrow(); + let hir_id = self.tcx.hir.node_to_hir_id(id); + tables.validate_hir_id(hir_id); + return tables.closure_kinds + .get(&hir_id.local_id) .cloned() .map(|(kind, _)| kind); } @@ -1353,7 +1355,10 @@ 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 tables = tables.borrow(); + let hir_id = self.tcx.hir.node_to_hir_id(id); + tables.validate_hir_id(hir_id); + if let Some(&ty) = tables.closure_tys.get(&hir_id.local_id) { return ty; } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index faa91d0fa3a9..e8c6cc812120 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -697,6 +697,9 @@ 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); + self.tables.validate_hir_id(fn_hir_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. @@ -720,7 +723,7 @@ 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.local_id) { Some(&(kind, _)) => kind, None => span_bug!(span, "missing closure kind") }; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f0fc6998c9e5..8c4054254d02 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -682,7 +682,10 @@ 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); + tables.validate_hir_id(closure_hir_id); + match tables.closure_kinds.get(&closure_hir_id.local_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 d4ff1590e8aa..492ec0f3e40d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -236,11 +236,11 @@ pub struct TypeckTables<'tcx> { pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>, /// Records the type of each closure. - pub closure_tys: NodeMap>, + pub 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)>)>, + pub 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 @@ -283,8 +283,8 @@ impl<'tcx> TypeckTables<'tcx> { adjustments: ItemLocalMap(), pat_binding_modes: ItemLocalMap(), upvar_capture_map: FxHashMap(), - closure_tys: NodeMap(), - closure_kinds: NodeMap(), + closure_tys: ItemLocalMap(), + closure_kinds: ItemLocalMap(), liberated_fn_sigs: NodeMap(), fru_field_types: NodeMap(), cast_kinds: NodeMap(), diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4b26aa95759d..7c9f4abe4183 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -598,8 +598,10 @@ 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); + self.tables.validate_hir_id(hir_id); if let Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) = - self.tables.closure_kinds.get(&node_id) + self.tables.closure_kinds.get(&hir_id.local_id) { err.span_note(span, &format!( "closure cannot be invoked more than once because \ diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 802eee91efcf..8bf58d866efc 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -102,12 +102,16 @@ 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.validate_hir_id(expr.hir_id); + tables.closure_tys.insert(expr.hir_id.local_id, sig); + match opt_kind { + Some(kind) => { + tables.closure_kinds.insert(expr.hir_id.local_id, (kind, None)); + } + None => {} } - None => {} } closure_type diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 7bf671d5e9f9..fc8f4f32440a 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,14 @@ 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 = { + let tables = self.tables.borrow(); + tables.validate_hir_id(closure_id); + match tables.closure_kinds.get(&closure_id.local_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 facacdc8d114..5308ffe6f8d7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -743,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.local_id].0 } fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 22047ed583e2..6621c9d027e9 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("analyze_closure(id={:?}, body.id={:?})", 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.entry(hir_id.local_id) { Entry::Occupied(_) => false, Entry::Vacant(entry) => { debug!("check_closure: adding closure {:?} as Fn", id); @@ -152,7 +152,7 @@ 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); + self.tables.borrow_mut().closure_kinds.insert(hir_id.local_id, kind); } } self.tables.borrow_mut().upvar_capture_map.extend( @@ -468,7 +468,13 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { 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.node_to_hir_id(closure_id); + let fcx_tables = self.fcx.tables.borrow(); + fcx_tables.validate_hir_id(closure_id); + fcx_tables.closure_kinds.get(&closure_id.local_id).cloned() + }); + if let Some((existing_kind, _)) = closure_kind { debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}", closure_id, existing_kind, new_kind); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index b689da6e3867..ed7b75ddb05b 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -230,12 +230,19 @@ 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); + let fcx_tables = self.fcx.tables.borrow(); + debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); + + for (&id, closure_ty) in fcx_tables.closure_tys.iter() { + let hir_id = hir::HirId { + owner: fcx_tables.local_id_root.index, + local_id: id, + }; + let closure_ty = self.resolve(closure_ty, &hir_id); self.tables.closure_tys.insert(id, closure_ty); } - for (&id, &closure_kind) in self.fcx.tables.borrow().closure_kinds.iter() { + for (&id, &closure_kind) in fcx_tables.closure_kinds.iter() { self.tables.closure_kinds.insert(id, closure_kind); } } @@ -380,6 +387,13 @@ impl Locatable for ast::NodeId { fn to_span(&self, tcx: &TyCtxt) -> Span { tcx.hir.span(*self) } } +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 7b63bd883f97..30188a7cbdce 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1239,8 +1239,10 @@ 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, .. }) => { + let tables = tcx.typeck_tables_of(def_id); + tables.validate_hir_id(hir_id); + tables.closure_tys[&hir_id.local_id] } x => {