uplift fold_regions to rustc_type_ir
This commit is contained in:
parent
f005c7437d
commit
9fe7750bcd
24 changed files with 129 additions and 115 deletions
|
@ -34,6 +34,7 @@ use rustc_infer::infer::{
|
||||||
use rustc_middle::mir::tcx::PlaceTy;
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
|
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_mir_dataflow::impls::{
|
use rustc_mir_dataflow::impls::{
|
||||||
|
@ -502,7 +503,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
|
||||||
for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) {
|
for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) {
|
||||||
// HIR typeck did not infer the regions of the opaque, so we instantiate
|
// HIR typeck did not infer the regions of the opaque, so we instantiate
|
||||||
// them with fresh inference variables.
|
// them with fresh inference variables.
|
||||||
let (key, hidden_ty) = tcx.fold_regions(data, |_, _| {
|
let (key, hidden_ty) = fold_regions(tcx, data, |_, _| {
|
||||||
self.next_nll_region_var_in_universe(
|
self.next_nll_region_var_in_universe(
|
||||||
NllRegionVariableOrigin::Existential { from_forall: false },
|
NllRegionVariableOrigin::Existential { from_forall: false },
|
||||||
ty::UniverseIndex::ROOT,
|
ty::UniverseIndex::ROOT,
|
||||||
|
|
|
@ -18,6 +18,7 @@ use rustc_middle::mir::{
|
||||||
TerminatorKind,
|
TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex};
|
||||||
use rustc_mir_dataflow::points::DenseLocationMap;
|
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -1100,7 +1101,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
let ty = ty.fold_with(&mut OpaqueFolder { tcx });
|
let ty = ty.fold_with(&mut OpaqueFolder { tcx });
|
||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
|
|
||||||
let ty = tcx.fold_regions(ty, |r, _depth| {
|
let ty = fold_regions(tcx, ty, |r, _depth| {
|
||||||
let r_vid = self.to_region_vid(r);
|
let r_vid = self.to_region_vid(r);
|
||||||
let r_scc = self.constraint_sccs.scc(r_vid);
|
let r_scc = self.constraint_sccs.scc(r_vid);
|
||||||
|
|
||||||
|
@ -1273,7 +1274,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
tcx.fold_regions(value, |r, _db| {
|
fold_regions(tcx, value, |r, _db| {
|
||||||
let vid = self.to_region_vid(r);
|
let vid = self.to_region_vid(r);
|
||||||
let scc = self.constraint_sccs.scc(vid);
|
let scc = self.constraint_sccs.scc(vid);
|
||||||
let repr = self.scc_representative(scc);
|
let repr = self.scc_representative(scc);
|
||||||
|
|
|
@ -3,6 +3,7 @@ use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _};
|
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _};
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
|
self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
|
||||||
|
@ -117,7 +118,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
});
|
});
|
||||||
debug!(?opaque_type_key, ?arg_regions);
|
debug!(?opaque_type_key, ?arg_regions);
|
||||||
|
|
||||||
let concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| {
|
let concrete_type = fold_regions(infcx.tcx, concrete_type, |region, _| {
|
||||||
arg_regions
|
arg_regions
|
||||||
.iter()
|
.iter()
|
||||||
.find(|&&(arg_vid, _)| self.eval_equal(region.as_var(), arg_vid))
|
.find(|&&(arg_vid, _)| self.eval_equal(region.as_var(), arg_vid))
|
||||||
|
@ -204,7 +205,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
tcx.fold_regions(ty, |region, _| match *region {
|
fold_regions(tcx, ty, |region, _| match *region {
|
||||||
ty::ReVar(vid) => {
|
ty::ReVar(vid) => {
|
||||||
let scc = self.constraint_sccs.scc(vid);
|
let scc = self.constraint_sccs.scc(vid);
|
||||||
|
|
||||||
|
@ -442,7 +443,7 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> {
|
||||||
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
||||||
|
|
||||||
let mut seen = vec![tcx.lifetimes.re_static];
|
let mut seen = vec![tcx.lifetimes.re_static];
|
||||||
let canonical_args = tcx.fold_regions(args, |r1, _| {
|
let canonical_args = fold_regions(tcx, args, |r1, _| {
|
||||||
if r1.is_error() {
|
if r1.is_error() {
|
||||||
r1
|
r1
|
||||||
} else if let Some(&r2) = seen.iter().find(|&&r2| {
|
} else if let Some(&r2) = seen.iter().find(|&&r2| {
|
||||||
|
|
|
@ -2,6 +2,7 @@ use rustc_index::IndexSlice;
|
||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||||
use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
|
use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
@ -68,7 +69,7 @@ impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> {
|
||||||
F: Fn() -> RegionCtxt,
|
F: Fn() -> RegionCtxt,
|
||||||
{
|
{
|
||||||
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
|
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
|
||||||
self.infcx.tcx.fold_regions(value, |_region, _depth| {
|
fold_regions(self.infcx.tcx, value, |_region, _depth| {
|
||||||
self.infcx.next_nll_region_var(origin, || region_ctxt_fn())
|
self.infcx.next_nll_region_var(origin, || region_ctxt_fn())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use rustc_middle::bug;
|
||||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::ScrubbedTraitError;
|
use rustc_trait_selection::traits::ScrubbedTraitError;
|
||||||
|
@ -216,7 +217,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||||
/// are dealt with during trait solving.
|
/// are dealt with during trait solving.
|
||||||
fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
|
fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
|
||||||
if value.has_placeholders() {
|
if value.has_placeholders() {
|
||||||
self.tcx.fold_regions(value, |r, _| match *r {
|
fold_regions(self.tcx, value, |r, _| match *r {
|
||||||
ty::RePlaceholder(placeholder) => {
|
ty::RePlaceholder(placeholder) => {
|
||||||
self.constraints.placeholder_region(self.infcx, placeholder)
|
self.constraints.placeholder_region(self.infcx, placeholder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ use rustc_middle::mir::*;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::cast::CastTy;
|
use rustc_middle::ty::cast::CastTy;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
|
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
|
||||||
|
@ -213,7 +214,7 @@ pub(crate) fn type_check<'a, 'tcx>(
|
||||||
|
|
||||||
// Convert all regions to nll vars.
|
// Convert all regions to nll vars.
|
||||||
let (opaque_type_key, hidden_type) =
|
let (opaque_type_key, hidden_type) =
|
||||||
infcx.tcx.fold_regions((opaque_type_key, hidden_type), |region, _| {
|
fold_regions(infcx.tcx, (opaque_type_key, hidden_type), |region, _| {
|
||||||
match region.kind() {
|
match region.kind() {
|
||||||
ty::ReVar(_) => region,
|
ty::ReVar(_) => region,
|
||||||
ty::RePlaceholder(placeholder) => {
|
ty::RePlaceholder(placeholder) => {
|
||||||
|
@ -2073,7 +2074,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
|
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
|
||||||
let unsize_to = tcx.fold_regions(ty, |r, _| {
|
let unsize_to = fold_regions(tcx, ty, |r, _| {
|
||||||
if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r }
|
if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r }
|
||||||
});
|
});
|
||||||
self.prove_trait_ref(
|
self.prove_trait_ref(
|
||||||
|
|
|
@ -26,7 +26,7 @@ use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::{TypeFoldable, fold_regions};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty,
|
self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty,
|
||||||
|
@ -824,7 +824,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
self.infcx.tcx.fold_regions(value, |region, _depth| {
|
fold_regions(self.infcx.tcx, value, |region, _depth| {
|
||||||
let name = region.get_name_or_anon();
|
let name = region.get_name_or_anon();
|
||||||
debug!(?region, ?name);
|
debug!(?region, ?name);
|
||||||
|
|
||||||
|
@ -906,7 +906,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
tcx.fold_regions(value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region)))
|
fold_regions(tcx, value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
|
||||||
use rustc_middle::middle::stability::EvalResult;
|
use rustc_middle::middle::stability::EvalResult;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::error::TypeErrorToStringExt;
|
use rustc_middle::ty::error::TypeErrorToStringExt;
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::{BottomUpFolder, fold_regions};
|
||||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||||
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
|
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
|
@ -346,7 +346,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
|
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
|
||||||
// here rather than using ReErased.
|
// here rather than using ReErased.
|
||||||
let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
|
let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
|
||||||
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
|
let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() {
|
||||||
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
|
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
|
||||||
_ => re,
|
_ => re,
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,6 +34,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||||
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode};
|
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
|
@ -1415,7 +1416,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
||||||
GenericParamKind::Lifetime { .. } => true,
|
GenericParamKind::Lifetime { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r {
|
let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
|
||||||
ty::ReErased => {
|
ty::ReErased => {
|
||||||
if has_region_params {
|
if has_region_params {
|
||||||
ty::Region::new_error_with_message(
|
ty::Region::new_error_with_message(
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::HirId;
|
use rustc_hir::HirId;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||||
use rustc_middle::ty::util::IntTypeExt;
|
use rustc_middle::ty::util::IntTypeExt;
|
||||||
use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
@ -113,7 +114,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
// so no need for ConstArg.
|
// so no need for ConstArg.
|
||||||
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => {
|
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => {
|
||||||
let ty = tcx.typeck(def_id).node_type(tcx.local_def_id_to_hir_id(def_id));
|
let ty = tcx.typeck(def_id).node_type(tcx.local_def_id_to_hir_id(def_id));
|
||||||
let ty = tcx.fold_regions(ty, |r, _| {
|
let ty = fold_regions(tcx, ty, |r, _| {
|
||||||
if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r }
|
if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r }
|
||||||
});
|
});
|
||||||
let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false, None) {
|
let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false, None) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::middle::stability::AllowUnstable;
|
use rustc_middle::middle::stability::AllowUnstable;
|
||||||
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
|
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
|
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
|
||||||
|
@ -1569,7 +1570,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
|
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
|
let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
|
||||||
// FIXME: Don't bother dealing with non-lifetime binders here...
|
// FIXME: Don't bother dealing with non-lifetime binders here...
|
||||||
if value.has_escaping_bound_vars() {
|
if value.has_escaping_bound_vars() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
|
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypingMode};
|
use rustc_middle::ty::{self, TyCtxt, TypingMode};
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||||
|
@ -75,7 +76,7 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||||
// This visitor can walk into binders, resulting in the `tcx_ty` to
|
// This visitor can walk into binders, resulting in the `tcx_ty` to
|
||||||
// potentially reference escaping bound variables. We simply erase
|
// potentially reference escaping bound variables. We simply erase
|
||||||
// those here.
|
// those here.
|
||||||
let tcx_ty = self.tcx.fold_regions(tcx_ty, |r, _| {
|
let tcx_ty = fold_regions(self.tcx, tcx_ty, |r, _| {
|
||||||
if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
|
if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
|
||||||
});
|
});
|
||||||
let cause = traits::ObligationCause::new(
|
let cause = traits::ObligationCause::new(
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
|
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, fold_regions};
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperFoldable};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperFoldable};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -827,7 +827,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
||||||
// no reason to keep regions around. They will be repopulated during MIR
|
// no reason to keep regions around. They will be repopulated during MIR
|
||||||
// borrowck, and specifically region constraints will be populated during
|
// borrowck, and specifically region constraints will be populated during
|
||||||
// MIR typeck which is run on the new body.
|
// MIR typeck which is run on the new body.
|
||||||
value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased);
|
//
|
||||||
|
// We're not using `tcx.erase_regions` as that also anonymizes bound variables,
|
||||||
|
// regressing borrowck diagnostics.
|
||||||
|
value = fold_regions(tcx, value, |_, _| tcx.lifetimes.re_erased);
|
||||||
|
|
||||||
// Normalize consts in writeback, because GCE doesn't normalize eagerly.
|
// Normalize consts in writeback, because GCE doesn't normalize eagerly.
|
||||||
if tcx.features().generic_const_exprs() {
|
if tcx.features().generic_const_exprs() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_data_structures::graph::implementation::{
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_data_structures::unord::UnordSet;
|
use rustc_data_structures::unord::UnordSet;
|
||||||
use rustc_index::{IndexSlice, IndexVec};
|
use rustc_index::{IndexSlice, IndexVec};
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::{TypeFoldable, fold_regions};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, ReBound, ReEarlyParam, ReErased, ReError, ReLateParam, RePlaceholder, ReStatic, ReVar,
|
self, ReBound, ReEarlyParam, ReErased, ReError, ReLateParam, RePlaceholder, ReStatic, ReVar,
|
||||||
Region, RegionVid, Ty, TyCtxt,
|
Region, RegionVid, Ty, TyCtxt,
|
||||||
|
@ -974,7 +974,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r))
|
fold_regions(tcx, value, |r, _db| self.resolve_region(tcx, r))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
|
fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
|
||||||
|
|
|
@ -33,7 +33,7 @@ use rustc_middle::traits::select;
|
||||||
pub use rustc_middle::ty::IntVarValue;
|
pub use rustc_middle::ty::IntVarValue;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::fold::{
|
use rustc_middle::ty::fold::{
|
||||||
BoundVarReplacerDelegate, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
BoundVarReplacerDelegate, TypeFoldable, TypeFolder, TypeSuperFoldable, fold_regions,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
|
@ -1165,7 +1165,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
if value.has_infer_regions() {
|
if value.has_infer_regions() {
|
||||||
let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved"));
|
let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved"));
|
||||||
Ok(self.tcx.fold_regions(value, |re, _| {
|
Ok(fold_regions(self.tcx, value, |re, _| {
|
||||||
if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re }
|
if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re }
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -17,6 +17,7 @@ use smallvec::SmallVec;
|
||||||
|
|
||||||
use super::{ConstValue, SourceInfo};
|
use super::{ConstValue, SourceInfo};
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
|
use crate::ty::fold::fold_regions;
|
||||||
use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt};
|
use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt};
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
|
@ -315,7 +316,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
|
||||||
/// All regions of `ty` must be of kind `ReVar` and must represent
|
/// All regions of `ty` must be of kind `ReVar` and must represent
|
||||||
/// universal regions *external* to the closure.
|
/// universal regions *external* to the closure.
|
||||||
pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
|
pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
|
||||||
let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
|
let inner = fold_regions(tcx, ty, |r, depth| match r.kind() {
|
||||||
ty::ReVar(vid) => {
|
ty::ReVar(vid) => {
|
||||||
let br = ty::BoundRegion {
|
let br = ty::BoundRegion {
|
||||||
var: ty::BoundVar::new(vid.index()),
|
var: ty::BoundVar::new(vid.index()),
|
||||||
|
@ -334,7 +335,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
|
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
tcx.fold_regions(self.inner, |r, depth| match r.kind() {
|
fold_regions(tcx, self.inner, |r, depth| match r.kind() {
|
||||||
ty::ReBound(debruijn, br) => {
|
ty::ReBound(debruijn, br) => {
|
||||||
debug_assert_eq!(debruijn, depth);
|
debug_assert_eq!(debruijn, depth);
|
||||||
map(ty::RegionVid::new(br.var.index()))
|
map(ty::RegionVid::new(br.var.index()))
|
||||||
|
|
|
@ -2,9 +2,9 @@ use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_type_ir::data_structures::DelayedMap;
|
use rustc_type_ir::data_structures::DelayedMap;
|
||||||
pub use rustc_type_ir::fold::{
|
pub use rustc_type_ir::fold::{
|
||||||
FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region, shift_vars,
|
FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, fold_regions, shift_region,
|
||||||
|
shift_vars,
|
||||||
};
|
};
|
||||||
use tracing::{debug, instrument};
|
|
||||||
|
|
||||||
use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitableExt};
|
use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
|
||||||
|
@ -50,85 +50,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Region folder
|
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
|
||||||
/// Folds the escaping and free regions in `value` using `f`.
|
|
||||||
pub fn fold_regions<T>(
|
|
||||||
self,
|
|
||||||
value: T,
|
|
||||||
mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
|
|
||||||
) -> T
|
|
||||||
where
|
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
|
||||||
{
|
|
||||||
value.fold_with(&mut RegionFolder::new(self, &mut f))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Folds over the substructure of a type, visiting its component
|
|
||||||
/// types and all regions that occur *free* within it.
|
|
||||||
///
|
|
||||||
/// That is, function pointer types and trait object can introduce
|
|
||||||
/// new bound regions which are not visited by this visitors as
|
|
||||||
/// they are not free; only regions that occur free will be
|
|
||||||
/// visited by `fld_r`.
|
|
||||||
pub struct RegionFolder<'a, 'tcx> {
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
|
|
||||||
/// Stores the index of a binder *just outside* the stuff we have
|
|
||||||
/// visited. So this begins as INNERMOST; when we pass through a
|
|
||||||
/// binder, it is incremented (via `shift_in`).
|
|
||||||
current_index: ty::DebruijnIndex,
|
|
||||||
|
|
||||||
/// Callback invokes for each free region. The `DebruijnIndex`
|
|
||||||
/// points to the binder *just outside* the ones we have passed
|
|
||||||
/// through.
|
|
||||||
fold_region_fn:
|
|
||||||
&'a mut (dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx> + 'a),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
fold_region_fn: &'a mut dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
|
|
||||||
) -> RegionFolder<'a, 'tcx> {
|
|
||||||
RegionFolder { tcx, current_index: ty::INNERMOST, fold_region_fn }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
|
||||||
fn cx(&self) -> TyCtxt<'tcx> {
|
|
||||||
self.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
|
|
||||||
&mut self,
|
|
||||||
t: ty::Binder<'tcx, T>,
|
|
||||||
) -> ty::Binder<'tcx, T> {
|
|
||||||
self.current_index.shift_in(1);
|
|
||||||
let t = t.super_fold_with(self);
|
|
||||||
self.current_index.shift_out(1);
|
|
||||||
t
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug", ret)]
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
|
||||||
match *r {
|
|
||||||
ty::ReBound(debruijn, _) if debruijn < self.current_index => {
|
|
||||||
debug!(?self.current_index, "skipped bound region");
|
|
||||||
r
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
debug!(?self.current_index, "folding free region");
|
|
||||||
(self.fold_region_fn)(r, self.current_index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Bound vars replacer
|
// Bound vars replacer
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ use tracing::{debug, instrument};
|
||||||
use super::TypingEnv;
|
use super::TypingEnv;
|
||||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use crate::query::Providers;
|
use crate::query::Providers;
|
||||||
|
use crate::ty::fold::fold_regions;
|
||||||
use crate::ty::layout::{FloatExt, IntegerExt};
|
use crate::ty::layout::{FloatExt, IntegerExt};
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
|
self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
|
||||||
|
@ -735,7 +736,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
.filter(|decl| !decl.ignore_for_traits)
|
.filter(|decl| !decl.ignore_for_traits)
|
||||||
.map(move |decl| {
|
.map(move |decl| {
|
||||||
let mut vars = vec![];
|
let mut vars = vec![];
|
||||||
let ty = self.fold_regions(decl.ty, |re, debruijn| {
|
let ty = fold_regions(self, decl.ty, |re, debruijn| {
|
||||||
assert_eq!(re, self.lifetimes.re_erased);
|
assert_eq!(re, self.lifetimes.re_erased);
|
||||||
let var = ty::BoundVar::from_usize(vars.len());
|
let var = ty::BoundVar::from_usize(vars.len());
|
||||||
vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));
|
vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
@ -83,7 +84,7 @@ pub fn find_param_with_region<'tcx>(
|
||||||
// May return None; sometimes the tables are not yet populated.
|
// May return None; sometimes the tables are not yet populated.
|
||||||
let ty = fn_sig.inputs()[index];
|
let ty = fn_sig.inputs()[index];
|
||||||
let mut found_anon_region = false;
|
let mut found_anon_region = false;
|
||||||
let new_param_ty = tcx.fold_regions(ty, |r, _| {
|
let new_param_ty = fold_regions(tcx, ty, |r, _| {
|
||||||
if r == anon_region {
|
if r == anon_region {
|
||||||
found_anon_region = true;
|
found_anon_region = true;
|
||||||
replace_region
|
replace_region
|
||||||
|
|
|
@ -25,6 +25,7 @@ use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds};
|
||||||
pub use rustc_middle::traits::select::*;
|
pub use rustc_middle::traits::select::*;
|
||||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||||
use rustc_middle::ty::error::TypeErrorToStringExt;
|
use rustc_middle::ty::error::TypeErrorToStringExt;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
|
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
|
self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
|
||||||
|
@ -3209,7 +3210,7 @@ fn bind_coroutine_hidden_types_above<'tcx>(
|
||||||
// Only remap erased regions if we use them.
|
// Only remap erased regions if we use them.
|
||||||
if considering_regions {
|
if considering_regions {
|
||||||
bty = bty.map_bound(|ty| {
|
bty = bty.map_bound(|ty| {
|
||||||
tcx.fold_regions(ty, |r, current_depth| match r.kind() {
|
fold_regions(tcx, ty, |r, current_depth| match r.kind() {
|
||||||
ty::ReErased => {
|
ty::ReErased => {
|
||||||
let br = ty::BoundRegion {
|
let br = ty::BoundRegion {
|
||||||
var: ty::BoundVar::from_u32(counter),
|
var: ty::BoundVar::from_u32(counter),
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -86,7 +87,8 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME: This could use a real folder, I guess.
|
// FIXME: This could use a real folder, I guess.
|
||||||
let remapped_wf_tys = tcx.fold_regions(
|
let remapped_wf_tys = fold_regions(
|
||||||
|
tcx,
|
||||||
tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(),
|
tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(),
|
||||||
|region, _| {
|
|region, _| {
|
||||||
// If `region` is a `ReLateParam` that is captured by the
|
// If `region` is a `ReLateParam` that is captured by the
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
|
self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
|
||||||
};
|
};
|
||||||
|
@ -197,7 +198,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||||
// We have entered some binders as we've walked into the
|
// We have entered some binders as we've walked into the
|
||||||
// bounds of the RPITIT. Shift these binders back out when
|
// bounds of the RPITIT. Shift these binders back out when
|
||||||
// constructing the top-level projection predicate.
|
// constructing the top-level projection predicate.
|
||||||
let shifted_alias_ty = self.tcx.fold_regions(unshifted_alias_ty, |re, depth| {
|
let shifted_alias_ty = fold_regions(self.tcx, unshifted_alias_ty, |re, depth| {
|
||||||
if let ty::ReBound(index, bv) = re.kind() {
|
if let ty::ReBound(index, bv) = re.kind() {
|
||||||
if depth != ty::INNERMOST {
|
if depth != ty::INNERMOST {
|
||||||
return ty::Region::new_error_with_message(
|
return ty::Region::new_error_with_message(
|
||||||
|
|
|
@ -49,7 +49,7 @@ use std::mem;
|
||||||
|
|
||||||
use rustc_index::{Idx, IndexVec};
|
use rustc_index::{Idx, IndexVec};
|
||||||
use thin_vec::ThinVec;
|
use thin_vec::ThinVec;
|
||||||
use tracing::instrument;
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::data_structures::Lrc;
|
use crate::data_structures::Lrc;
|
||||||
use crate::inherent::*;
|
use crate::inherent::*;
|
||||||
|
@ -431,3 +431,75 @@ where
|
||||||
value.fold_with(&mut Shifter::new(cx, amount))
|
value.fold_with(&mut Shifter::new(cx, amount))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Region folder
|
||||||
|
|
||||||
|
pub fn fold_regions<I: Interner, T>(
|
||||||
|
cx: I,
|
||||||
|
value: T,
|
||||||
|
mut f: impl FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
|
||||||
|
) -> T
|
||||||
|
where
|
||||||
|
T: TypeFoldable<I>,
|
||||||
|
{
|
||||||
|
value.fold_with(&mut RegionFolder::new(cx, &mut f))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Folds over the substructure of a type, visiting its component
|
||||||
|
/// types and all regions that occur *free* within it.
|
||||||
|
///
|
||||||
|
/// That is, function pointer types and trait object can introduce
|
||||||
|
/// new bound regions which are not visited by this visitors as
|
||||||
|
/// they are not free; only regions that occur free will be
|
||||||
|
/// visited by `fld_r`.
|
||||||
|
pub struct RegionFolder<'a, I: Interner> {
|
||||||
|
cx: I,
|
||||||
|
|
||||||
|
/// Stores the index of a binder *just outside* the stuff we have
|
||||||
|
/// visited. So this begins as INNERMOST; when we pass through a
|
||||||
|
/// binder, it is incremented (via `shift_in`).
|
||||||
|
current_index: ty::DebruijnIndex,
|
||||||
|
|
||||||
|
/// Callback invokes for each free region. The `DebruijnIndex`
|
||||||
|
/// points to the binder *just outside* the ones we have passed
|
||||||
|
/// through.
|
||||||
|
fold_region_fn: &'a mut (dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region + 'a),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I: Interner> RegionFolder<'a, I> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(
|
||||||
|
cx: I,
|
||||||
|
fold_region_fn: &'a mut dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
|
||||||
|
) -> RegionFolder<'a, I> {
|
||||||
|
RegionFolder { cx, current_index: ty::INNERMOST, fold_region_fn }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I: Interner> TypeFolder<I> for RegionFolder<'a, I> {
|
||||||
|
fn cx(&self) -> I {
|
||||||
|
self.cx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T: TypeFoldable<I>>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> {
|
||||||
|
self.current_index.shift_in(1);
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.current_index.shift_out(1);
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(self), level = "debug", ret)]
|
||||||
|
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||||
|
match r.kind() {
|
||||||
|
ty::ReBound(debruijn, _) if debruijn < self.current_index => {
|
||||||
|
debug!(?self.current_index, "skipped bound region");
|
||||||
|
r
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
debug!(?self.current_index, "folding free region");
|
||||||
|
(self.fold_region_fn)(r, self.current_index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, Region, Ty};
|
use rustc_middle::ty::{self, Region, Ty};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::symbol::{Symbol, kw};
|
use rustc_span::symbol::{Symbol, kw};
|
||||||
|
@ -182,7 +183,7 @@ fn clean_param_env<'tcx>(
|
||||||
.is_some_and(|pred| tcx.lang_items().sized_trait() == Some(pred.def_id()))
|
.is_some_and(|pred| tcx.lang_items().sized_trait() == Some(pred.def_id()))
|
||||||
})
|
})
|
||||||
.map(|pred| {
|
.map(|pred| {
|
||||||
tcx.fold_regions(pred, |r, _| match *r {
|
fold_regions(tcx, pred, |r, _| match *r {
|
||||||
// FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that
|
// FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that
|
||||||
// we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds
|
// we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds
|
||||||
// of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests.
|
// of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue