@@ -7,8 +7,8 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
77use crate :: ty:: visit:: ValidateBoundVars ;
88use crate :: ty:: InferTy :: * ;
99use crate :: ty:: {
10- self , AdtDef , DefIdTree , Discr , Term , Ty , TyCtxt , TypeFlags , TypeSuperVisitable , TypeVisitable ,
11- TypeVisitor ,
10+ self , AdtDef , DefIdTree , Discr , FallibleTypeFolder , Term , Ty , TyCtxt , TypeFlags , TypeFoldable ,
11+ TypeSuperFoldable , TypeSuperVisitable , TypeVisitable , TypeVisitor ,
1212} ;
1313use crate :: ty:: { List , ParamEnv } ;
1414use hir:: def:: DefKind ;
@@ -1106,6 +1106,17 @@ impl<'tcx, T> Binder<'tcx, T> {
11061106 if self . 0 . has_escaping_bound_vars ( ) { None } else { Some ( self . skip_binder ( ) ) }
11071107 }
11081108
1109+ pub fn no_bound_vars_ignoring_escaping ( self , tcx : TyCtxt < ' tcx > ) -> Option < T >
1110+ where
1111+ T : TypeFoldable < ' tcx > ,
1112+ {
1113+ if !self . 0 . has_escaping_bound_vars ( ) {
1114+ Some ( self . skip_binder ( ) )
1115+ } else {
1116+ self . 0 . try_fold_with ( & mut SkipBindersAt { index : ty:: INNERMOST , tcx } ) . ok ( )
1117+ }
1118+ }
1119+
11091120 /// Splits the contents into two things that share the same binder
11101121 /// level as the original, returning two distinct binders.
11111122 ///
@@ -1135,6 +1146,81 @@ impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
11351146 }
11361147}
11371148
1149+ struct SkipBindersAt < ' tcx > {
1150+ tcx : TyCtxt < ' tcx > ,
1151+ index : ty:: DebruijnIndex ,
1152+ }
1153+
1154+ impl < ' tcx > FallibleTypeFolder < ' tcx > for SkipBindersAt < ' tcx > {
1155+ type Error = ( ) ;
1156+
1157+ fn tcx ( & self ) -> TyCtxt < ' tcx > {
1158+ self . tcx
1159+ }
1160+
1161+ fn try_fold_binder < T > ( & mut self , t : Binder < ' tcx , T > ) -> Result < Binder < ' tcx , T > , Self :: Error >
1162+ where
1163+ T : ty:: TypeFoldable < ' tcx > ,
1164+ {
1165+ self . index . shift_in ( 1 ) ;
1166+ let value = t. try_map_bound ( |t| t. try_fold_with ( self ) ) ;
1167+ self . index . shift_out ( 1 ) ;
1168+ value
1169+ }
1170+
1171+ fn try_fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Result < Ty < ' tcx > , Self :: Error > {
1172+ if !ty. has_escaping_bound_vars ( ) {
1173+ Ok ( ty)
1174+ } else if let ty:: Bound ( index, bv) = * ty. kind ( ) {
1175+ if index == self . index {
1176+ Err ( ( ) )
1177+ } else {
1178+ Ok ( self . tcx ( ) . mk_ty ( ty:: Bound ( index. shifted_out ( 1 ) , bv) ) )
1179+ }
1180+ } else {
1181+ ty. try_super_fold_with ( self )
1182+ }
1183+ }
1184+
1185+ fn try_fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> Result < ty:: Region < ' tcx > , Self :: Error > {
1186+ if !r. has_escaping_bound_vars ( ) {
1187+ Ok ( r)
1188+ } else if let ty:: ReLateBound ( index, bv) = r. kind ( ) {
1189+ if index == self . index {
1190+ Err ( ( ) )
1191+ } else {
1192+ Ok ( self . tcx ( ) . mk_region ( ty:: ReLateBound ( index. shifted_out ( 1 ) , bv) ) )
1193+ }
1194+ } else {
1195+ r. try_super_fold_with ( self )
1196+ }
1197+ }
1198+
1199+ fn try_fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> Result < ty:: Const < ' tcx > , Self :: Error > {
1200+ if !ct. has_escaping_bound_vars ( ) {
1201+ Ok ( ct)
1202+ } else if let ty:: ConstKind :: Bound ( index, bv) = ct. kind ( ) {
1203+ if index == self . index {
1204+ Err ( ( ) )
1205+ } else {
1206+ Ok ( self . tcx ( ) . mk_const (
1207+ ty:: ConstKind :: Bound ( index. shifted_out ( 1 ) , bv) ,
1208+ ct. ty ( ) . try_fold_with ( self ) ?,
1209+ ) )
1210+ }
1211+ } else {
1212+ ct. try_super_fold_with ( self )
1213+ }
1214+ }
1215+
1216+ fn try_fold_predicate (
1217+ & mut self ,
1218+ p : ty:: Predicate < ' tcx > ,
1219+ ) -> Result < ty:: Predicate < ' tcx > , Self :: Error > {
1220+ if !p. has_escaping_bound_vars ( ) { Ok ( p) } else { p. try_super_fold_with ( self ) }
1221+ }
1222+ }
1223+
11381224/// Represents the projection of an associated type.
11391225///
11401226/// For a projection, this would be `<Ty as Trait<...>>::N`.
0 commit comments