Store LocalDefId in is_late_bound_map.

This allows to avoid looking at HIR from borrowck.
This commit is contained in:
Camille GILLOT 2022-03-30 00:17:41 +02:00
parent db03a2deb0
commit 69d8183337
6 changed files with 42 additions and 28 deletions

View file

@ -828,13 +828,11 @@ fn for_each_late_bound_region_defined_on<'tcx>(
mut f: impl FnMut(ty::Region<'tcx>),
) {
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
for &late_bound in late_bounds.iter() {
let region_def_id =
tcx.hir().local_def_id(HirId { owner, local_id: late_bound }).to_def_id();
let name = tcx.item_name(region_def_id);
for &region_def_id in late_bounds.iter() {
let name = tcx.item_name(region_def_id.to_def_id());
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: owner.to_def_id(),
bound_region: ty::BoundRegionKind::BrNamed(region_def_id, name),
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
}));
f(liberated_region);
}

View file

@ -64,7 +64,7 @@ pub struct ResolveLifetimes {
/// Set of lifetime def ids that are late-bound; a region can
/// be late-bound if (a) it does NOT appear in a where-clause and
/// (b) it DOES appear in the arguments.
pub late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
pub late_bound: FxHashMap<LocalDefId, FxHashSet<LocalDefId>>,
pub late_bound_vars: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
}

View file

@ -1502,8 +1502,7 @@ rustc_queries! {
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
desc { "looking up a named region" }
}
query is_late_bound_map(_: LocalDefId) ->
Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
query is_late_bound_map(_: LocalDefId) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
desc { "testing if a region is late bound" }
}
/// For a given item (like a struct), gets the default lifetimes to be used

View file

@ -2772,11 +2772,6 @@ impl<'tcx> TyCtxt<'tcx> {
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
}
pub fn is_late_bound(self, id: HirId) -> bool {
self.is_late_bound_map(id.owner)
.map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
}
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds(
self.late_bound_vars_map(id.owner)

View file

@ -427,7 +427,7 @@ fn resolve_lifetimes_trait_definition(
tcx: TyCtxt<'_>,
local_def_id: LocalDefId,
) -> ResolveLifetimes {
convert_named_region_map(do_resolve(tcx, local_def_id, true, false))
convert_named_region_map(tcx, do_resolve(tcx, local_def_id, true, false))
}
/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
@ -435,7 +435,7 @@ fn resolve_lifetimes_trait_definition(
/// `named_region_map`, `is_late_bound_map`, etc.
#[tracing::instrument(level = "debug", skip(tcx))]
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
convert_named_region_map(do_resolve(tcx, local_def_id, false, false))
convert_named_region_map(tcx, do_resolve(tcx, local_def_id, false, false))
}
fn do_resolve(
@ -468,7 +468,7 @@ fn do_resolve(
named_region_map
}
fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes {
fn convert_named_region_map(tcx: TyCtxt<'_>, named_region_map: NamedRegionMap) -> ResolveLifetimes {
let mut rl = ResolveLifetimes::default();
for (hir_id, v) in named_region_map.defs {
@ -477,7 +477,8 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime
}
for hir_id in named_region_map.late_bound {
let map = rl.late_bound.entry(hir_id.owner).or_default();
map.insert(hir_id.local_id);
let def_id = tcx.hir().local_def_id(hir_id);
map.insert(def_id);
}
for (hir_id, v) in named_region_map.late_bound_vars {
let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
@ -537,7 +538,7 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
fn is_late_bound_map<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
match tcx.def_kind(def_id) {
DefKind::AnonConst | DefKind::InlineConst => {
let mut def_id = tcx
@ -774,8 +775,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
});
}
for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() {
late_bound.iter().for_each(|&local_id| {
self.map.late_bound.insert(hir::HirId { owner, local_id });
late_bound.iter().for_each(|&id| {
let hir_id = self.tcx.local_def_id_to_hir_id(id);
debug_assert_eq!(owner, hir_id.owner);
self.map.late_bound.insert(hir_id);
});
}
for (&owner, late_bound_vars) in

View file

@ -1388,6 +1388,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
fn has_late_bound_regions<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
generics: &'tcx hir::Generics<'tcx>,
decl: &'tcx hir::FnDecl<'tcx>,
) -> Option<Span> {
@ -1396,9 +1397,14 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
outer_index: ty::INNERMOST,
has_late_bound_regions: None,
};
let late_bound_map = tcx.is_late_bound_map(def_id);
let is_late_bound = |id| {
let id = tcx.hir().local_def_id(id);
late_bound_map.map_or(false, |(_, set)| set.contains(&id))
};
for param in generics.params {
if let GenericParamKind::Lifetime { .. } = param.kind {
if tcx.is_late_bound(param.hir_id) {
if is_late_bound(param.hir_id) {
return Some(param.span);
}
}
@ -1410,25 +1416,25 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
match node {
Node::TraitItem(item) => match item.kind {
hir::TraitItemKind::Fn(ref sig, _) => {
has_late_bound_regions(tcx, &item.generics, sig.decl)
has_late_bound_regions(tcx, item.def_id, &item.generics, sig.decl)
}
_ => None,
},
Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::Fn(ref sig, _) => {
has_late_bound_regions(tcx, &item.generics, sig.decl)
has_late_bound_regions(tcx, item.def_id, &item.generics, sig.decl)
}
_ => None,
},
Node::ForeignItem(item) => match item.kind {
hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => {
has_late_bound_regions(tcx, generics, fn_decl)
has_late_bound_regions(tcx, item.def_id, generics, fn_decl)
}
_ => None,
},
Node::Item(item) => match item.kind {
hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
has_late_bound_regions(tcx, generics, sig.decl)
has_late_bound_regions(tcx, item.def_id, generics, sig.decl)
}
_ => None,
},
@ -1677,7 +1683,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
params.push(opt_self);
}
let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
let early_lifetimes = early_bound_lifetimes_from_generics(tcx, hir_id.owner, ast_generics);
params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
name: param.name.ident().name,
index: own_start + i as u32,
@ -2034,10 +2040,23 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
/// `resolve_lifetime::early_bound_lifetimes`.
fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
generics: &'a hir::Generics<'a>,
) -> impl Iterator<Item = &'a hir::GenericParam<'a>> + Captures<'tcx> {
let late_bound_map = if generics.params.is_empty() {
// This function may be called on `def_id == CRATE_DEF_ID`,
// which makes `is_late_bound_map` ICE. Don't even try if there
// is no generic parameter.
None
} else {
tcx.is_late_bound_map(def_id)
};
let is_late_bound = move |hir_id| {
let id = tcx.hir().local_def_id(hir_id);
late_bound_map.map_or(false, |(_, set)| set.contains(&id))
};
generics.params.iter().filter(move |param| match param.kind {
GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
GenericParamKind::Lifetime { .. } => !is_late_bound(param.hir_id),
_ => false,
})
}
@ -2221,7 +2240,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
// well. In the case of parameters declared on a fn or method, we
// have to be careful to only iterate over early-bound regions.
let mut index = parent_count + has_own_self as u32;
for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
for param in early_bound_lifetimes_from_generics(tcx, hir_id.owner, ast_generics) {
let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
index,