Uplift EarlyBinder · rust-lang/rust@993553c

@@ -3,7 +3,9 @@ use rustc_data_structures::fx::FxIndexMap;

33

use rustc_hir::def_id::DefId;

44

use 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> {

412414

Binder::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-

}