@@ -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,36 +291,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
260
291
} )
261
292
}
262
293
263
- fn consider_assumption_with_certainty (
264
- ecx : & mut EvalCtxt < ' _ , ' tcx > ,
265
- goal : Goal < ' tcx , Self > ,
266
- assumption : ty:: Predicate < ' tcx > ,
267
- assumption_certainty : Certainty ,
268
- ) -> QueryResult < ' tcx > {
269
- if let Some ( poly_projection_pred) = assumption. to_opt_poly_projection_pred ( )
270
- && poly_projection_pred. projection_def_id ( ) == goal. predicate . def_id ( )
271
- {
272
- ecx. infcx . probe ( |_| {
273
- let assumption_projection_pred =
274
- ecx. infcx . instantiate_binder_with_infer ( poly_projection_pred) ;
275
- let nested_goals = ecx. infcx . eq (
276
- goal. param_env ,
277
- goal. predicate . projection_ty ,
278
- assumption_projection_pred. projection_ty ,
279
- ) ?;
280
- let subst_certainty = ecx. evaluate_all ( nested_goals) ?;
281
-
282
- ecx. eq_term_and_make_canonical_response (
283
- goal,
284
- subst_certainty. unify_and ( assumption_certainty) ,
285
- assumption_projection_pred. term ,
286
- )
287
- } )
288
- } else {
289
- Err ( NoSolution )
290
- }
291
- }
292
-
293
294
fn consider_auto_trait_candidate (
294
295
_ecx : & mut EvalCtxt < ' _ , ' tcx > ,
295
296
goal : Goal < ' tcx , Self > ,
@@ -331,31 +332,27 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
331
332
goal_kind : ty:: ClosureKind ,
332
333
) -> QueryResult < ' tcx > {
333
334
let tcx = ecx. tcx ( ) ;
334
- if let Some ( tupled_inputs_and_output) =
335
- structural_traits:: extract_tupled_inputs_and_output_from_callable (
336
- tcx,
337
- goal. predicate . self_ty ( ) ,
338
- goal_kind,
339
- ) ?
340
- {
341
- // A built-in `Fn` trait needs to check that its output is `Sized`
342
- // (FIXME: technically we only need to check this if the type is a fn ptr...)
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
- let ( _, output_is_sized_certainty) =
346
- ecx. evaluate_goal ( goal. with ( tcx, output_is_sized_pred) ) ?;
347
-
348
- let pred = tupled_inputs_and_output
349
- . map_bound ( |( inputs, output) | ty:: ProjectionPredicate {
350
- projection_ty : tcx
351
- . mk_alias_ty ( goal. predicate . def_id ( ) , [ goal. predicate . self_ty ( ) , inputs] ) ,
352
- term : output. into ( ) ,
353
- } )
354
- . to_predicate ( tcx) ;
355
- Self :: consider_assumption_with_certainty ( ecx, goal, pred, output_is_sized_certainty)
356
- } else {
357
- ecx. make_canonical_response ( Certainty :: AMBIGUOUS )
358
- }
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) ] )
359
356
}
360
357
361
358
fn consider_builtin_tuple_candidate (
@@ -474,14 +471,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
474
471
475
472
let term = substs. as_generator ( ) . return_ty ( ) . into ( ) ;
476
473
477
- Self :: consider_assumption (
474
+ Self :: consider_implied_clause (
478
475
ecx,
479
476
goal,
480
477
ty:: Binder :: dummy ( ty:: ProjectionPredicate {
481
478
projection_ty : ecx. tcx ( ) . mk_alias_ty ( goal. predicate . def_id ( ) , [ self_ty] ) ,
482
479
term,
483
480
} )
484
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
+ [ ] ,
485
485
)
486
486
}
487
487
@@ -511,7 +511,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
511
511
bug ! ( "unexpected associated item `<{self_ty} as Generator>::{name}`" )
512
512
} ;
513
513
514
- Self :: consider_assumption (
514
+ Self :: consider_implied_clause (
515
515
ecx,
516
516
goal,
517
517
ty:: Binder :: dummy ( ty:: ProjectionPredicate {
@@ -521,6 +521,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
521
521
term,
522
522
} )
523
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
+ [ ] ,
524
527
)
525
528
}
526
529
0 commit comments