@@ -458,28 +458,23 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
458
458
) )
459
459
}
460
460
461
- ty:: FnDef ( ..) | ty:: FnPtr ( ..) => {
462
- let bound_sig = self_ty. fn_sig ( cx) ;
463
- let sig = bound_sig. skip_binder ( ) ;
464
- let future_trait_def_id = cx. require_lang_item ( TraitSolverLangItem :: Future ) ;
465
- // `FnDef` and `FnPtr` only implement `AsyncFn*` when their
466
- // return type implements `Future`.
467
- let nested = vec ! [
468
- bound_sig
469
- . rebind( ty:: TraitRef :: new( cx, future_trait_def_id, [ sig. output( ) ] ) )
470
- . upcast( cx) ,
471
- ] ;
472
- let future_output_def_id = cx. require_lang_item ( TraitSolverLangItem :: FutureOutput ) ;
473
- let future_output_ty = Ty :: new_projection ( cx, future_output_def_id, [ sig. output ( ) ] ) ;
474
- Ok ( (
475
- bound_sig. rebind ( AsyncCallableRelevantTypes {
476
- tupled_inputs_ty : Ty :: new_tup ( cx, sig. inputs ( ) . as_slice ( ) ) ,
477
- output_coroutine_ty : sig. output ( ) ,
478
- coroutine_return_ty : future_output_ty,
479
- } ) ,
480
- nested,
481
- ) )
461
+ ty:: FnDef ( def_id, _) => {
462
+ let sig = self_ty. fn_sig ( cx) ;
463
+ if sig. skip_binder ( ) . is_fn_trait_compatible ( ) && !cx. has_target_features ( def_id) {
464
+ fn_item_to_async_callable ( cx, sig)
465
+ } else {
466
+ Err ( NoSolution )
467
+ }
468
+ }
469
+ ty:: FnPtr ( ..) => {
470
+ let sig = self_ty. fn_sig ( cx) ;
471
+ if sig. skip_binder ( ) . is_fn_trait_compatible ( ) {
472
+ fn_item_to_async_callable ( cx, sig)
473
+ } else {
474
+ Err ( NoSolution )
475
+ }
482
476
}
477
+
483
478
ty:: Closure ( _, args) => {
484
479
let args = args. as_closure ( ) ;
485
480
let bound_sig = args. sig ( ) ;
@@ -563,6 +558,29 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
563
558
}
564
559
}
565
560
561
+ fn fn_item_to_async_callable < I : Interner > (
562
+ cx : I ,
563
+ bound_sig : ty:: Binder < I , ty:: FnSig < I > > ,
564
+ ) -> Result < ( ty:: Binder < I , AsyncCallableRelevantTypes < I > > , Vec < I :: Predicate > ) , NoSolution > {
565
+ let sig = bound_sig. skip_binder ( ) ;
566
+ let future_trait_def_id = cx. require_lang_item ( TraitSolverLangItem :: Future ) ;
567
+ // `FnDef` and `FnPtr` only implement `AsyncFn*` when their
568
+ // return type implements `Future`.
569
+ let nested = vec ! [
570
+ bound_sig. rebind( ty:: TraitRef :: new( cx, future_trait_def_id, [ sig. output( ) ] ) ) . upcast( cx) ,
571
+ ] ;
572
+ let future_output_def_id = cx. require_lang_item ( TraitSolverLangItem :: FutureOutput ) ;
573
+ let future_output_ty = Ty :: new_projection ( cx, future_output_def_id, [ sig. output ( ) ] ) ;
574
+ Ok ( (
575
+ bound_sig. rebind ( AsyncCallableRelevantTypes {
576
+ tupled_inputs_ty : Ty :: new_tup ( cx, sig. inputs ( ) . as_slice ( ) ) ,
577
+ output_coroutine_ty : sig. output ( ) ,
578
+ coroutine_return_ty : future_output_ty,
579
+ } ) ,
580
+ nested,
581
+ ) )
582
+ }
583
+
566
584
/// Given a coroutine-closure, project to its returned coroutine when we are *certain*
567
585
/// that the closure's kind is compatible with the goal.
568
586
fn coroutine_closure_to_certain_coroutine < I : Interner > (
0 commit comments