@@ -959,24 +959,58 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
959
959
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
960
960
pub struct Binder < T > ( T , u32 ) ;
961
961
962
- impl < T > Binder < T > {
962
+ impl < ' tcx , T > Binder < T >
963
+ where
964
+ T : TypeFoldable < ' tcx > ,
965
+ {
963
966
/// Wraps `value` in a binder, asserting that `value` does not
964
967
/// contain any bound vars that would be bound by the
965
968
/// binder. This is commonly used to 'inject' a value T into a
966
969
/// 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 > {
971
971
debug_assert ! ( !value. has_escaping_bound_vars( ) ) ;
972
972
Binder ( value, 0 )
973
973
}
974
974
975
975
/// Wraps `value` in a binder, binding higher-ranked vars (if any).
976
976
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 )
978
1010
}
1011
+ }
979
1012
1013
+ impl < T > Binder < T > {
980
1014
/// Skips the binder and returns the "bound" value. This is a
981
1015
/// risky thing to do because it's easy to get confused about
982
1016
/// De Bruijn indices and the like. It is usually better to
@@ -997,6 +1031,10 @@ impl<T> Binder<T> {
997
1031
self . 0
998
1032
}
999
1033
1034
+ pub fn bound_vars ( & self ) -> u32 {
1035
+ self . 1
1036
+ }
1037
+
1000
1038
pub fn as_ref ( & self ) -> Binder < & T > {
1001
1039
Binder ( & self . 0 , self . 1 )
1002
1040
}
0 commit comments