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.
This commit is contained in:
Alex Crichton 2017-08-30 09:31:14 -07:00
parent 64a70342e6
commit fd61fa5aef
7 changed files with 95 additions and 41 deletions

View File

@ -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 {

View File

@ -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");
}

View File

@ -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<HirId, Rc<Vec<Export>>>,
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<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
}
}
fn in_scope_traits<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: HirId)
-> Option<Rc<Vec<TraitCandidate>>>
{
tcx.gcx.trait_map.get(&id).cloned()
}
fn module_exports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: HirId)
-> Option<Rc<Vec<Export>>>
{
tcx.gcx.export_map.get(&id).cloned()
struct NamedRegionMap {
defs: FxHashMap<HirId, resolve_lifetime::Region>,
late_bound: FxHashSet<HirId>,
object_lifetime_defaults: FxHashMap<HirId, Rc<Vec<ObjectLifetimeDefault>>>,
}
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()
};
}

View File

@ -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<NativeLibraryKind>,
[] link_args: link_args_node(CrateNum) -> Rc<Vec<String>>,
[] named_region: NamedRegion(HirId) -> Option<Region>,
[] is_late_bound: IsLateBound(HirId) -> bool,
[] object_lifetime_defaults: ObjectLifetimeDefaults(HirId)
-> Option<Rc<Vec<ObjectLifetimeDefault>>>,
}
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {

View File

@ -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(|| {

View File

@ -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(&lt.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::<Vec<_>>();
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>,

View File

@ -830,7 +830,8 @@ impl Lifetime {
impl Clean<Lifetime> 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)) |