@@ -67,18 +67,18 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
67
67
/// bound by `binder` or bound by some binder outside of `binder`.
68
68
/// If `binder` is `ty::INNERMOST`, this indicates whether
69
69
/// there are any late-bound regions that appear free.
70
- fn has_regions_bound_at_or_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
71
- self . visit_with ( & mut HasEscapingRegionsVisitor { outer_index : binder } )
70
+ fn has_vars_bound_at_or_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
71
+ self . visit_with ( & mut HasEscapingVarsVisitor { outer_index : binder } )
72
72
}
73
73
74
74
/// True if this `self` has any regions that escape `binder` (and
75
75
/// hence are not bound by it).
76
- fn has_regions_bound_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
77
- self . has_regions_bound_at_or_above ( binder. shifted_in ( 1 ) )
76
+ fn has_vars_bound_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
77
+ self . has_vars_bound_at_or_above ( binder. shifted_in ( 1 ) )
78
78
}
79
79
80
- fn has_escaping_regions ( & self ) -> bool {
81
- self . has_regions_bound_at_or_above ( ty:: INNERMOST )
80
+ fn has_escaping_bound_vars ( & self ) -> bool {
81
+ self . has_vars_bound_at_or_above ( ty:: INNERMOST )
82
82
}
83
83
84
84
fn has_type_flags ( & self , flags : TypeFlags ) -> bool {
@@ -574,7 +574,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
574
574
}
575
575
576
576
fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
577
- if !t. has_regions_bound_at_or_above ( self . current_index ) {
577
+ if !t. has_vars_bound_at_or_above ( self . current_index ) {
578
578
return t;
579
579
}
580
580
@@ -603,55 +603,99 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
603
603
}
604
604
605
605
///////////////////////////////////////////////////////////////////////////
606
- // Region shifter
606
+ // Shifter
607
607
//
608
- // Shifts the De Bruijn indices on all escaping bound regions by a
608
+ // Shifts the De Bruijn indices on all escaping bound vars by a
609
609
// fixed amount. Useful in substitution or when otherwise introducing
610
610
// a binding level that is not intended to capture the existing bound
611
- // regions . See comment on `shift_regions_through_binders ` method in
611
+ // vars . See comment on `shift_vars_through_binders ` method in
612
612
// `subst.rs` for more details.
613
613
614
- pub fn shift_region ( region : ty:: RegionKind , amount : u32 ) -> ty:: RegionKind {
615
- match region {
616
- ty:: ReLateBound ( debruijn, br) => {
617
- ty:: ReLateBound ( debruijn. shifted_in ( amount) , br)
614
+ struct Shifter < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
615
+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
616
+
617
+ current_index : ty:: DebruijnIndex ,
618
+ amount : u32 ,
619
+ }
620
+
621
+ impl Shifter < ' a , ' gcx , ' tcx > {
622
+ pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , amount : u32 ) -> Self {
623
+ Shifter {
624
+ tcx,
625
+ current_index : ty:: INNERMOST ,
626
+ amount,
618
627
}
619
- _ => {
620
- region
628
+ }
629
+ }
630
+
631
+ impl < ' a , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for Shifter < ' a , ' gcx , ' tcx > {
632
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' tcx > { self . tcx }
633
+
634
+ fn fold_binder < T : TypeFoldable < ' tcx > > ( & mut self , t : & ty:: Binder < T > ) -> ty:: Binder < T > {
635
+ self . current_index . shift_in ( 1 ) ;
636
+ let t = t. super_fold_with ( self ) ;
637
+ self . current_index . shift_out ( 1 ) ;
638
+ t
639
+ }
640
+
641
+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
642
+ match * r {
643
+ ty:: ReLateBound ( debruijn, br) => {
644
+ if self . amount == 0 || debruijn < self . current_index {
645
+ r
646
+ } else {
647
+ let shifted = ty:: ReLateBound ( debruijn. shifted_in ( self . amount ) , br) ;
648
+ self . tcx . mk_region ( shifted)
649
+ }
650
+ }
651
+ _ => r
652
+ }
653
+ }
654
+
655
+ fn fold_ty ( & mut self , ty : ty:: Ty < ' tcx > ) -> ty:: Ty < ' tcx > {
656
+ match ty. sty {
657
+ ty:: Bound ( bound_ty) => {
658
+ if self . amount == 0 || bound_ty. level < self . current_index {
659
+ ty
660
+ } else {
661
+ let shifted = ty:: BoundTy {
662
+ level : bound_ty. level . shifted_in ( self . amount ) ,
663
+ var : bound_ty. var ,
664
+ kind : bound_ty. kind ,
665
+ } ;
666
+ self . tcx . mk_ty ( ty:: Bound ( shifted) )
667
+ }
668
+ }
669
+
670
+ _ => ty. super_fold_with ( self ) ,
621
671
}
622
672
}
623
673
}
624
674
625
- pub fn shift_region_ref < ' a , ' gcx , ' tcx > (
626
- tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
627
- region : ty:: Region < ' tcx > ,
628
- amount : u32 )
629
- -> ty:: Region < ' tcx >
630
- {
675
+ pub fn shift_region ( region : ty:: RegionKind , amount : u32 ) -> ty:: RegionKind {
631
676
match region {
632
- & ty:: ReLateBound ( debruijn, br) if amount > 0 => {
633
- tcx . mk_region ( ty:: ReLateBound ( debruijn. shifted_in ( amount) , br) )
677
+ ty:: ReLateBound ( debruijn, br) => {
678
+ ty:: ReLateBound ( debruijn. shifted_in ( amount) , br)
634
679
}
635
680
_ => {
636
681
region
637
682
}
638
683
}
639
684
}
640
685
641
- pub fn shift_regions < ' a , ' gcx , ' tcx , T > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
642
- amount : u32 ,
643
- value : & T ) -> T
644
- where T : TypeFoldable < ' tcx >
645
- {
646
- debug ! ( "shift_regions (value={:?}, amount={})" ,
686
+ pub fn shift_vars < ' a , ' gcx , ' tcx , T > (
687
+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
688
+ amount : u32 ,
689
+ value : & T
690
+ ) -> T where T : TypeFoldable < ' tcx > {
691
+ debug ! ( "shift_vars (value={:?}, amount={})" ,
647
692
value, amount) ;
648
693
649
- value. fold_with ( & mut RegionFolder :: new ( tcx, & mut false , & mut |region, _current_depth| {
650
- shift_region_ref ( tcx, region, amount)
651
- } ) )
694
+ value. fold_with ( & mut Shifter :: new ( tcx, amount) )
652
695
}
653
696
654
- /// An "escaping region" is a bound region whose binder is not part of `t`.
697
+ /// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
698
+ /// bound region or a bound type.
655
699
///
656
700
/// So, for example, consider a type like the following, which has two binders:
657
701
///
@@ -663,24 +707,24 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
663
707
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
664
708
/// fn type*, that type has an escaping region: `'a`.
665
709
///
666
- /// Note that what I'm calling an "escaping region " is often just called a "free region ". However,
667
- /// we already use the term "free region ". It refers to the regions that we use to represent bound
668
- /// regions on a fn definition while we are typechecking its body.
710
+ /// Note that what I'm calling an "escaping var " is often just called a "free var ". However,
711
+ /// we already use the term "free var ". It refers to the regions or types that we use to represent
712
+ /// bound regions or type params on a fn definition while we are typechecking its body.
669
713
///
670
714
/// To clarify, conceptually there is no particular difference between
671
- /// an "escaping" region and a "free" region . However, there is a big
715
+ /// an "escaping" var and a "free" var . However, there is a big
672
716
/// difference in practice. Basically, when "entering" a binding
673
717
/// level, one is generally required to do some sort of processing to
674
- /// a bound region , such as replacing it with a fresh/placeholder
675
- /// region , or making an entry in the environment to represent the
676
- /// scope to which it is attached, etc. An escaping region represents
677
- /// a bound region for which this processing has not yet been done.
678
- struct HasEscapingRegionsVisitor {
718
+ /// a bound var , such as replacing it with a fresh/placeholder
719
+ /// var , or making an entry in the environment to represent the
720
+ /// scope to which it is attached, etc. An escaping var represents
721
+ /// a bound var for which this processing has not yet been done.
722
+ struct HasEscapingVarsVisitor {
679
723
/// Anything bound by `outer_index` or "above" is escaping
680
724
outer_index : ty:: DebruijnIndex ,
681
725
}
682
726
683
- impl < ' tcx > TypeVisitor < ' tcx > for HasEscapingRegionsVisitor {
727
+ impl < ' tcx > TypeVisitor < ' tcx > for HasEscapingVarsVisitor {
684
728
fn visit_binder < T : TypeFoldable < ' tcx > > ( & mut self , t : & Binder < T > ) -> bool {
685
729
self . outer_index . shift_in ( 1 ) ;
686
730
let result = t. super_visit_with ( self ) ;
@@ -693,7 +737,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
693
737
// `outer_index`, that means that `t` contains some content
694
738
// bound at `outer_index` or above (because
695
739
// `outer_exclusive_binder` is always 1 higher than the
696
- // content in `t`). Therefore, `t` has some escaping regions .
740
+ // content in `t`). Therefore, `t` has some escaping vars .
697
741
t. outer_exclusive_binder > self . outer_index
698
742
}
699
743
0 commit comments