Store LocalDefId in is_late_bound_map.
This allows to avoid looking at HIR from borrowck.
This commit is contained in:
parent
db03a2deb0
commit
69d8183337
6 changed files with 42 additions and 28 deletions
compiler
rustc_borrowck/src
rustc_middle/src
rustc_resolve/src/late
rustc_typeck/src
|
@ -828,13 +828,11 @@ fn for_each_late_bound_region_defined_on<'tcx>(
|
||||||
mut f: impl FnMut(ty::Region<'tcx>),
|
mut f: impl FnMut(ty::Region<'tcx>),
|
||||||
) {
|
) {
|
||||||
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
|
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
|
||||||
for &late_bound in late_bounds.iter() {
|
for ®ion_def_id in late_bounds.iter() {
|
||||||
let region_def_id =
|
let name = tcx.item_name(region_def_id.to_def_id());
|
||||||
tcx.hir().local_def_id(HirId { owner, local_id: late_bound }).to_def_id();
|
|
||||||
let name = tcx.item_name(region_def_id);
|
|
||||||
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||||
scope: owner.to_def_id(),
|
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);
|
f(liberated_region);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub struct ResolveLifetimes {
|
||||||
/// Set of lifetime def ids that are late-bound; a region can
|
/// 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
|
/// be late-bound if (a) it does NOT appear in a where-clause and
|
||||||
/// (b) it DOES appear in the arguments.
|
/// (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>>>,
|
pub late_bound_vars: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1502,8 +1502,7 @@ rustc_queries! {
|
||||||
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
|
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
|
||||||
desc { "looking up a named region" }
|
desc { "looking up a named region" }
|
||||||
}
|
}
|
||||||
query is_late_bound_map(_: LocalDefId) ->
|
query is_late_bound_map(_: LocalDefId) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
|
||||||
Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
|
|
||||||
desc { "testing if a region is late bound" }
|
desc { "testing if a region is late bound" }
|
||||||
}
|
}
|
||||||
/// For a given item (like a struct), gets the default lifetimes to be used
|
/// For a given item (like a struct), gets the default lifetimes to be used
|
||||||
|
|
|
@ -2772,11 +2772,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
|
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> {
|
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
|
||||||
self.mk_bound_variable_kinds(
|
self.mk_bound_variable_kinds(
|
||||||
self.late_bound_vars_map(id.owner)
|
self.late_bound_vars_map(id.owner)
|
||||||
|
|
|
@ -427,7 +427,7 @@ fn resolve_lifetimes_trait_definition(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
local_def_id: LocalDefId,
|
local_def_id: LocalDefId,
|
||||||
) -> ResolveLifetimes {
|
) -> 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`.
|
/// 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.
|
/// `named_region_map`, `is_late_bound_map`, etc.
|
||||||
#[tracing::instrument(level = "debug", skip(tcx))]
|
#[tracing::instrument(level = "debug", skip(tcx))]
|
||||||
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
|
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(
|
fn do_resolve(
|
||||||
|
@ -468,7 +468,7 @@ fn do_resolve(
|
||||||
named_region_map
|
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();
|
let mut rl = ResolveLifetimes::default();
|
||||||
|
|
||||||
for (hir_id, v) in named_region_map.defs {
|
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 {
|
for hir_id in named_region_map.late_bound {
|
||||||
let map = rl.late_bound.entry(hir_id.owner).or_default();
|
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 {
|
for (hir_id, v) in named_region_map.late_bound_vars {
|
||||||
let map = rl.late_bound_vars.entry(hir_id.owner).or_default();
|
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>(
|
fn is_late_bound_map<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
|
) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
|
||||||
match tcx.def_kind(def_id) {
|
match tcx.def_kind(def_id) {
|
||||||
DefKind::AnonConst | DefKind::InlineConst => {
|
DefKind::AnonConst | DefKind::InlineConst => {
|
||||||
let mut def_id = tcx
|
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() {
|
for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() {
|
||||||
late_bound.iter().for_each(|&local_id| {
|
late_bound.iter().for_each(|&id| {
|
||||||
self.map.late_bound.insert(hir::HirId { owner, local_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
|
for (&owner, late_bound_vars) in
|
||||||
|
|
|
@ -1388,6 +1388,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||||
|
|
||||||
fn has_late_bound_regions<'tcx>(
|
fn has_late_bound_regions<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
generics: &'tcx hir::Generics<'tcx>,
|
generics: &'tcx hir::Generics<'tcx>,
|
||||||
decl: &'tcx hir::FnDecl<'tcx>,
|
decl: &'tcx hir::FnDecl<'tcx>,
|
||||||
) -> Option<Span> {
|
) -> Option<Span> {
|
||||||
|
@ -1396,9 +1397,14 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||||
outer_index: ty::INNERMOST,
|
outer_index: ty::INNERMOST,
|
||||||
has_late_bound_regions: None,
|
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 {
|
for param in generics.params {
|
||||||
if let GenericParamKind::Lifetime { .. } = param.kind {
|
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);
|
return Some(param.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1410,25 +1416,25 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||||
match node {
|
match node {
|
||||||
Node::TraitItem(item) => match item.kind {
|
Node::TraitItem(item) => match item.kind {
|
||||||
hir::TraitItemKind::Fn(ref sig, _) => {
|
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,
|
_ => None,
|
||||||
},
|
},
|
||||||
Node::ImplItem(item) => match item.kind {
|
Node::ImplItem(item) => match item.kind {
|
||||||
hir::ImplItemKind::Fn(ref sig, _) => {
|
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,
|
_ => None,
|
||||||
},
|
},
|
||||||
Node::ForeignItem(item) => match item.kind {
|
Node::ForeignItem(item) => match item.kind {
|
||||||
hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => {
|
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,
|
_ => None,
|
||||||
},
|
},
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
|
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,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
@ -1677,7 +1683,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||||
params.push(opt_self);
|
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 {
|
params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
|
||||||
name: param.name.ident().name,
|
name: param.name.ident().name,
|
||||||
index: own_start + i as u32,
|
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`.
|
/// `resolve_lifetime::early_bound_lifetimes`.
|
||||||
fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
|
fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
generics: &'a hir::Generics<'a>,
|
generics: &'a hir::Generics<'a>,
|
||||||
) -> impl Iterator<Item = &'a hir::GenericParam<'a>> + Captures<'tcx> {
|
) -> 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 {
|
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,
|
_ => 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
|
// well. In the case of parameters declared on a fn or method, we
|
||||||
// have to be careful to only iterate over early-bound regions.
|
// have to be careful to only iterate over early-bound regions.
|
||||||
let mut index = parent_count + has_own_self as u32;
|
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 {
|
let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
|
||||||
def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
|
def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
|
||||||
index,
|
index,
|
||||||
|
|
Loading…
Add table
Reference in a new issue