@@ -168,6 +168,37 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
168
168
self . trait_def_id ( tcx)
169
169
}
170
170
171
+ fn consider_implied_clause (
172
+ ecx : & mut EvalCtxt < ' _ , ' tcx > ,
173
+ goal : Goal < ' tcx , Self > ,
174
+ assumption : ty:: Predicate < ' tcx > ,
175
+ requirements : impl IntoIterator < Item = Goal < ' tcx , ty:: Predicate < ' tcx > > > ,
176
+ ) -> QueryResult < ' tcx > {
177
+ if let Some ( poly_projection_pred) = assumption. to_opt_poly_projection_pred ( )
178
+ && poly_projection_pred. projection_def_id ( ) == goal. predicate . def_id ( )
179
+ {
180
+ ecx. infcx . probe ( |_| {
181
+ let assumption_projection_pred =
182
+ ecx. infcx . instantiate_binder_with_infer ( poly_projection_pred) ;
183
+ let mut nested_goals = ecx. infcx . eq (
184
+ goal. param_env ,
185
+ goal. predicate . projection_ty ,
186
+ assumption_projection_pred. projection_ty ,
187
+ ) ?;
188
+ nested_goals. extend ( requirements) ;
189
+ let subst_certainty = ecx. evaluate_all ( nested_goals) ?;
190
+
191
+ ecx. eq_term_and_make_canonical_response (
192
+ goal,
193
+ subst_certainty,
194
+ assumption_projection_pred. term ,
195
+ )
196
+ } )
197
+ } else {
198
+ Err ( NoSolution )
199
+ }
200
+ }
201
+
171
202
fn consider_impl_candidate (
172
203
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
173
204
goal : Goal < ' tcx , ProjectionPredicate < ' tcx > > ,
@@ -260,35 +291,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
260
291
} )
261
292
}
262
293
263
- fn consider_assumption (
264
- ecx : & mut EvalCtxt < ' _ , ' tcx > ,
265
- goal : Goal < ' tcx , Self > ,
266
- assumption : ty:: Predicate < ' tcx > ,
267
- ) -> QueryResult < ' tcx > {
268
- if let Some ( poly_projection_pred) = assumption. to_opt_poly_projection_pred ( )
269
- && poly_projection_pred. projection_def_id ( ) == goal. predicate . def_id ( )
270
- {
271
- ecx. infcx . probe ( |_| {
272
- let assumption_projection_pred =
273
- ecx. infcx . instantiate_binder_with_infer ( poly_projection_pred) ;
274
- let nested_goals = ecx. infcx . eq (
275
- goal. param_env ,
276
- goal. predicate . projection_ty ,
277
- assumption_projection_pred. projection_ty ,
278
- ) ?;
279
- let subst_certainty = ecx. evaluate_all ( nested_goals) ?;
280
-
281
- ecx. eq_term_and_make_canonical_response (
282
- goal,
283
- subst_certainty,
284
- assumption_projection_pred. term ,
285
- )
286
- } )
287
- } else {
288
- Err ( NoSolution )
289
- }
290
- }
291
-
292
294
fn consider_auto_trait_candidate (
293
295
_ecx : & mut EvalCtxt < ' _ , ' tcx > ,
294
296
goal : Goal < ' tcx , Self > ,
@@ -329,25 +331,28 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
329
331
goal : Goal < ' tcx , Self > ,
330
332
goal_kind : ty:: ClosureKind ,
331
333
) -> QueryResult < ' tcx > {
332
- if let Some ( tupled_inputs_and_output) =
333
- structural_traits:: extract_tupled_inputs_and_output_from_callable (
334
- ecx. tcx ( ) ,
335
- goal. predicate . self_ty ( ) ,
336
- goal_kind,
337
- ) ?
338
- {
339
- let pred = tupled_inputs_and_output
340
- . map_bound ( |( inputs, output) | ty:: ProjectionPredicate {
341
- projection_ty : ecx
342
- . tcx ( )
343
- . mk_alias_ty ( goal. predicate . def_id ( ) , [ goal. predicate . self_ty ( ) , inputs] ) ,
344
- term : output. into ( ) ,
345
- } )
346
- . to_predicate ( ecx. tcx ( ) ) ;
347
- Self :: consider_assumption ( ecx, goal, pred)
348
- } else {
349
- ecx. make_canonical_response ( Certainty :: AMBIGUOUS )
350
- }
334
+ let tcx = ecx. tcx ( ) ;
335
+ let Some ( tupled_inputs_and_output) =
336
+ structural_traits:: extract_tupled_inputs_and_output_from_callable (
337
+ tcx,
338
+ goal. predicate . self_ty ( ) ,
339
+ goal_kind,
340
+ ) ? else {
341
+ return ecx. make_canonical_response ( Certainty :: AMBIGUOUS ) ;
342
+ } ;
343
+ let output_is_sized_pred = tupled_inputs_and_output
344
+ . map_bound ( |( _, output) | tcx. at ( DUMMY_SP ) . mk_trait_ref ( LangItem :: Sized , [ output] ) ) ;
345
+
346
+ let pred = tupled_inputs_and_output
347
+ . map_bound ( |( inputs, output) | ty:: ProjectionPredicate {
348
+ projection_ty : tcx
349
+ . mk_alias_ty ( goal. predicate . def_id ( ) , [ goal. predicate . self_ty ( ) , inputs] ) ,
350
+ term : output. into ( ) ,
351
+ } )
352
+ . to_predicate ( tcx) ;
353
+ // A built-in `Fn` impl only holds if the output is sized.
354
+ // (FIXME: technically we only need to check this if the type is a fn ptr...)
355
+ Self :: consider_implied_clause ( ecx, goal, pred, [ goal. with ( tcx, output_is_sized_pred) ] )
351
356
}
352
357
353
358
fn consider_builtin_tuple_candidate (
@@ -466,14 +471,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
466
471
467
472
let term = substs. as_generator ( ) . return_ty ( ) . into ( ) ;
468
473
469
- Self :: consider_assumption (
474
+ Self :: consider_implied_clause (
470
475
ecx,
471
476
goal,
472
477
ty:: Binder :: dummy ( ty:: ProjectionPredicate {
473
478
projection_ty : ecx. tcx ( ) . mk_alias_ty ( goal. predicate . def_id ( ) , [ self_ty] ) ,
474
479
term,
475
480
} )
476
481
. to_predicate ( tcx) ,
482
+ // Technically, we need to check that the future type is Sized,
483
+ // but that's already proven by the generator being WF.
484
+ [ ] ,
477
485
)
478
486
}
479
487
@@ -503,7 +511,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
503
511
bug ! ( "unexpected associated item `<{self_ty} as Generator>::{name}`" )
504
512
} ;
505
513
506
- Self :: consider_assumption (
514
+ Self :: consider_implied_clause (
507
515
ecx,
508
516
goal,
509
517
ty:: Binder :: dummy ( ty:: ProjectionPredicate {
@@ -513,6 +521,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
513
521
term,
514
522
} )
515
523
. to_predicate ( tcx) ,
524
+ // Technically, we need to check that the future type is Sized,
525
+ // but that's already proven by the generator being WF.
526
+ [ ] ,
516
527
)
517
528
}
518
529
0 commit comments