Skip to content

Commit 1436fa9

Browse files
committed
optimize bound vars replacement :3
1 parent c3fce8e commit 1436fa9

File tree

2 files changed

+24
-20
lines changed

2 files changed

+24
-20
lines changed

compiler/rustc_infer/src/infer/canonical/substitute.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ where
7171
if var_values.var_values.is_empty() {
7272
value
7373
} else {
74-
let mut delegate = FnMutDelegate {
74+
let delegate = FnMutDelegate {
7575
regions: |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
7676
GenericArgKind::Lifetime(l) => l,
7777
r => bug!("{:?} is a region but value is {:?}", br, r),
@@ -86,6 +86,6 @@ where
8686
},
8787
};
8888

89-
tcx.replace_escaping_bound_vars_uncached(value, &mut delegate)
89+
tcx.replace_escaping_bound_vars_uncached(value, delegate)
9090
}
9191
}

compiler/rustc_middle/src/ty/fold.rs

+22-18
Original file line numberDiff line numberDiff line change
@@ -400,23 +400,26 @@ where
400400
}
401401

402402
/// Replaces the escaping bound vars (late bound regions or bound types) in a type.
403-
struct BoundVarReplacer<'a, 'tcx> {
403+
struct BoundVarReplacer<'tcx, D> {
404404
tcx: TyCtxt<'tcx>,
405405

406406
/// As with `RegionFolder`, represents the index of a binder *just outside*
407407
/// the ones we have visited.
408408
current_index: ty::DebruijnIndex,
409409

410-
delegate: &'a mut dyn BoundVarReplacerDelegate<'tcx>,
410+
delegate: D,
411411
}
412412

413-
impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
414-
fn new(tcx: TyCtxt<'tcx>, delegate: &'a mut dyn BoundVarReplacerDelegate<'tcx>) -> Self {
413+
impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> {
414+
fn new(tcx: TyCtxt<'tcx>, delegate: D) -> Self {
415415
BoundVarReplacer { tcx, current_index: ty::INNERMOST, delegate }
416416
}
417417
}
418418

419-
impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
419+
impl<'tcx, D> TypeFolder<'tcx> for BoundVarReplacer<'tcx, D>
420+
where
421+
D: BoundVarReplacerDelegate<'tcx>,
422+
{
420423
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
421424
self.tcx
422425
}
@@ -452,7 +455,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
452455
// debruijn index. Then we adjust it to the
453456
// correct depth.
454457
assert_eq!(debruijn1, ty::INNERMOST);
455-
self.tcx.mk_region(ty::ReLateBound(debruijn, br))
458+
self.tcx.reuse_or_mk_region(region, ty::ReLateBound(debruijn, br))
456459
} else {
457460
region
458461
}
@@ -518,12 +521,12 @@ impl<'tcx> TyCtxt<'tcx> {
518521
if !value.has_escaping_bound_vars() {
519522
value
520523
} else {
521-
let mut delegate = FnMutDelegate {
524+
let delegate = FnMutDelegate {
522525
regions: replace_regions,
523526
types: |b| bug!("unexpected bound ty in binder: {b:?}"),
524527
consts: |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
525528
};
526-
let mut replacer = BoundVarReplacer::new(self, &mut delegate);
529+
let mut replacer = BoundVarReplacer::new(self, delegate);
527530
value.fold_with(&mut replacer)
528531
}
529532
}
@@ -534,7 +537,7 @@ impl<'tcx> TyCtxt<'tcx> {
534537
pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<'tcx>>(
535538
self,
536539
value: T,
537-
delegate: &mut impl BoundVarReplacerDelegate<'tcx>,
540+
delegate: impl BoundVarReplacerDelegate<'tcx>,
538541
) -> T {
539542
if !value.has_escaping_bound_vars() {
540543
value
@@ -550,9 +553,9 @@ impl<'tcx> TyCtxt<'tcx> {
550553
pub fn replace_bound_vars_uncached<T: TypeFoldable<'tcx>>(
551554
self,
552555
value: Binder<'tcx, T>,
553-
mut delegate: impl BoundVarReplacerDelegate<'tcx>,
556+
delegate: impl BoundVarReplacerDelegate<'tcx>,
554557
) -> T {
555-
self.replace_escaping_bound_vars_uncached(value.skip_binder(), &mut delegate)
558+
self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate)
556559
}
557560

558561
/// Replaces any late-bound regions bound in `value` with
@@ -580,7 +583,7 @@ impl<'tcx> TyCtxt<'tcx> {
580583
let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
581584
self.replace_escaping_bound_vars_uncached(
582585
value,
583-
&mut FnMutDelegate {
586+
FnMutDelegate {
584587
regions: |r: ty::BoundRegion| {
585588
self.mk_region(ty::ReLateBound(
586589
ty::INNERMOST,
@@ -647,11 +650,11 @@ impl<'tcx> TyCtxt<'tcx> {
647650
where
648651
T: TypeFoldable<'tcx>,
649652
{
650-
struct Anonymize<'tcx> {
653+
struct Anonymize<'a, 'tcx> {
651654
tcx: TyCtxt<'tcx>,
652-
map: FxIndexMap<ty::BoundVar, ty::BoundVariableKind>,
655+
map: &'a mut FxIndexMap<ty::BoundVar, ty::BoundVariableKind>,
653656
}
654-
impl<'tcx> BoundVarReplacerDelegate<'tcx> for Anonymize<'tcx> {
657+
impl<'tcx> BoundVarReplacerDelegate<'tcx> for Anonymize<'_, 'tcx> {
655658
fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx> {
656659
let entry = self.map.entry(br.var);
657660
let index = entry.index();
@@ -680,9 +683,10 @@ impl<'tcx> TyCtxt<'tcx> {
680683
}
681684
}
682685

683-
let mut delegate = Anonymize { tcx: self, map: Default::default() };
684-
let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), &mut delegate);
685-
let bound_vars = self.mk_bound_variable_kinds(delegate.map.into_values());
686+
let mut map = Default::default();
687+
let delegate = Anonymize { tcx: self, map: &mut map };
688+
let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
689+
let bound_vars = self.mk_bound_variable_kinds(map.into_values());
686690
Binder::bind_with_vars(inner, bound_vars)
687691
}
688692
}

0 commit comments

Comments
 (0)