Uplift EarlyBinder · rust-lang/rust@993553c
@@ -3,7 +3,9 @@ use rustc_data_structures::fx::FxIndexMap;
33use rustc_hir::def_id::DefId;
44use tracing::{debug, instrument};
556-pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
6+pub use rustc_type_ir::fold::{
7+ shift_region, shift_vars, FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable,
8+};
79810///////////////////////////////////////////////////////////////////////////
911// Some sample folders
@@ -412,103 +414,3 @@ impl<'tcx> TyCtxt<'tcx> {
412414Binder::bind_with_vars(inner, bound_vars)
413415}
414416}
415-416-///////////////////////////////////////////////////////////////////////////
417-// Shifter
418-//
419-// Shifts the De Bruijn indices on all escaping bound vars by a
420-// fixed amount. Useful in instantiation or when otherwise introducing
421-// a binding level that is not intended to capture the existing bound
422-// vars. See comment on `shift_vars_through_binders` method in
423-// `rustc_middle/src/ty/generic_args.rs` for more details.
424-425-struct Shifter<'tcx> {
426-tcx: TyCtxt<'tcx>,
427-current_index: ty::DebruijnIndex,
428-amount: u32,
429-}
430-431-impl<'tcx> Shifter<'tcx> {
432-pub fn new(tcx: TyCtxt<'tcx>, amount: u32) -> Self {
433-Shifter { tcx, current_index: ty::INNERMOST, amount }
434-}
435-}
436-437-impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
438-fn interner(&self) -> TyCtxt<'tcx> {
439-self.tcx
440-}
441-442-fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
443-&mut self,
444-t: ty::Binder<'tcx, T>,
445-) -> ty::Binder<'tcx, T> {
446-self.current_index.shift_in(1);
447-let t = t.super_fold_with(self);
448-self.current_index.shift_out(1);
449- t
450-}
451-452-fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
453-match *r {
454- ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
455-let debruijn = debruijn.shifted_in(self.amount);
456- ty::Region::new_bound(self.tcx, debruijn, br)
457-}
458- _ => r,
459-}
460-}
461-462-fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
463-match *ty.kind() {
464- ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
465-let debruijn = debruijn.shifted_in(self.amount);
466-Ty::new_bound(self.tcx, debruijn, bound_ty)
467-}
468-469- _ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self),
470- _ => ty,
471-}
472-}
473-474-fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
475-if let ty::ConstKind::Bound(debruijn, bound_ct) = ct.kind()
476-&& debruijn >= self.current_index
477-{
478-let debruijn = debruijn.shifted_in(self.amount);
479- ty::Const::new_bound(self.tcx, debruijn, bound_ct, ct.ty())
480-} else {
481- ct.super_fold_with(self)
482-}
483-}
484-485-fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
486-if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
487-}
488-}
489-490-pub fn shift_region<'tcx>(
491-tcx: TyCtxt<'tcx>,
492-region: ty::Region<'tcx>,
493-amount: u32,
494-) -> ty::Region<'tcx> {
495-match *region {
496- ty::ReBound(debruijn, br) if amount > 0 => {
497- ty::Region::new_bound(tcx, debruijn.shifted_in(amount), br)
498-}
499- _ => region,
500-}
501-}
502-503-pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T
504-where
505-T: TypeFoldable<TyCtxt<'tcx>>,
506-{
507-debug!("shift_vars(value={:?}, amount={})", value, amount);
508-509-if amount == 0 || !value.has_escaping_bound_vars() {
510-return value;
511-}
512-513- value.fold_with(&mut Shifter::new(tcx, amount))
514-}