File tree Expand file tree Collapse file tree 2 files changed +42
-8
lines changed Expand file tree Collapse file tree 2 files changed +42
-8
lines changed Original file line number Diff line number Diff line change @@ -161,14 +161,16 @@ pub fn push_auto_trait_impls<I: Interner>(
161
161
TyKind :: Foreign ( _) => Ok ( ( ) ) ,
162
162
163
163
// closures require binders, while the other types do not
164
- TyKind :: Closure ( closure_id, _) => {
165
- let binders = builder
166
- . db
167
- . closure_upvars ( * closure_id, & Substitution :: empty ( interner) ) ;
168
- builder. push_binders ( binders, |builder, upvar_ty| {
169
- let conditions = iter:: once ( mk_ref ( upvar_ty) ) ;
170
- builder. push_clause ( consequence, conditions) ;
171
- } ) ;
164
+ TyKind :: Closure ( closure_id, substs) => {
165
+ let closure_fn_substitution = builder. db . closure_fn_substitution ( * closure_id, substs) ;
166
+ let binders = builder. db . closure_upvars ( * closure_id, substs) ;
167
+ let upvars = binders. substitute ( builder. db . interner ( ) , & closure_fn_substitution) ;
168
+
169
+ // in a same behavior as for non-auto traits (reuse the code) we can require that
170
+ // every bound type must implement this auto-trait
171
+ use crate :: clauses:: builtin_traits:: needs_impl_for_tys;
172
+ needs_impl_for_tys ( builder. db , builder, consequence, Some ( upvars) . into_iter ( ) ) ;
173
+
172
174
Ok ( ( ) )
173
175
}
174
176
TyKind :: Generator ( generator_id, _) => {
Original file line number Diff line number Diff line change @@ -280,3 +280,35 @@ fn closure_implements_fn_traits() {
280
280
}
281
281
}
282
282
}
283
+
284
+ #[ test]
285
+ fn closures_propagate_auto_traits ( ) {
286
+ test ! {
287
+ program {
288
+ #[ auto]
289
+ trait Send { }
290
+
291
+ closure foo( self , ) { }
292
+
293
+ closure with_ty<T >( self , ) { T }
294
+ }
295
+
296
+ goal {
297
+ foo: Send
298
+ } yields {
299
+ expect![ [ "Unique" ] ]
300
+ }
301
+
302
+ goal {
303
+ forall<T > { with_ty<T >: Send }
304
+ } yields {
305
+ expect![ [ "No possible solution" ] ]
306
+ }
307
+
308
+ goal {
309
+ forall<T > { if ( T : Send ) { with_ty<T >: Send } }
310
+ } yields {
311
+ expect![ [ "Unique" ] ]
312
+ }
313
+ }
314
+ }
You can’t perform that action at this time.
0 commit comments