1
Fork 0
This commit is contained in:
b-naber 2022-11-10 13:59:01 +01:00 committed by b-naber
parent 46bd77aa80
commit 2d2bccf751
4 changed files with 92 additions and 81 deletions

View file

@ -9,7 +9,7 @@ use rustc_middle::mir::{Body, Location, Promoted};
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use rustc_span::Symbol; use rustc_span::{Span, Symbol};
/// Replaces all free regions appearing in the MIR with fresh /// Replaces all free regions appearing in the MIR with fresh
/// inference variables, returning the number of variables created. /// inference variables, returning the number of variables created.
@ -62,16 +62,23 @@ where
}) })
} }
#[cfg(debug_assertions)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) enum BoundRegionInfo {
Name(Symbol),
Span(Span),
}
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) enum RegionCtxt { pub(crate) enum RegionCtxt {
Location(Location), Location(Location),
TyContext(TyContext), TyContext(TyContext),
Free(Symbol), Free(Symbol),
Bound(Symbol), Bound(BoundRegionInfo),
LateBound(Symbol), LateBound(BoundRegionInfo),
Existential(Option<Symbol>), Existential(Option<Symbol>),
Placeholder(Symbol), Placeholder(BoundRegionInfo),
Unknown, Unknown,
} }
@ -86,10 +93,7 @@ impl RegionCtxt {
match self { match self {
RegionCtxt::Unknown => 1, RegionCtxt::Unknown => 1,
RegionCtxt::Existential(None) => 2, RegionCtxt::Existential(None) => 2,
RegionCtxt::Existential(Some(_anon)) RegionCtxt::Existential(Some(_anon)) | RegionCtxt::Free(_anon) => 2,
| RegionCtxt::Free(_anon)
| RegionCtxt::Bound(_anon)
| RegionCtxt::LateBound(_anon) => 2,
RegionCtxt::Location(_) => 3, RegionCtxt::Location(_) => 3,
RegionCtxt::TyContext(_) => 4, RegionCtxt::TyContext(_) => 4,
_ => 5, _ => 5,

View file

@ -1346,13 +1346,21 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
use crate::renumber::RegionCtxt; use crate::renumber::{BoundRegionInfo, RegionCtxt};
use rustc_span::Symbol; use rustc_span::Symbol;
let name = match br.kind { let reg_info = match br.kind {
ty::BoundRegionKind::BrAnon(_) => Symbol::intern("anon"), // FIXME Probably better to use the `Span` here
ty::BoundRegionKind::BrNamed(_, name) => name, ty::BoundRegionKind::BrAnon(_, Some(span)) => {
ty::BoundRegionKind::BrEnv => Symbol::intern("env"), BoundRegionInfo::Span(span)
}
ty::BoundRegionKind::BrAnon(..) => {
BoundRegionInfo::Name(Symbol::intern("anon"))
}
ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
ty::BoundRegionKind::BrEnv => {
BoundRegionInfo::Name(Symbol::intern("env"))
}
}; };
self.infcx.next_region_var( self.infcx.next_region_var(
@ -1361,7 +1369,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
br.kind, br.kind,
LateBoundRegionConversionTime::FnCall, LateBoundRegionConversionTime::FnCall,
), ),
RegionCtxt::LateBound(name), RegionCtxt::LateBound(reg_info),
) )
} }
}); });

View file

@ -10,7 +10,7 @@ use rustc_trait_selection::traits::query::Fallible;
use crate::constraints::OutlivesConstraint; use crate::constraints::OutlivesConstraint;
use crate::diagnostics::UniverseInfo; use crate::diagnostics::UniverseInfo;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use crate::renumber::RegionCtxt; use crate::renumber::{BoundRegionInfo, RegionCtxt};
use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker}; use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
impl<'a, 'tcx> TypeChecker<'a, 'tcx> { impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@ -130,17 +130,19 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
let name = match placeholder.name { let reg_info = match placeholder.name {
ty::BoundRegionKind::BrAnon(_) => Symbol::intern("anon"), // FIXME Probably better to use the `Span` here
ty::BoundRegionKind::BrNamed(_, name) => name, ty::BoundRegionKind::BrAnon(_, Some(span)) => BoundRegionInfo::Span(span),
ty::BoundRegionKind::BrEnv => Symbol::intern("env"), ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(Symbol::intern("anon")),
ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(Symbol::intern("env")),
}; };
let reg_var = reg let reg_var = reg
.try_get_var() .try_get_var()
.unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg)); .unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(name)); let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
assert!(matches!(prev, None)); assert!(matches!(prev, None));
} }

View file

