rebase
This commit is contained in:
parent
46bd77aa80
commit
2d2bccf751
4 changed files with 92 additions and 81 deletions
|
@ -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,
|
||||||
|
|
|
@ -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),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue