@@ -12,7 +12,9 @@ use crate::data_structures::SsoHashSet;
1212use crate :: fold:: { FallibleTypeFolder , TypeFoldable , TypeFolder , TypeSuperFoldable } ;
1313use crate :: inherent:: * ;
1414use crate :: lift:: Lift ;
15- use crate :: visit:: { Flags , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor } ;
15+ use crate :: visit:: {
16+ Flags , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor , try_visit,
17+ } ;
1618use crate :: { self as ty, Interner } ;
1719
1820/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
@@ -34,6 +36,7 @@ use crate::{self as ty, Interner};
3436pub struct Binder < I : Interner , T > {
3537 value : T ,
3638 bound_vars : I :: BoundVarKinds ,
39+ clauses : I :: Clauses ,
3740}
3841
3942// FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't
@@ -42,13 +45,15 @@ impl<I: Interner, U: Interner, T> Lift<U> for Binder<I, T>
4245where
4346 T : Lift < U > ,
4447 I :: BoundVarKinds : Lift < U , Lifted = U :: BoundVarKinds > ,
48+ I :: Clauses : Lift < U , Lifted = U :: Clauses > ,
4549{
4650 type Lifted = Binder < U , T :: Lifted > ;
4751
4852 fn lift_to_interner ( self , cx : U ) -> Option < Self :: Lifted > {
4953 Some ( Binder {
5054 value : self . value . lift_to_interner ( cx) ?,
5155 bound_vars : self . bound_vars . lift_to_interner ( cx) ?,
56+ clauses : self . clauses . lift_to_interner ( cx) ?,
5257 } )
5358 }
5459}
@@ -106,15 +111,28 @@ where
106111 !value. has_escaping_bound_vars( ) ,
107112 "`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
108113 ) ;
109- Binder { value, bound_vars : Default :: default ( ) }
114+ Binder { value, bound_vars : Default :: default ( ) , clauses : I :: Clauses :: empty ( ) }
110115 }
111116
112117 pub fn bind_with_vars ( value : T , bound_vars : I :: BoundVarKinds ) -> Binder < I , T > {
113118 if cfg ! ( debug_assertions) {
114119 let mut validator = ValidateBoundVars :: new ( bound_vars) ;
115120 let _ = value. visit_with ( & mut validator) ;
116121 }
117- Binder { value, bound_vars }
122+ Binder { value, bound_vars, clauses : I :: Clauses :: empty ( ) }
123+ }
124+
125+ pub fn bind_with_vars_and_clauses (
126+ value : T ,
127+ bound_vars : I :: BoundVarKinds ,
128+ clauses : I :: Clauses ,
129+ ) -> Binder < I , T > {
130+ if cfg ! ( debug_assertions) {
131+ let mut validator = ValidateBoundVars :: new ( bound_vars) ;
132+ value. visit_with ( & mut validator) ;
133+ clauses. visit_with ( & mut validator) ;
134+ }
135+ Binder { bound_vars, value, clauses }
118136 }
119137}
120138
@@ -135,13 +153,18 @@ impl<I: Interner, T: TypeFoldable<I>> TypeSuperFoldable<I> for Binder<I, T> {
135153 self ,
136154 folder : & mut F ,
137155 ) -> Result < Self , F :: Error > {
138- self . try_map_bound ( |ty| ty. try_fold_with ( folder) )
156+ let Binder { bound_vars, value, clauses } = self ;
157+ let clauses = clauses. try_fold_with ( folder) ?;
158+ let value = value. try_fold_with ( folder) ?;
159+ Ok ( Binder :: bind_with_vars_and_clauses ( value, bound_vars, clauses) )
139160 }
140161}
141162
142163impl < I : Interner , T : TypeVisitable < I > > TypeSuperVisitable < I > for Binder < I , T > {
143164 fn super_visit_with < V : TypeVisitor < I > > ( & self , visitor : & mut V ) -> V :: Result {
144- self . as_ref ( ) . skip_binder ( ) . visit_with ( visitor)
165+ let ( value, clauses) = self . as_ref ( ) . skip_binder_with_clauses ( ) ;
166+ try_visit ! ( clauses. visit_with( visitor) ) ;
167+ value. visit_with ( visitor)
145168 }
146169}
147170
@@ -166,19 +189,23 @@ impl<I: Interner, T> Binder<I, T> {
166189 self . value
167190 }
168191
192+ pub fn skip_binder_with_clauses ( self ) -> ( T , I :: Clauses ) {
193+ ( self . value , self . clauses )
194+ }
195+
169196 pub fn bound_vars ( & self ) -> I :: BoundVarKinds {
170197 self . bound_vars
171198 }
172199
173200 pub fn as_ref ( & self ) -> Binder < I , & T > {
174- Binder { value : & self . value , bound_vars : self . bound_vars }
201+ Binder { value : & self . value , bound_vars : self . bound_vars , clauses : self . clauses }
175202 }
176203
177204 pub fn as_deref ( & self ) -> Binder < I , & T :: Target >
178205 where
179206 T : Deref ,
180207 {
181- Binder { value : & self . value , bound_vars : self . bound_vars }
208+ Binder { value : & self . value , bound_vars : self . bound_vars , clauses : self . clauses }
182209 }
183210
184211 pub fn map_bound_ref < F , U : TypeVisitable < I > > ( & self , f : F ) -> Binder < I , U >
@@ -192,26 +219,39 @@ impl<I: Interner, T> Binder<I, T> {
192219 where
193220 F : FnOnce ( T ) -> U ,
194221 {
195- let Binder { value, bound_vars } = self ;
222+ let Binder { value, bound_vars, clauses } = self ;
196223 let value = f ( value) ;
197224 if cfg ! ( debug_assertions) {
198225 let mut validator = ValidateBoundVars :: new ( bound_vars) ;
199226 let _ = value. visit_with ( & mut validator) ;
200227 }
201- Binder { value, bound_vars }
228+ Binder { value, bound_vars, clauses }
229+ }
230+
231+ pub fn map_clauses < F , U : TypeVisitable < I > > ( self , f : F ) -> Self
232+ where
233+ F : FnOnce ( I :: Clauses ) -> I :: Clauses ,
234+ {
235+ let Binder { value, bound_vars, clauses } = self ;
236+ let clauses = f ( clauses) ;
237+ if cfg ! ( debug_assertions) {
238+ let mut validator = ValidateBoundVars :: new ( bound_vars) ;
239+ clauses. visit_with ( & mut validator) ;
240+ }
241+ Binder { value, bound_vars, clauses }
202242 }
203243
204244 pub fn try_map_bound < F , U : TypeVisitable < I > , E > ( self , f : F ) -> Result < Binder < I , U > , E >
205245 where
206246 F : FnOnce ( T ) -> Result < U , E > ,
207247 {
208- let Binder { value, bound_vars } = self ;
248+ let Binder { value, bound_vars, clauses } = self ;
209249 let value = f ( value) ?;
210250 if cfg ! ( debug_assertions) {
211251 let mut validator = ValidateBoundVars :: new ( bound_vars) ;
212252 let _ = value. visit_with ( & mut validator) ;
213253 }
214- Ok ( Binder { value, bound_vars } )
254+ Ok ( Binder { value, bound_vars, clauses } )
215255 }
216256
217257 /// Wraps a `value` in a binder, using the same bound variables as the
@@ -227,7 +267,7 @@ impl<I: Interner, T> Binder<I, T> {
227267 where
228268 U : TypeVisitable < I > ,
229269 {
230- Binder :: bind_with_vars ( value, self . bound_vars )
270+ Binder :: bind_with_vars_and_clauses ( value, self . bound_vars , self . clauses )
231271 }
232272
233273 /// Unwraps and returns the value within, but only if it contains
@@ -245,21 +285,25 @@ impl<I: Interner, T> Binder<I, T> {
245285 T : TypeVisitable < I > ,
246286 {
247287 // `self.value` is equivalent to `self.skip_binder()`
248- if self . value . has_escaping_bound_vars ( ) { None } else { Some ( self . skip_binder ( ) ) }
288+ if self . value . has_escaping_bound_vars ( ) && self . clauses . is_empty ( ) {
289+ None
290+ } else {
291+ Some ( self . skip_binder ( ) )
292+ }
249293 }
250294}
251295
252296impl < I : Interner , T > Binder < I , Option < T > > {
253297 pub fn transpose ( self ) -> Option < Binder < I , T > > {
254- let Binder { value, bound_vars } = self ;
255- value. map ( |value| Binder { value, bound_vars } )
298+ let Binder { value, bound_vars, clauses } = self ;
299+ value. map ( |value| Binder { value, bound_vars, clauses } )
256300 }
257301}
258302
259303impl < I : Interner , T : IntoIterator > Binder < I , T > {
260304 pub fn iter ( self ) -> impl Iterator < Item = Binder < I , T :: Item > > {
261- let Binder { value, bound_vars } = self ;
262- value. into_iter ( ) . map ( move |value| Binder { value, bound_vars } )
305+ let Binder { value, bound_vars, clauses } = self ;
306+ value. into_iter ( ) . map ( move |value| Binder { value, bound_vars, clauses } )
263307 }
264308}
265309
0 commit comments