1
Fork 0

uplift fold_regions to rustc_type_ir

This commit is contained in:
lcnr 2024-11-27 18:37:39 +01:00
parent f005c7437d
commit 9fe7750bcd
24 changed files with 129 additions and 115 deletions

View file

@ -17,6 +17,7 @@ use smallvec::SmallVec;
use super::{ConstValue, SourceInfo};
use crate::mir;
use crate::ty::fold::fold_regions;
use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt};
rustc_index::newtype_index! {
@ -315,7 +316,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
/// All regions of `ty` must be of kind `ReVar` and must represent
/// universal regions *external* to the closure.
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) => {
let br = ty::BoundRegion {
var: ty::BoundVar::new(vid.index()),
@ -334,7 +335,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
tcx: TyCtxt<'tcx>,
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'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) => {
debug_assert_eq!(debruijn, depth);
map(ty::RegionVid::new(br.var.index()))

View file

@ -2,9 +2,9 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::DefId;
use rustc_type_ir::data_structures::DelayedMap;
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};
@ -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

View file

@ -21,6 +21,7 @@ use tracing::{debug, instrument};
use super::TypingEnv;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::query::Providers;
use crate::ty::fold::fold_regions;
use crate::ty::layout::{FloatExt, IntegerExt};
use crate::ty::{
self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
@ -735,7 +736,7 @@ impl<'tcx> TyCtxt<'tcx> {
.filter(|decl| !decl.ignore_for_traits)
.map(move |decl| {
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);
let var = ty::BoundVar::from_usize(vars.len());
vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));