From fd61fa5aef171e27209f1fad6388f730a64d61a2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 30 Aug 2017 09:31:14 -0700 Subject: [PATCH] rustc: Hide the `named_region_map` behind queries This commit makes the `named_region_map` field of `GlobalCtxt` private by encapsulating the fields behind new queries, and the new queries are also targeted at particular `HirId` nodes instead of accessing the entire map. --- src/librustc/dep_graph/dep_node.rs | 4 ++ .../error_reporting/anon_anon_conflict.rs | 26 ++++++----- src/librustc/ty/context.rs | 45 ++++++++++++------- src/librustc/ty/maps.rs | 25 +++++++++++ src/librustc_typeck/astconv.rs | 16 ++++--- src/librustc_typeck/collect.rs | 17 ++++--- src/librustdoc/clean/mod.rs | 3 +- 7 files changed, 95 insertions(+), 41 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 9646d3a7b3b..3efba6a5f22 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -550,6 +550,10 @@ define_dep_nodes!( <'tcx> [] IsStaticallyIncludedForeignItem(DefId), [] NativeLibraryKind(DefId), [] LinkArgs, + + [] NamedRegion(HirId), + [] IsLateBound(HirId), + [] ObjectLifetimeDefaults(HirId), ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/infer/error_reporting/anon_anon_conflict.rs b/src/librustc/infer/error_reporting/anon_anon_conflict.rs index c80ce3c96f1..d3fff4c66af 100644 --- a/src/librustc/infer/error_reporting/anon_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/anon_anon_conflict.rs @@ -209,18 +209,19 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { match arg.node { hir::TyRptr(ref lifetime, _) => { - match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) { + let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id); + match self.infcx.tcx.named_region(hir_id) { // the lifetime of the TyRptr - Some(&rl::Region::LateBoundAnon(debruijn_index, anon_index)) => { + Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)) => { if debruijn_index.depth == 1 && anon_index == br_index { self.found_type = Some(arg); return; // we can stop visiting now } } - Some(&rl::Region::Static) | - Some(&rl::Region::EarlyBound(_, _)) | - Some(&rl::Region::LateBound(_, _)) | - Some(&rl::Region::Free(_, _)) | + Some(rl::Region::Static) | + Some(rl::Region::EarlyBound(_, _)) | + Some(rl::Region::LateBound(_, _)) | + Some(rl::Region::Free(_, _)) | None => { debug!("no arg found"); } @@ -272,17 +273,18 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { _ => return, }; - match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) { + let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id); + match self.infcx.tcx.named_region(hir_id) { // the lifetime of the TyPath! - Some(&rl::Region::LateBoundAnon(debruijn_index, anon_index)) => { + Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)) => { if debruijn_index.depth == 1 && anon_index == br_index { self.found_it = true; } } - Some(&rl::Region::Static) | - Some(&rl::Region::EarlyBound(_, _)) | - Some(&rl::Region::LateBound(_, _)) | - Some(&rl::Region::Free(_, _)) | + Some(rl::Region::Static) | + Some(rl::Region::EarlyBound(_, _)) | + Some(rl::Region::LateBound(_, _)) | + Some(rl::Region::Free(_, _)) | None => { debug!("no arg found"); } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0b9bf9a708a..f2e40e3693a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -23,7 +23,7 @@ use lint::{self, Lint}; use ich::{self, StableHashingContext, NodeIdHashingMode}; use middle::free_region::FreeRegionMap; use middle::lang_items; -use middle::resolve_lifetime; +use middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use middle::stability; use mir::Mir; use mir::transform::Passes; @@ -822,7 +822,7 @@ pub struct GlobalCtxt<'tcx> { /// Export map produced by name resolution. export_map: FxHashMap>>, - pub named_region_map: resolve_lifetime::NamedRegionMap, + named_region_map: NamedRegionMap, pub hir: hir_map::Map<'tcx>, @@ -1054,7 +1054,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { global_interners: interners, dep_graph: dep_graph.clone(), types: common_types, - named_region_map, + named_region_map: NamedRegionMap { + defs: + named_region_map.defs + .into_iter() + .map(|(k, v)| (hir.node_to_hir_id(k), v)) + .collect(), + late_bound: + named_region_map.late_bound + .into_iter() + .map(|k| hir.node_to_hir_id(k)) + .collect(), + object_lifetime_defaults: + named_region_map.object_lifetime_defaults + .into_iter() + .map(|(k, v)| (hir.node_to_hir_id(k), Rc::new(v))) + .collect(), + }, trait_map: resolutions.trait_map.into_iter().map(|(k, v)| { (hir.node_to_hir_id(k), Rc::new(v)) }).collect(), @@ -1978,19 +1994,18 @@ impl InternIteratorElement for Result { } } -fn in_scope_traits<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: HirId) - -> Option>> -{ - tcx.gcx.trait_map.get(&id).cloned() -} - -fn module_exports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: HirId) - -> Option>> -{ - tcx.gcx.export_map.get(&id).cloned() +struct NamedRegionMap { + defs: FxHashMap, + late_bound: FxHashSet, + object_lifetime_defaults: FxHashMap>>, } pub fn provide(providers: &mut ty::maps::Providers) { - providers.in_scope_traits = in_scope_traits; - providers.module_exports = module_exports; + providers.in_scope_traits = |tcx, id| tcx.gcx.trait_map.get(&id).cloned(); + providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned(); + providers.named_region = |tcx, id| tcx.gcx.named_region_map.defs.get(&id).cloned(); + providers.is_late_bound = |tcx, id| tcx.gcx.named_region_map.late_bound.contains(&id); + providers.object_lifetime_defaults = |tcx, id| { + tcx.gcx.named_region_map.object_lifetime_defaults.get(&id).cloned() + }; } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 1312bd3a7a6..d4bd434add4 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -20,6 +20,8 @@ use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary}; use middle::cstore::NativeLibraryKind; use middle::privacy::AccessLevels; use middle::region; +use middle::region::RegionMaps; +use middle::resolve_lifetime::{Region, ObjectLifetimeDefault}; use mir; use mir::transform::{MirSuite, MirPassIndex}; use session::CompileResult; @@ -649,6 +651,24 @@ impl<'tcx> QueryDescription for queries::link_args<'tcx> { } } +impl<'tcx> QueryDescription for queries::named_region<'tcx> { + fn describe(_tcx: TyCtxt, _: HirId) -> String { + format!("fetching info about a named region") + } +} + +impl<'tcx> QueryDescription for queries::is_late_bound<'tcx> { + fn describe(_tcx: TyCtxt, _: HirId) -> String { + format!("testing whether a lifetime is late bound") + } +} + +impl<'tcx> QueryDescription for queries::object_lifetime_defaults<'tcx> { + fn describe(_tcx: TyCtxt, _: HirId) -> String { + format!("fetching a list of ObjectLifetimeDefault for a lifetime") + } +} + // If enabled, send a message to the profile-queries thread macro_rules! profq_msg { ($tcx:expr, $msg:expr) => { @@ -1243,6 +1263,11 @@ define_maps! { <'tcx> [] native_library_kind: NativeLibraryKind(DefId) -> Option, [] link_args: link_args_node(CrateNum) -> Rc>, + + [] named_region: NamedRegion(HirId) -> Option, + [] is_late_bound: IsLateBound(HirId) -> bool, + [] object_lifetime_defaults: ObjectLifetimeDefaults(HirId) + -> Option>>, } fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ee1e6bd950f..f391c2f9279 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -96,22 +96,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { -> ty::Region<'tcx> { let tcx = self.tcx(); - let r = match tcx.named_region_map.defs.get(&lifetime.id) { - Some(&rl::Region::Static) => { + let hir_id = tcx.hir.node_to_hir_id(lifetime.id); + let r = match tcx.named_region(hir_id) { + Some(rl::Region::Static) => { tcx.types.re_static } - Some(&rl::Region::LateBound(debruijn, id)) => { + Some(rl::Region::LateBound(debruijn, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReLateBound(debruijn, ty::BrNamed(tcx.hir.local_def_id(id), name))) } - Some(&rl::Region::LateBoundAnon(debruijn, index)) => { + Some(rl::Region::LateBoundAnon(debruijn, index)) => { tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index))) } - Some(&rl::Region::EarlyBound(index, id)) => { + Some(rl::Region::EarlyBound(index, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: tcx.hir.local_def_id(id), @@ -120,7 +121,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { })) } - Some(&rl::Region::Free(scope, id)) => { + Some(rl::Region::Free(scope, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReFree(ty::FreeRegion { scope, @@ -627,7 +628,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.ast_region_to_region(lifetime, None) } else { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { - if tcx.named_region_map.defs.contains_key(&lifetime.id) { + let hir_id = tcx.hir.node_to_hir_id(lifetime.id); + if tcx.named_region(hir_id).is_some() { self.ast_region_to_region(lifetime, None) } else { self.re_infer(span, None).unwrap_or_else(|| { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index c177623af48..38b72677bc6 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -812,7 +812,8 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) { if self.has_late_bound_regions.is_some() { return } - match self.tcx.named_region_map.defs.get(<.id).cloned() { + let hir_id = self.tcx.hir.node_to_hir_id(lt.id); + match self.tcx.named_region(hir_id) { Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {} Some(rl::Region::LateBound(debruijn, _)) | Some(rl::Region::LateBoundAnon(debruijn, _)) @@ -830,7 +831,8 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx, binder_depth: 1, has_late_bound_regions: None }; for lifetime in &generics.lifetimes { - if tcx.named_region_map.late_bound.contains(&lifetime.lifetime.id) { + let hir_id = tcx.hir.node_to_hir_id(lifetime.lifetime.id); + if tcx.is_late_bound(hir_id) { return Some(lifetime.lifetime.span); } } @@ -987,8 +989,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }).collect::>(); - let object_lifetime_defaults = - tcx.named_region_map.object_lifetime_defaults.get(&node_id); + let hir_id = tcx.hir.node_to_hir_id(node_id); + let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id); // Now create the real type parameters. let type_start = own_start + regions.len() as u32; @@ -1014,7 +1016,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: tcx.hir.local_def_id(p.id), has_default: p.default.is_some(), object_lifetime_default: - object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]), + object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]), pure_wrt_drop: p.pure_wrt_drop, } }); @@ -1343,7 +1345,10 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>( ast_generics .lifetimes .iter() - .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id)) + .filter(move |l| { + let hir_id = tcx.hir.node_to_hir_id(l.lifetime.id); + !tcx.is_late_bound(hir_id) + }) } fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aab44ddce0e..f446bf587bd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -830,7 +830,8 @@ impl Lifetime { impl Clean for hir::Lifetime { fn clean(&self, cx: &DocContext) -> Lifetime { - let def = cx.tcx.named_region_map.defs.get(&self.id).cloned(); + let hir_id = cx.tcx.hir.node_to_hir_id(self.id); + let def = cx.tcx.named_region(hir_id); match def { Some(rl::Region::EarlyBound(_, node_id)) | Some(rl::Region::LateBound(_, node_id)) |