@@ -10,7 +10,6 @@ use rustc_hir as hir;
1010use rustc_hir:: def:: Res ;
1111use rustc_span:: source_map:: { respan, DesugaringKind , Span , Spanned } ;
1212use rustc_span:: symbol:: { sym, Symbol } ;
13- use rustc_span:: DUMMY_SP ;
1413
1514impl < ' hir > LoweringContext < ' _ , ' hir > {
1615 fn lower_exprs ( & mut self , exprs : & [ AstP < Expr > ] ) -> & ' hir [ hir:: Expr < ' hir > ] {
@@ -471,6 +470,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
471470 }
472471 }
473472
473+ /// Lower an `async` construct to a generator that is then wrapped so it implements `Future`.
474+ ///
475+ /// This results in:
476+ ///
477+ /// ```text
478+ /// std::future::from_generator(static move? |_task_context| -> <ret_ty> {
479+ /// <body>
480+ /// })
481+ /// ```
474482 pub ( super ) fn make_async_expr (
475483 & mut self ,
476484 capture_clause : CaptureBy ,
@@ -481,46 +489,42 @@ impl<'hir> LoweringContext<'_, 'hir> {
481489 body : impl FnOnce ( & mut Self ) -> hir:: Expr < ' hir > ,
482490 ) -> hir:: ExprKind < ' hir > {
483491 let output = match ret_ty {
484- Some ( ty) => FnRetTy :: Ty ( ty ) ,
485- None => FnRetTy :: Default ( span) ,
492+ Some ( ty) => hir :: FnRetTy :: Return ( self . lower_ty ( & ty , ImplTraitContext :: disallowed ( ) ) ) ,
493+ None => hir :: FnRetTy :: DefaultReturn ( span) ,
486494 } ;
487495
488- let task_context_id = self . resolver . next_node_id ( ) ;
489- let task_context_hid = self . lower_node_id ( task_context_id) ;
496+ // Resume argument type. We let the compiler infer this to simplify the lowering. It is
497+ // fully constrained by `future::from_generator`.
498+ let input_ty = hir:: Ty { hir_id : self . next_id ( ) , kind : hir:: TyKind :: Infer , span } ;
490499
491- let arg_ty = Ty { id : self . resolver . next_node_id ( ) , kind : TyKind :: Infer , span : DUMMY_SP } ;
492- let arg_pat = Pat {
493- id : task_context_id,
494- kind : PatKind :: Ident (
495- BindingMode :: ByValue ( Mutability :: Mut ) ,
496- Ident :: with_dummy_span ( sym:: _task_context) ,
497- None ,
498- ) ,
499- span : DUMMY_SP ,
500- } ;
501- let ast_decl = FnDecl {
502- inputs : vec ! [ Param {
503- attrs: AttrVec :: new( ) ,
504- ty: AstP ( arg_ty) ,
505- pat: AstP ( arg_pat) ,
506- id: self . resolver. next_node_id( ) ,
507- span: DUMMY_SP ,
508- is_placeholder: false ,
509- } ] ,
500+ // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
501+ let decl = self . arena . alloc ( hir:: FnDecl {
502+ inputs : arena_vec ! [ self ; input_ty] ,
510503 output,
511- } ;
512- let decl = self . lower_fn_decl ( & ast_decl, None , /* impl trait allowed */ false , None ) ;
513- let body_id = self . lower_fn_body ( & ast_decl, |this| {
504+ c_variadic : false ,
505+ implicit_self : hir:: ImplicitSelfKind :: None ,
506+ } ) ;
507+
508+ // Lower the argument pattern/ident. The ident is used again in the `.await` lowering.
509+ let ( pat, task_context_hid) = self . pat_ident_binding_mode (
510+ span,
511+ Ident :: with_dummy_span ( sym:: _task_context) ,
512+ hir:: BindingAnnotation :: Mutable ,
513+ ) ;
514+ let param = hir:: Param { attrs : & [ ] , hir_id : self . next_id ( ) , pat, span } ;
515+ let params = arena_vec ! [ self ; param] ;
516+
517+ let body_id = self . lower_body ( move |this| {
514518 this. generator_kind = Some ( hir:: GeneratorKind :: Async ( async_gen_kind) ) ;
515519
516520 let old_ctx = this. task_context ;
517521 this. task_context = Some ( task_context_hid) ;
518522 let res = body ( this) ;
519523 this. task_context = old_ctx;
520- res
524+ ( params , res)
521525 } ) ;
522526
523- // `static |task_context | -> <ret_ty> { body }`:
527+ // `static |_task_context | -> <ret_ty> { body }`:
524528 let generator_kind = hir:: ExprKind :: Closure (
525529 capture_clause,
526530 decl,
0 commit comments