@@ -67,18 +67,18 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
6767 /// bound by `binder` or bound by some binder outside of `binder`.
6868 /// If `binder` is `ty::INNERMOST`, this indicates whether
6969 /// 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 } )
7272 }
7373
7474 /// True if this `self` has any regions that escape `binder` (and
7575 /// 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 ) )
7878 }
7979
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 )
8282 }
8383
8484 fn has_type_flags ( & self , flags : TypeFlags ) -> bool {
@@ -574,7 +574,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
574574 }
575575
576576 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 ) {
578578 return t;
579579 }
580580
@@ -603,55 +603,99 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
603603}
604604
605605///////////////////////////////////////////////////////////////////////////
606- // Region shifter
606+ // Shifter
607607//
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
609609// fixed amount. Useful in substitution or when otherwise introducing
610610// 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
612612// `subst.rs` for more details.
613613
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,
618627 }
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 ) ,
621671 }
622672 }
623673}
624674
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 {
631676 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)
634679 }
635680 _ => {
636681 region
637682 }
638683 }
639684}
640685
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={})" ,
647692 value, amount) ;
648693
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) )
652695}
653696
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.
655699///
656700/// So, for example, consider a type like the following, which has two binders:
657701///
@@ -663,24 +707,24 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
663707/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
664708/// fn type*, that type has an escaping region: `'a`.
665709///
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.
669713///
670714/// 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
672716/// difference in practice. Basically, when "entering" a binding
673717/// 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 {
679723 /// Anything bound by `outer_index` or "above" is escaping
680724 outer_index : ty:: DebruijnIndex ,
681725}
682726
683- impl < ' tcx > TypeVisitor < ' tcx > for HasEscapingRegionsVisitor {
727+ impl < ' tcx > TypeVisitor < ' tcx > for HasEscapingVarsVisitor {
684728 fn visit_binder < T : TypeFoldable < ' tcx > > ( & mut self , t : & Binder < T > ) -> bool {
685729 self . outer_index . shift_in ( 1 ) ;
686730 let result = t. super_visit_with ( self ) ;
@@ -693,7 +737,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
693737 // `outer_index`, that means that `t` contains some content
694738 // bound at `outer_index` or above (because
695739 // `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 .
697741 t. outer_exclusive_binder > self . outer_index
698742 }
699743
0 commit comments