@@ -448,10 +448,9 @@ impl<'a> LoweringContext<'a> {
448448 impl < ' lcx , ' interner > Visitor < ' lcx > for MiscCollector < ' lcx , ' interner > {
449449 fn visit_pat ( & mut self , p : & ' lcx Pat ) {
450450 match p. node {
451- // Doesn't generate a Hir node
451+ // Doesn't generate a HIR node
452452 PatKind :: Paren ( ..) => { } ,
453453 _ => {
454-
455454 if let Some ( owner) = self . hir_id_owner {
456455 self . lctx . lower_node_id_with_owner ( p. id , owner) ;
457456 }
@@ -461,6 +460,31 @@ impl<'a> LoweringContext<'a> {
461460 visit:: walk_pat ( self , p)
462461 }
463462
463+ fn visit_fn ( & mut self , fk : visit:: FnKind < ' lcx > , fd : & ' lcx FnDecl , s : Span , _: NodeId ) {
464+ if fk. header ( ) . map ( |h| h. asyncness . node . is_async ( ) ) . unwrap_or ( false ) {
465+ // Don't visit the original pattern for async functions as it will be
466+ // replaced.
467+ for arg in & fd. inputs {
468+ self . visit_ty ( & arg. ty )
469+ }
470+ self . visit_fn_ret_ty ( & fd. output ) ;
471+
472+ match fk {
473+ visit:: FnKind :: ItemFn ( _, decl, _, body) => {
474+ self . visit_fn_header ( decl) ;
475+ self . visit_block ( body)
476+ } ,
477+ visit:: FnKind :: Method ( _, sig, _, body) => {
478+ self . visit_fn_header ( & sig. header ) ;
479+ self . visit_block ( body)
480+ } ,
481+ visit:: FnKind :: Closure ( body) => self . visit_expr ( body) ,
482+ }
483+ } else {
484+ visit:: walk_fn ( self , fk, fd, s)
485+ }
486+ }
487+
464488 fn visit_item ( & mut self , item : & ' lcx Item ) {
465489 let hir_id = self . lctx . allocate_hir_id_counter ( item. id ) . hir_id ;
466490
@@ -3003,12 +3027,18 @@ impl<'a> LoweringContext<'a> {
30033027 asyncness : & IsAsync ,
30043028 body : & Block ,
30053029 ) -> hir:: BodyId {
3006- self . lower_body ( Some ( decl) , |this| {
3007- if let IsAsync :: Async { closure_id, .. } = asyncness {
3030+ self . lower_body ( Some ( & decl) , |this| {
3031+ if let IsAsync :: Async { closure_id, ref arguments, .. } = asyncness {
3032+ let mut body = body. clone ( ) ;
3033+
3034+ for a in arguments. iter ( ) . rev ( ) {
3035+ body. stmts . insert ( 0 , a. stmt . clone ( ) ) ;
3036+ }
3037+
30083038 let async_expr = this. make_async_expr (
30093039 CaptureBy :: Value , * closure_id, None ,
30103040 |this| {
3011- let body = this. lower_block ( body, false ) ;
3041+ let body = this. lower_block ( & body, false ) ;
30123042 this. expr_block ( body, ThinVec :: new ( ) )
30133043 } ) ;
30143044 this. expr ( body. span , async_expr, ThinVec :: new ( ) )
@@ -3070,23 +3100,39 @@ impl<'a> LoweringContext<'a> {
30703100 ItemKind :: Fn ( ref decl, ref header, ref generics, ref body) => {
30713101 let fn_def_id = self . resolver . definitions ( ) . local_def_id ( id) ;
30723102 self . with_new_scopes ( |this| {
3073- // Note: we don't need to change the return type from `T` to
3074- // `impl Future<Output = T>` here because lower_body
3075- // only cares about the input argument patterns in the function
3076- // declaration (decl), not the return types.
3077- let body_id = this. lower_async_body ( decl, & header. asyncness . node , body) ;
3103+ let mut lower_fn = |decl : & FnDecl | {
3104+ // Note: we don't need to change the return type from `T` to
3105+ // `impl Future<Output = T>` here because lower_body
3106+ // only cares about the input argument patterns in the function
3107+ // declaration (decl), not the return types.
3108+ let body_id = this. lower_async_body ( & decl, & header. asyncness . node , body) ;
3109+
3110+ let ( generics, fn_decl) = this. add_in_band_defs (
3111+ generics,
3112+ fn_def_id,
3113+ AnonymousLifetimeMode :: PassThrough ,
3114+ |this, idty| this. lower_fn_decl (
3115+ & decl,
3116+ Some ( ( fn_def_id, idty) ) ,
3117+ true ,
3118+ header. asyncness . node . opt_return_id ( )
3119+ ) ,
3120+ ) ;
30783121
3079- let ( generics, fn_decl) = this. add_in_band_defs (
3080- generics,
3081- fn_def_id,
3082- AnonymousLifetimeMode :: PassThrough ,
3083- |this, idty| this. lower_fn_decl (
3084- decl,
3085- Some ( ( fn_def_id, idty) ) ,
3086- true ,
3087- header. asyncness . node . opt_return_id ( )
3088- ) ,
3089- ) ;
3122+ ( body_id, generics, fn_decl)
3123+ } ;
3124+
3125+ let ( body_id, generics, fn_decl) = if let IsAsync :: Async {
3126+ arguments, ..
3127+ } = & header. asyncness . node {
3128+ let mut decl = decl. clone ( ) ;
3129+ // Replace the arguments of this async function with the generated
3130+ // arguments that will be moved into the closure.
3131+ decl. inputs = arguments. clone ( ) . drain ( ..) . map ( |a| a. arg ) . collect ( ) ;
3132+ lower_fn ( & decl)
3133+ } else {
3134+ lower_fn ( decl)
3135+ } ;
30903136
30913137 hir:: ItemKind :: Fn (
30923138 fn_decl,
0 commit comments