diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 6d3f51a7249b..5ccf735f1d2a 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -753,19 +753,29 @@ pub fn replace_late_bound_regions( T: TypeFoldable<'tcx>, { let mut region_map = BTreeMap::new(); - let mut real_fld_r = - |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); + let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); + let value = self.replace_late_bound_regions_uncached(value, real_fld_r); + (value, region_map) + } + + pub fn replace_late_bound_regions_uncached( + self, + value: Binder<'tcx, T>, + mut fld_r: F, + ) -> T + where + F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, + T: TypeFoldable<'tcx>, + { let mut fld_t = |b| bug!("unexpected bound ty in binder: {b:?}"); let mut fld_c = |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"); - let value = value.skip_binder(); - let value = if !value.has_escaping_bound_vars() { + if !value.has_escaping_bound_vars() { value } else { - let mut replacer = BoundVarReplacer::new(self, &mut real_fld_r, &mut fld_t, &mut fld_c); + let mut replacer = BoundVarReplacer::new(self, &mut fld_r, &mut fld_t, &mut fld_c); value.fold_with(&mut replacer) - }; - (value, region_map) + } } /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping @@ -821,13 +831,12 @@ pub fn liberate_late_bound_regions( where T: TypeFoldable<'tcx>, { - self.replace_late_bound_regions(value, |br| { + self.replace_late_bound_regions_uncached(value, |br| { self.mk_region(ty::ReFree(ty::FreeRegion { scope: all_outlive_scope, bound_region: br.kind, })) }) - .0 } pub fn shift_bound_var_indices(self, bound_vars: usize, value: T) -> T diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 838980e08aa0..de40126e724d 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -449,8 +449,9 @@ fn projected_ty_from_poly_trait_ref( format!( "{}::", // Replace the existing lifetimes with a new named lifetime. - self.tcx - .replace_late_bound_regions(poly_trait_ref, |_| { + self.tcx.replace_late_bound_regions_uncached( + poly_trait_ref, + |_| { self.tcx.mk_region(ty::ReEarlyBound( ty::EarlyBoundRegion { def_id: item_def_id, @@ -458,8 +459,8 @@ fn projected_ty_from_poly_trait_ref( name: Symbol::intern(<_name), }, )) - }) - .0, + } + ), ), ), ];