@ -32,7 +32,7 @@ use std::iter;
use crate::nll::ToRegionVid; use crate::nll::ToRegionVid;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use crate::renumber::RegionCtxt; use crate::renumber::{BoundRegionInfo, RegionCtxt};
use crate::BorrowckInferCtxt; use crate::BorrowckInferCtxt;
#[derive(Debug)] #[derive(Debug)]
@ -446,7 +446,22 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|r| { |r| {
debug!(?r); debug!(?r);
if !indices.indices.contains_key(&r) { if !indices.indices.contains_key(&r) {
#[cfg(not(debug_assertions))]
let region_vid = self.infcx.next_nll_region_var(FR); let region_vid = self.infcx.next_nll_region_var(FR);
#[cfg(debug_assertions)]
let region_vid = {
let name = match r.get_name() {
Some(name) => name,
_ => Symbol::intern("anon"),
};
self.infcx.next_nll_region_var(
FR,
RegionCtxt::LateBound(BoundRegionInfo::Name(name)),
)
};
debug!(?region_vid); debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid()); indices.insert_late_bound_region(r, region_vid.to_region_vid());
} }
@ -474,7 +489,20 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| { for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
debug!(?r); debug!(?r);
if !indices.indices.contains_key(&r) { if !indices.indices.contains_key(&r) {
#[cfg(not(debug_assertions))]
let region_vid = self.infcx.next_nll_region_var(FR); let region_vid = self.infcx.next_nll_region_var(FR);
#[cfg(debug_assertions)]
let region_vid = {
let name = match r.get_name() {
Some(name) => name,
_ => Symbol::intern("anon"),
};
self.infcx
.next_nll_region_var(FR, RegionCtxt::LateBound(BoundRegionInfo::Name(name)))
};
debug!(?region_vid); debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid()); indices.insert_late_bound_region(r, region_vid.to_region_vid());
} }
@ -773,7 +801,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
}) })
} }
#[cfg(not(debug_assertions))]
#[instrument(level = "debug", skip(self, indices))] #[instrument(level = "debug", skip(self, indices))]
fn replace_bound_regions_with_nll_infer_vars<T>( fn replace_bound_regions_with_nll_infer_vars<T>(
&self, &self,
@ -788,39 +815,19 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
debug!(?br); debug!(?br);
let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind); let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind);
#[cfg(not(debug_assertions))]
let region_vid = self.next_nll_region_var(origin); let region_vid = self.next_nll_region_var(origin);
indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
debug!(?liberated_region, ?region_vid);
region_vid
});
value
}
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
#[instrument(level = "debug", skip(self, indices))] let region_vid = {
fn replace_bound_regions_with_nll_infer_vars<T>( let name = match br.kind.get_name() {
&self, Some(name) => name,
origin: NllRegionVariableOrigin, _ => Symbol::intern("anon"),
all_outlive_scope: LocalDefId, };
value: ty::Binder<'tcx, T>,
indices: &mut UniversalRegionIndices<'tcx>,
) -> T
where
T: TypeFoldable<'tcx>,
{
let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
debug!(?br);
let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: all_outlive_scope.to_def_id(),
bound_region: br.kind,
}));
let name = match br.kind.get_name() { self.next_nll_region_var(origin, RegionCtxt::Bound(BoundRegionInfo::Name(name)))
Some(name) => name,
_ => Symbol::intern("anon"),
}; };
let region_vid = self.next_nll_region_var(origin, RegionCtxt::Bound(name));
indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
debug!(?liberated_region, ?region_vid); debug!(?liberated_region, ?region_vid);
region_vid region_vid
@ -837,7 +844,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
/// entries for them and store them in the indices map. This code iterates over the complete /// entries for them and store them in the indices map. This code iterates over the complete
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the /// set of late-bound regions and checks for any that we have not yet seen, adding them to the
/// inputs vector. /// inputs vector.
#[cfg(not(debug_assertions))]
#[instrument(skip(self, indices))] #[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope( fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
&self, &self,
@ -847,7 +853,19 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| { for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| {
debug!(?r); debug!(?r);
if !indices.indices.contains_key(&r) { if !indices.indices.contains_key(&r) {
#[cfg(not(debug_assertions))]
let region_vid = self.next_nll_region_var(FR); let region_vid = self.next_nll_region_var(FR);
#[cfg(debug_assertions)]
let region_vid = {
let name = match r.get_name() {
Some(name) => name,
_ => Symbol::intern("anon"),
};
self.next_nll_region_var(FR, RegionCtxt::LateBound(BoundRegionInfo::Name(name)))
};
debug!(?region_vid); debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid()); indices.insert_late_bound_region(r, region_vid.to_region_vid());
} }
@ -863,40 +881,19 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| { for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| {
debug!(?r); debug!(?r);
if !indices.indices.contains_key(&r) { if !indices.indices.contains_key(&r) {
#[cfg(not(debug_assertions))]
let region_vid = self.next_nll_region_var(FR); let region_vid = self.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
});
}
/// Finds late-bound regions that do not appear in the parameter listing and adds them to the #[cfg(debug_assertions)]
/// indices vector. Typically, we identify late-bound regions as we process the inputs and let region_vid = {
/// outputs of the closure/function. However, sometimes there are late-bound regions which do let name = match r.get_name() {
/// not appear in the fn parameters but which are nonetheless in scope. The simplest case of Some(name) => name,
/// this are unused functions, like fn foo<'a>() { } (see e.g., #51351). Despite not being used, _ => Symbol::intern("anon"),
/// users can still reference these regions (e.g., let x: &'a u32 = &22;), so we need to create };
/// entries for them and store them in the indices map. This code iterates over the complete
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the self.next_nll_region_var(FR, RegionCtxt::LateBound(BoundRegionInfo::Name(name)))
/// inputs vector.
#[cfg(debug_assertions)]
#[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
) {
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| {
debug!(?r);
if !indices.indices.contains_key(&r) {
let name = match r.get_name() {
Some(name) => name,
_ => Symbol::intern("anon"),
}; };
let region_vid = self.next_nll_region_var(FR, RegionCtxt::LateBound(name));
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid()); indices.insert_late_bound_region(r, region_vid.to_region_vid());
} }
}); });