@@ -2450,99 +2450,170 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
24502450) -> Progress < ' tcx > {
24512451 let tcx = selcx. tcx ( ) ;
24522452 let self_ty = selcx. infcx . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
2453- let ty:: CoroutineClosure ( def_id, args) = * self_ty. kind ( ) else {
2454- unreachable ! (
2455- "expected coroutine-closure self type for coroutine-closure candidate, found {self_ty}"
2456- )
2457- } ;
2458- let args = args. as_coroutine_closure ( ) ;
2459- let kind_ty = args. kind_ty ( ) ;
2460- let sig = args. coroutine_closure_sig ( ) . skip_binder ( ) ;
24612453
24622454 let goal_kind =
24632455 tcx. async_fn_trait_kind_from_def_id ( obligation. predicate . trait_def_id ( tcx) ) . unwrap ( ) ;
24642456 let env_region = match goal_kind {
24652457 ty:: ClosureKind :: Fn | ty:: ClosureKind :: FnMut => obligation. predicate . args . region_at ( 2 ) ,
24662458 ty:: ClosureKind :: FnOnce => tcx. lifetimes . re_static ,
24672459 } ;
2468-
24692460 let item_name = tcx. item_name ( obligation. predicate . def_id ) ;
2470- let term = match item_name {
2471- sym:: CallOnceFuture | sym:: CallMutFuture | sym:: CallFuture => {
2472- if let Some ( closure_kind) = kind_ty. to_opt_closure_kind ( ) {
2473- if !closure_kind. extends ( goal_kind) {
2474- bug ! ( "we should not be confirming if the closure kind is not met" ) ;
2461+
2462+ let poly_cache_entry = match * self_ty. kind ( ) {
2463+ ty:: CoroutineClosure ( def_id, args) => {
2464+ let args = args. as_coroutine_closure ( ) ;
2465+ let kind_ty = args. kind_ty ( ) ;
2466+ let sig = args. coroutine_closure_sig ( ) . skip_binder ( ) ;
2467+
2468+ let term = match item_name {
2469+ sym:: CallOnceFuture | sym:: CallMutFuture | sym:: CallFuture => {
2470+ if let Some ( closure_kind) = kind_ty. to_opt_closure_kind ( ) {
2471+ if !closure_kind. extends ( goal_kind) {
2472+ bug ! ( "we should not be confirming if the closure kind is not met" ) ;
2473+ }
2474+ sig. to_coroutine_given_kind_and_upvars (
2475+ tcx,
2476+ args. parent_args ( ) ,
2477+ tcx. coroutine_for_closure ( def_id) ,
2478+ goal_kind,
2479+ env_region,
2480+ args. tupled_upvars_ty ( ) ,
2481+ args. coroutine_captures_by_ref_ty ( ) ,
2482+ )
2483+ } else {
2484+ let async_fn_kind_trait_def_id =
2485+ tcx. require_lang_item ( LangItem :: AsyncFnKindHelper , None ) ;
2486+ let upvars_projection_def_id = tcx
2487+ . associated_items ( async_fn_kind_trait_def_id)
2488+ . filter_by_name_unhygienic ( sym:: Upvars )
2489+ . next ( )
2490+ . unwrap ( )
2491+ . def_id ;
2492+ // When we don't know the closure kind (and therefore also the closure's upvars,
2493+ // which are computed at the same time), we must delay the computation of the
2494+ // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
2495+ // goal functions similarly to the old `ClosureKind` predicate, and ensures that
2496+ // the goal kind <= the closure kind. As a projection `AsyncFnKindHelper::Upvars`
2497+ // will project to the right upvars for the generator, appending the inputs and
2498+ // coroutine upvars respecting the closure kind.
2499+ // N.B. No need to register a `AsyncFnKindHelper` goal here, it's already in `nested`.
2500+ let tupled_upvars_ty = Ty :: new_projection (
2501+ tcx,
2502+ upvars_projection_def_id,
2503+ [
2504+ ty:: GenericArg :: from ( kind_ty) ,
2505+ Ty :: from_closure_kind ( tcx, goal_kind) . into ( ) ,
2506+ env_region. into ( ) ,
2507+ sig. tupled_inputs_ty . into ( ) ,
2508+ args. tupled_upvars_ty ( ) . into ( ) ,
2509+ args. coroutine_captures_by_ref_ty ( ) . into ( ) ,
2510+ ] ,
2511+ ) ;
2512+ sig. to_coroutine (
2513+ tcx,
2514+ args. parent_args ( ) ,
2515+ Ty :: from_closure_kind ( tcx, goal_kind) ,
2516+ tcx. coroutine_for_closure ( def_id) ,
2517+ tupled_upvars_ty,
2518+ )
2519+ }
24752520 }
2476- sig. to_coroutine_given_kind_and_upvars (
2521+ sym:: Output => sig. return_ty ,
2522+ name => bug ! ( "no such associated type: {name}" ) ,
2523+ } ;
2524+ let projection_ty = match item_name {
2525+ sym:: CallOnceFuture | sym:: Output => ty:: AliasTy :: new (
24772526 tcx,
2478- args. parent_args ( ) ,
2479- tcx. coroutine_for_closure ( def_id) ,
2480- goal_kind,
2481- env_region,
2482- args. tupled_upvars_ty ( ) ,
2483- args. coroutine_captures_by_ref_ty ( ) ,
2484- )
2485- } else {
2486- let async_fn_kind_trait_def_id =
2487- tcx. require_lang_item ( LangItem :: AsyncFnKindHelper , None ) ;
2488- let upvars_projection_def_id = tcx
2489- . associated_items ( async_fn_kind_trait_def_id)
2490- . filter_by_name_unhygienic ( sym:: Upvars )
2491- . next ( )
2492- . unwrap ( )
2493- . def_id ;
2494- // When we don't know the closure kind (and therefore also the closure's upvars,
2495- // which are computed at the same time), we must delay the computation of the
2496- // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
2497- // goal functions similarly to the old `ClosureKind` predicate, and ensures that
2498- // the goal kind <= the closure kind. As a projection `AsyncFnKindHelper::Upvars`
2499- // will project to the right upvars for the generator, appending the inputs and
2500- // coroutine upvars respecting the closure kind.
2501- // N.B. No need to register a `AsyncFnKindHelper` goal here, it's already in `nested`.
2502- let tupled_upvars_ty = Ty :: new_projection (
2527+ obligation. predicate . def_id ,
2528+ [ self_ty, sig. tupled_inputs_ty ] ,
2529+ ) ,
2530+ sym:: CallMutFuture | sym:: CallFuture => ty:: AliasTy :: new (
25032531 tcx,
2504- upvars_projection_def_id,
2532+ obligation. predicate . def_id ,
2533+ [ ty:: GenericArg :: from ( self_ty) , sig. tupled_inputs_ty . into ( ) , env_region. into ( ) ] ,
2534+ ) ,
2535+ name => bug ! ( "no such associated type: {name}" ) ,
2536+ } ;
2537+
2538+ args. coroutine_closure_sig ( )
2539+ . rebind ( ty:: ProjectionPredicate { projection_ty, term : term. into ( ) } )
2540+ }
2541+ ty:: FnDef ( ..) | ty:: FnPtr ( ..) => {
2542+ let bound_sig = self_ty. fn_sig ( tcx) ;
2543+ let sig = bound_sig. skip_binder ( ) ;
2544+
2545+ let term = match item_name {
2546+ sym:: CallOnceFuture | sym:: CallMutFuture | sym:: CallFuture => sig. output ( ) ,
2547+ sym:: Output => {
2548+ let future_trait_def_id = tcx. require_lang_item ( LangItem :: Future , None ) ;
2549+ let future_output_def_id = tcx
2550+ . associated_items ( future_trait_def_id)
2551+ . filter_by_name_unhygienic ( sym:: Output )
2552+ . next ( )
2553+ . unwrap ( )
2554+ . def_id ;
2555+ Ty :: new_projection ( tcx, future_output_def_id, [ sig. output ( ) ] )
2556+ }
2557+ name => bug ! ( "no such associated type: {name}" ) ,
2558+ } ;
2559+ let projection_ty = match item_name {
2560+ sym:: CallOnceFuture | sym:: Output => ty:: AliasTy :: new (
2561+ tcx,
2562+ obligation. predicate . def_id ,
2563+ [ self_ty, Ty :: new_tup ( tcx, sig. inputs ( ) ) ] ,
2564+ ) ,
2565+ sym:: CallMutFuture | sym:: CallFuture => ty:: AliasTy :: new (
2566+ tcx,
2567+ obligation. predicate . def_id ,
25052568 [
2506- ty:: GenericArg :: from ( kind_ty ) ,
2507- Ty :: from_closure_kind ( tcx, goal_kind ) . into ( ) ,
2569+ ty:: GenericArg :: from ( self_ty ) ,
2570+ Ty :: new_tup ( tcx, sig . inputs ( ) ) . into ( ) ,
25082571 env_region. into ( ) ,
2509- sig. tupled_inputs_ty . into ( ) ,
2510- args. tupled_upvars_ty ( ) . into ( ) ,
2511- args. coroutine_captures_by_ref_ty ( ) . into ( ) ,
25122572 ] ,
2513- ) ;
2514- sig. to_coroutine (
2515- tcx,
2516- args. parent_args ( ) ,
2517- Ty :: from_closure_kind ( tcx, goal_kind) ,
2518- tcx. coroutine_for_closure ( def_id) ,
2519- tupled_upvars_ty,
2520- )
2521- }
2573+ ) ,
2574+ name => bug ! ( "no such associated type: {name}" ) ,
2575+ } ;
2576+
2577+ bound_sig. rebind ( ty:: ProjectionPredicate { projection_ty, term : term. into ( ) } )
25222578 }
2523- sym:: Output => sig. return_ty ,
2524- name => bug ! ( "no such associated type: {name}" ) ,
2525- } ;
2526- let projection_ty = match item_name {
2527- sym:: CallOnceFuture | sym:: Output => {
2528- ty:: AliasTy :: new ( tcx, obligation. predicate . def_id , [ self_ty, sig. tupled_inputs_ty ] )
2579+ ty:: Closure ( _, args) => {
2580+ let args = args. as_closure ( ) ;
2581+ let bound_sig = args. sig ( ) ;
2582+ let sig = bound_sig. skip_binder ( ) ;
2583+
2584+ let term = match item_name {
2585+ sym:: CallOnceFuture | sym:: CallMutFuture | sym:: CallFuture => sig. output ( ) ,
2586+ sym:: Output => {
2587+ let future_trait_def_id = tcx. require_lang_item ( LangItem :: Future , None ) ;
2588+ let future_output_def_id = tcx
2589+ . associated_items ( future_trait_def_id)
2590+ . filter_by_name_unhygienic ( sym:: Output )
2591+ . next ( )
2592+ . unwrap ( )
2593+ . def_id ;
2594+ Ty :: new_projection ( tcx, future_output_def_id, [ sig. output ( ) ] )
2595+ }
2596+ name => bug ! ( "no such associated type: {name}" ) ,
2597+ } ;
2598+ let projection_ty = match item_name {
2599+ sym:: CallOnceFuture | sym:: Output => {
2600+ ty:: AliasTy :: new ( tcx, obligation. predicate . def_id , [ self_ty, sig. inputs ( ) [ 0 ] ] )
2601+ }
2602+ sym:: CallMutFuture | sym:: CallFuture => ty:: AliasTy :: new (
2603+ tcx,
2604+ obligation. predicate . def_id ,
2605+ [ ty:: GenericArg :: from ( self_ty) , sig. inputs ( ) [ 0 ] . into ( ) , env_region. into ( ) ] ,
2606+ ) ,
2607+ name => bug ! ( "no such associated type: {name}" ) ,
2608+ } ;
2609+
2610+ bound_sig. rebind ( ty:: ProjectionPredicate { projection_ty, term : term. into ( ) } )
25292611 }
2530- sym:: CallMutFuture | sym:: CallFuture => ty:: AliasTy :: new (
2531- tcx,
2532- obligation. predicate . def_id ,
2533- [ ty:: GenericArg :: from ( self_ty) , sig. tupled_inputs_ty . into ( ) , env_region. into ( ) ] ,
2534- ) ,
2535- name => bug ! ( "no such associated type: {name}" ) ,
2612+ _ => bug ! ( "expected callable type for AsyncFn candidate" ) ,
25362613 } ;
25372614
2538- confirm_param_env_candidate (
2539- selcx,
2540- obligation,
2541- args. coroutine_closure_sig ( )
2542- . rebind ( ty:: ProjectionPredicate { projection_ty, term : term. into ( ) } ) ,
2543- true ,
2544- )
2545- . with_addl_obligations ( nested)
2615+ confirm_param_env_candidate ( selcx, obligation, poly_cache_entry, true )
2616+ . with_addl_obligations ( nested)
25462617}
25472618
25482619fn confirm_async_fn_kind_helper_candidate < ' cx , ' tcx > (
0 commit comments