@@ -959,24 +959,58 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
959959#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
960960pub struct Binder < T > ( T , u32 ) ;
961961
962- impl < T > Binder < T > {
962+ impl < ' tcx , T > Binder < T >
963+ where
964+ T : TypeFoldable < ' tcx > ,
965+ {
963966 /// Wraps `value` in a binder, asserting that `value` does not
964967 /// contain any bound vars that would be bound by the
965968 /// binder. This is commonly used to 'inject' a value T into a
966969 /// different binding level.
967- pub fn dummy < ' tcx > ( value : T ) -> Binder < T >
968- where
969- T : TypeFoldable < ' tcx > ,
970- {
970+ pub fn dummy ( value : T ) -> Binder < T > {
971971 debug_assert ! ( !value. has_escaping_bound_vars( ) ) ;
972972 Binder ( value, 0 )
973973 }
974974
975975 /// Wraps `value` in a binder, binding higher-ranked vars (if any).
976976 pub fn bind ( value : T ) -> Binder < T > {
977- Binder ( value, 0 )
977+ use crate :: ty:: fold:: CountBoundVars ;
978+ use rustc_data_structures:: fx:: FxHashSet ;
979+ let mut counter = CountBoundVars {
980+ outer_index : ty:: INNERMOST ,
981+ bound_tys : FxHashSet :: default ( ) ,
982+ bound_regions : FxHashSet :: default ( ) ,
983+ bound_consts : FxHashSet :: default ( ) ,
984+ } ;
985+ value. visit_with ( & mut counter) ;
986+ let bound_tys = counter. bound_tys . len ( ) ;
987+ let bound_regions = if !counter. bound_regions . is_empty ( ) {
988+ let mut env = false ;
989+ let mut anons = FxHashSet :: default ( ) ;
990+ let mut named = FxHashSet :: default ( ) ;
991+ for br in counter. bound_regions {
992+ match br. kind {
993+ ty:: BrAnon ( idx) => {
994+ anons. insert ( idx) ;
995+ }
996+ ty:: BrNamed ( def_id, _) => {
997+ named. insert ( def_id) ;
998+ }
999+ ty:: BrEnv => env = true ,
1000+ }
1001+ }
1002+ ( if env { 1 } else { 0 } ) + anons. len ( ) + named. len ( )
1003+ } else {
1004+ 0
1005+ } ;
1006+ let bound_consts = counter. bound_consts . len ( ) ;
1007+
1008+ let bound_vars = bound_tys + bound_regions + bound_consts;
1009+ Binder ( value, bound_vars as u32 )
9781010 }
1011+ }
9791012
1013+ impl < T > Binder < T > {
9801014 /// Skips the binder and returns the "bound" value. This is a
9811015 /// risky thing to do because it's easy to get confused about
9821016 /// De Bruijn indices and the like. It is usually better to
@@ -997,6 +1031,10 @@ impl<T> Binder<T> {
9971031 self . 0
9981032 }
9991033
1034+ pub fn bound_vars ( & self ) -> u32 {
1035+ self . 1
1036+ }
1037+
10001038 pub fn as_ref ( & self ) -> Binder < & T > {
10011039 Binder ( & self . 0 , self . 1 )
10021040 }
0 commit comments