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
|
@ -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()))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue