optimize bound vars replacement :3
This commit is contained in:
parent
c3fce8e937
commit
1436fa9e90
2 changed files with 24 additions and 20 deletions
|
@ -71,7 +71,7 @@ where
|
||||||
if var_values.var_values.is_empty() {
|
if var_values.var_values.is_empty() {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
let mut delegate = FnMutDelegate {
|
let delegate = FnMutDelegate {
|
||||||
regions: |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
|
regions: |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
|
||||||
GenericArgKind::Lifetime(l) => l,
|
GenericArgKind::Lifetime(l) => l,
|
||||||
r => bug!("{:?} is a region but value is {:?}", br, r),
|
r => bug!("{:?} is a region but value is {:?}", br, r),
|
||||||
|
@ -86,6 +86,6 @@ where
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
tcx.replace_escaping_bound_vars_uncached(value, &mut delegate)
|
tcx.replace_escaping_bound_vars_uncached(value, delegate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,23 +400,26 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces the escaping bound vars (late bound regions or bound types) in a type.
|
/// 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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
||||||
/// As with `RegionFolder`, represents the index of a binder *just outside*
|
/// As with `RegionFolder`, represents the index of a binder *just outside*
|
||||||
/// the ones we have visited.
|
/// the ones we have visited.
|
||||||
current_index: ty::DebruijnIndex,
|
current_index: ty::DebruijnIndex,
|
||||||
|
|
||||||
delegate: &'a mut dyn BoundVarReplacerDelegate<'tcx>,
|
delegate: D,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
|
impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> {
|
||||||
fn new(tcx: TyCtxt<'tcx>, delegate: &'a mut dyn BoundVarReplacerDelegate<'tcx>) -> Self {
|
fn new(tcx: TyCtxt<'tcx>, delegate: D) -> Self {
|
||||||
BoundVarReplacer { tcx, current_index: ty::INNERMOST, delegate }
|
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> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
@ -452,7 +455,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||||
// debruijn index. Then we adjust it to the
|
// debruijn index. Then we adjust it to the
|
||||||
// correct depth.
|
// correct depth.
|
||||||
assert_eq!(debruijn1, ty::INNERMOST);
|
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 {
|
} else {
|
||||||
region
|
region
|
||||||
}
|
}
|
||||||
|
@ -518,12 +521,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
if !value.has_escaping_bound_vars() {
|
if !value.has_escaping_bound_vars() {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
let mut delegate = FnMutDelegate {
|
let delegate = FnMutDelegate {
|
||||||
regions: replace_regions,
|
regions: replace_regions,
|
||||||
types: |b| bug!("unexpected bound ty in binder: {b:?}"),
|
types: |b| bug!("unexpected bound ty in binder: {b:?}"),
|
||||||
consts: |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
|
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)
|
value.fold_with(&mut replacer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,7 +537,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<'tcx>>(
|
pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<'tcx>>(
|
||||||
self,
|
self,
|
||||||
value: T,
|
value: T,
|
||||||
delegate: &mut impl BoundVarReplacerDelegate<'tcx>,
|
delegate: impl BoundVarReplacerDelegate<'tcx>,
|
||||||
) -> T {
|
) -> T {
|
||||||
if !value.has_escaping_bound_vars() {
|
if !value.has_escaping_bound_vars() {
|
||||||
value
|
value
|
||||||
|
@ -550,9 +553,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn replace_bound_vars_uncached<T: TypeFoldable<'tcx>>(
|
pub fn replace_bound_vars_uncached<T: TypeFoldable<'tcx>>(
|
||||||
self,
|
self,
|
||||||
value: Binder<'tcx, T>,
|
value: Binder<'tcx, T>,
|
||||||
mut delegate: impl BoundVarReplacerDelegate<'tcx>,
|
delegate: impl BoundVarReplacerDelegate<'tcx>,
|
||||||
) -> T {
|
) -> 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
|
/// Replaces any late-bound regions bound in `value` with
|
||||||
|
@ -580,7 +583,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
|
let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
|
||||||
self.replace_escaping_bound_vars_uncached(
|
self.replace_escaping_bound_vars_uncached(
|
||||||
value,
|
value,
|
||||||
&mut FnMutDelegate {
|
FnMutDelegate {
|
||||||
regions: |r: ty::BoundRegion| {
|
regions: |r: ty::BoundRegion| {
|
||||||
self.mk_region(ty::ReLateBound(
|
self.mk_region(ty::ReLateBound(
|
||||||
ty::INNERMOST,
|
ty::INNERMOST,
|
||||||
|
@ -647,11 +650,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
struct Anonymize<'tcx> {
|
struct Anonymize<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'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> {
|
fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx> {
|
||||||
let entry = self.map.entry(br.var);
|
let entry = self.map.entry(br.var);
|
||||||
let index = entry.index();
|
let index = entry.index();
|
||||||
|
@ -680,9 +683,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut delegate = Anonymize { tcx: self, map: Default::default() };
|
let mut map = Default::default();
|
||||||
let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), &mut delegate);
|
let delegate = Anonymize { tcx: self, map: &mut map };
|
||||||
let bound_vars = self.mk_bound_variable_kinds(delegate.map.into_values());
|
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)
|
Binder::bind_with_vars(inner, bound_vars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue