}
/// Replaces the escaping bound vars (late bound regions or bound types) in a type.
-struct BoundVarReplacer<'a, 'tcx> {
+struct BoundVarReplacer<'tcx, D> {
tcx: TyCtxt<'tcx>,
/// As with `RegionFolder`, represents the index of a binder *just outside*
/// the ones we have visited.
current_index: ty::DebruijnIndex,
- delegate: &'a mut dyn BoundVarReplacerDelegate<'tcx>,
+ delegate: D,
}
-impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
- fn new(tcx: TyCtxt<'tcx>, delegate: &'a mut dyn BoundVarReplacerDelegate<'tcx>) -> Self {
+impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> {
+ fn new(tcx: TyCtxt<'tcx>, delegate: D) -> Self {
BoundVarReplacer { tcx, current_index: ty::INNERMOST, delegate }
}
}
-impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
+impl<'tcx, D> TypeFolder<'tcx> for BoundVarReplacer<'tcx, D>
+where
+ D: BoundVarReplacerDelegate<'tcx>,
+{
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx
}
// debruijn index. Then we adjust it to the
// correct depth.
assert_eq!(debruijn1, ty::INNERMOST);
- self.tcx.mk_region(ty::ReLateBound(debruijn, br))
+ self.tcx.reuse_or_mk_region(region, ty::ReLateBound(debruijn, br))
} else {
region
}
if !value.has_escaping_bound_vars() {
value
} else {
- let mut delegate = FnMutDelegate {
+ let delegate = FnMutDelegate {
regions: replace_regions,
types: |b| bug!("unexpected bound ty in binder: {b:?}"),
consts: |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
};
- let mut replacer = BoundVarReplacer::new(self, &mut delegate);
+ let mut replacer = BoundVarReplacer::new(self, delegate);
value.fold_with(&mut replacer)
}
}
pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<'tcx>>(
self,
value: T,
- delegate: &mut impl BoundVarReplacerDelegate<'tcx>,
+ delegate: impl BoundVarReplacerDelegate<'tcx>,
) -> T {
if !value.has_escaping_bound_vars() {
value
pub fn replace_bound_vars_uncached<T: TypeFoldable<'tcx>>(
self,
value: Binder<'tcx, T>,
- mut delegate: impl BoundVarReplacerDelegate<'tcx>,
+ delegate: impl BoundVarReplacerDelegate<'tcx>,
) -> T {
- self.replace_escaping_bound_vars_uncached(value.skip_binder(), &mut delegate)
+ self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate)
}
/// Replaces any late-bound regions bound in `value` with
let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
self.replace_escaping_bound_vars_uncached(
value,
- &mut FnMutDelegate {
+ FnMutDelegate {
regions: |r: ty::BoundRegion| {
self.mk_region(ty::ReLateBound(
ty::INNERMOST,
where
T: TypeFoldable<'tcx>,
{
- struct Anonymize<'tcx> {
+ struct Anonymize<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
- map: FxIndexMap<ty::BoundVar, ty::BoundVariableKind>,
+ map: &'a mut FxIndexMap<ty::BoundVar, ty::BoundVariableKind>,
}
- impl<'tcx> BoundVarReplacerDelegate<'tcx> for Anonymize<'tcx> {
+ impl<'tcx> BoundVarReplacerDelegate<'tcx> for Anonymize<'_, 'tcx> {
fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx> {
let entry = self.map.entry(br.var);
let index = entry.index();
}
}
- let mut delegate = Anonymize { tcx: self, map: Default::default() };
- let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), &mut delegate);
- let bound_vars = self.mk_bound_variable_kinds(delegate.map.into_values());
+ let mut map = Default::default();
+ let delegate = Anonymize { tcx: self, map: &mut map };
+ let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
+ let bound_vars = self.mk_bound_variable_kinds(map.into_values());
Binder::bind_with_vars(inner, bound_vars)
}
}