Skip to content

Commit

Permalink
Uplift EarlyBinder
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed May 27, 2024
1 parent bbcdb4f commit 993553c
Show file tree
Hide file tree
Showing 13 changed files with 679 additions and 613 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4686,6 +4686,7 @@ dependencies = [
"rustc_span",
"rustc_type_ir_macros",
"smallvec",
"tracing",
]

[[package]]
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
Const::new_var(tcx, vid, ty)
}

fn new_bound(
interner: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
var: ty::BoundVar,
ty: Ty<'tcx>,
) -> Self {
Const::new_bound(interner, debruijn, var, ty)
}

fn new_anon_bound(
tcx: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
Expand Down
104 changes: 3 additions & 101 deletions compiler/rustc_middle/src/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::DefId;
use tracing::{debug, instrument};

pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
pub use rustc_type_ir::fold::{
shift_region, shift_vars, FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable,
};

///////////////////////////////////////////////////////////////////////////
// Some sample folders
Expand Down Expand Up @@ -412,103 +414,3 @@ impl<'tcx> TyCtxt<'tcx> {
Binder::bind_with_vars(inner, bound_vars)
}
}

///////////////////////////////////////////////////////////////////////////
// Shifter
//
// Shifts the De Bruijn indices on all escaping bound vars by a
// fixed amount. Useful in instantiation or when otherwise introducing
// a binding level that is not intended to capture the existing bound
// vars. See comment on `shift_vars_through_binders` method in
// `rustc_middle/src/ty/generic_args.rs` for more details.

struct Shifter<'tcx> {
tcx: TyCtxt<'tcx>,
current_index: ty::DebruijnIndex,
amount: u32,
}

impl<'tcx> Shifter<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, amount: u32) -> Self {
Shifter { tcx, current_index: ty::INNERMOST, amount }
}
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
fn interner(&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
}

fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
let debruijn = debruijn.shifted_in(self.amount);
ty::Region::new_bound(self.tcx, debruijn, br)
}
_ => r,
}
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match *ty.kind() {
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
let debruijn = debruijn.shifted_in(self.amount);
Ty::new_bound(self.tcx, debruijn, bound_ty)
}

_ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self),
_ => ty,
}
}

fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.kind()
&& debruijn >= self.current_index
{
let debruijn = debruijn.shifted_in(self.amount);
ty::Const::new_bound(self.tcx, debruijn, bound_ct, ct.ty())
} else {
ct.super_fold_with(self)
}
}

fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
}
}

pub fn shift_region<'tcx>(
tcx: TyCtxt<'tcx>,
region: ty::Region<'tcx>,
amount: u32,
) -> ty::Region<'tcx> {
match *region {
ty::ReBound(debruijn, br) if amount > 0 => {
ty::Region::new_bound(tcx, debruijn.shifted_in(amount), br)
}
_ => region,
}
}

pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
debug!("shift_vars(value={:?}, amount={})", value, amount);

if amount == 0 || !value.has_escaping_bound_vars() {
return value;
}

value.fold_with(&mut Shifter::new(tcx, amount))
}
Loading

0 comments on commit 993553c

Please sign in to comment.