Skip to content

Commit 04ae501

Browse files
committed
Auto merge of #83090 - jackh726:bound_var_replacer_option, r=varkor
Make functions passed to BoundVarReplacer be optional This means we can reuse the bound vars when we don't care to change them
2 parents 0ce0fed + ba27cae commit 04ae501

File tree

1 file changed

+53
-55
lines changed
  • compiler/rustc_middle/src/ty

1 file changed

+53
-55
lines changed

compiler/rustc_middle/src/ty/fold.rs

+53-55
Original file line numberDiff line numberDiff line change
@@ -439,18 +439,18 @@ struct BoundVarReplacer<'a, 'tcx> {
439439
/// the ones we have visited.
440440
current_index: ty::DebruijnIndex,
441441

442-
fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
443-
fld_t: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
444-
fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a),
442+
fld_r: Option<&'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a)>,
443+
fld_t: Option<&'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a)>,
444+
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a)>,
445445
}
446446

447447
impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
448-
fn new<F, G, H>(tcx: TyCtxt<'tcx>, fld_r: &'a mut F, fld_t: &'a mut G, fld_c: &'a mut H) -> Self
449-
where
450-
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
451-
G: FnMut(ty::BoundTy) -> Ty<'tcx>,
452-
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
453-
{
448+
fn new(
449+
tcx: TyCtxt<'tcx>,
450+
fld_r: Option<&'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a)>,
451+
fld_t: Option<&'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a)>,
452+
fld_c: Option<&'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a)>,
453+
) -> Self {
454454
BoundVarReplacer { tcx, current_index: ty::INNERMOST, fld_r, fld_t, fld_c }
455455
}
456456
}
@@ -469,63 +469,58 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
469469

470470
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
471471
match *t.kind() {
472-
ty::Bound(debruijn, bound_ty) => {
473-
if debruijn == self.current_index {
474-
let fld_t = &mut self.fld_t;
472+
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
473+
if let Some(fld_t) = self.fld_t.as_mut() {
475474
let ty = fld_t(bound_ty);
476-
ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32())
477-
} else {
478-
t
475+
return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32());
479476
}
480477
}
481-
_ => {
482-
if !t.has_vars_bound_at_or_above(self.current_index) {
483-
// Nothing more to substitute.
484-
t
485-
} else {
486-
t.super_fold_with(self)
487-
}
478+
_ if t.has_vars_bound_at_or_above(self.current_index) => {
479+
return t.super_fold_with(self);
488480
}
481+
_ => {}
489482
}
483+
t
490484
}
491485

492486
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
493487
match *r {
494488
ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
495-
let fld_r = &mut self.fld_r;
496-
let region = fld_r(br);
497-
if let ty::ReLateBound(debruijn1, br) = *region {
498-
// If the callback returns a late-bound region,
499-
// that region should always use the INNERMOST
500-
// debruijn index. Then we adjust it to the
501-
// correct depth.
502-
assert_eq!(debruijn1, ty::INNERMOST);
503-
self.tcx.mk_region(ty::ReLateBound(debruijn, br))
504-
} else {
505-
region
489+
if let Some(fld_r) = self.fld_r.as_mut() {
490+
let region = fld_r(br);
491+
return if let ty::ReLateBound(debruijn1, br) = *region {
492+
// If the callback returns a late-bound region,
493+
// that region should always use the INNERMOST
494+
// debruijn index. Then we adjust it to the
495+
// correct depth.
496+
assert_eq!(debruijn1, ty::INNERMOST);
497+
self.tcx.mk_region(ty::ReLateBound(debruijn, br))
498+
} else {
499+
region
500+
};
506501
}
507502
}
508-
_ => r,
503+
_ => {}
509504
}
505+
r
510506
}
511507

512508
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
513-
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } = *ct {
514-
if debruijn == self.current_index {
515-
let fld_c = &mut self.fld_c;
516-
let ct = fld_c(bound_const, ty);
517-
ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())
518-
} else {
519-
ct
509+
match *ct {
510+
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
511+
if debruijn == self.current_index =>
512+
{
513+
if let Some(fld_c) = self.fld_c.as_mut() {
514+
let ct = fld_c(bound_const, ty);
515+
return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32());
516+
}
520517
}
521-
} else {
522-
if !ct.has_vars_bound_at_or_above(self.current_index) {
523-
// Nothing more to substitute.
524-
ct
525-
} else {
526-
ct.super_fold_with(self)
518+
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
519+
return ct.super_fold_with(self);
527520
}
521+
_ => {}
528522
}
523+
ct
529524
}
530525
}
531526

@@ -550,14 +545,16 @@ impl<'tcx> TyCtxt<'tcx> {
550545
F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
551546
T: TypeFoldable<'tcx>,
552547
{
553-
// identity for bound types and consts
554-
let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty));
555-
let fld_c = |bound_ct, ty| {
556-
self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty })
557-
};
558548
let mut region_map = BTreeMap::new();
559-
let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br));
560-
let value = self.replace_escaping_bound_vars(value.skip_binder(), real_fld_r, fld_t, fld_c);
549+
let mut real_fld_r =
550+
|br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br));
551+
let value = value.skip_binder();
552+
let value = if !value.has_escaping_bound_vars() {
553+
value
554+
} else {
555+
let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None);
556+
value.fold_with(&mut replacer)
557+
};
561558
(value, region_map)
562559
}
563560

@@ -580,7 +577,8 @@ impl<'tcx> TyCtxt<'tcx> {
580577
if !value.has_escaping_bound_vars() {
581578
value
582579
} else {
583-
let mut replacer = BoundVarReplacer::new(self, &mut fld_r, &mut fld_t, &mut fld_c);
580+
let mut replacer =
581+
BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c));
584582
value.fold_with(&mut replacer)
585583
}
586584
}

0 commit comments

Comments
 (0)