@@ -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,32 @@ 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+ if let ArgSource :: AsyncFn ( pat) = & arg. source { self . visit_pat ( pat) ; }
469+ self . visit_ty ( & arg. ty )
470+ }
471+ self . visit_fn_ret_ty ( & fd. output ) ;
472+
473+ match fk {
474+ visit:: FnKind :: ItemFn ( _, decl, _, body) => {
475+ self . visit_fn_header ( decl) ;
476+ self . visit_block ( body)
477+ } ,
478+ visit:: FnKind :: Method ( _, sig, _, body) => {
479+ self . visit_fn_header ( & sig. header ) ;
480+ self . visit_block ( body)
481+ } ,
482+ visit:: FnKind :: Closure ( body) => self . visit_expr ( body) ,
483+ }
484+ } else {
485+ visit:: walk_fn ( self , fk, fd, s)
486+ }
487+ }
488+
464489 fn visit_item ( & mut self , item : & ' lcx Item ) {
465490 let hir_id = self . lctx . allocate_hir_id_counter ( item. id ) . hir_id ;
466491
@@ -784,12 +809,10 @@ impl<'a> LoweringContext<'a> {
784809 } )
785810 }
786811
787- fn record_body ( & mut self , value : hir:: Expr , decl : Option < & FnDecl > ) -> hir:: BodyId {
812+ fn record_body ( & mut self , value : hir:: Expr , arguments : HirVec < hir :: Arg > ) -> hir:: BodyId {
788813 let body = hir:: Body {
789- arguments : decl. map_or ( hir_vec ! [ ] , |decl| {
790- decl. inputs . iter ( ) . map ( |x| self . lower_arg ( x) ) . collect ( )
791- } ) ,
792814 is_generator : self . is_generator ,
815+ arguments,
793816 value,
794817 } ;
795818 let id = body. id ( ) ;
@@ -1112,11 +1135,10 @@ impl<'a> LoweringContext<'a> {
11121135 capture_clause : CaptureBy ,
11131136 closure_node_id : NodeId ,
11141137 ret_ty : Option < & Ty > ,
1138+ span : Span ,
11151139 body : impl FnOnce ( & mut LoweringContext < ' _ > ) -> hir:: Expr ,
11161140 ) -> hir:: ExprKind {
11171141 let prev_is_generator = mem:: replace ( & mut self . is_generator , true ) ;
1118- let body_expr = body ( self ) ;
1119- let span = body_expr. span ;
11201142 let output = match ret_ty {
11211143 Some ( ty) => FunctionRetTy :: Ty ( P ( ty. clone ( ) ) ) ,
11221144 None => FunctionRetTy :: Default ( span) ,
@@ -1126,7 +1148,11 @@ impl<'a> LoweringContext<'a> {
11261148 output,
11271149 c_variadic : false
11281150 } ;
1129- let body_id = self . record_body ( body_expr, Some ( & decl) ) ;
1151+ // Lower the arguments before the body otherwise the body will call `lower_def` expecting
1152+ // the argument to have been assigned an id already.
1153+ let arguments = self . lower_args ( Some ( & decl) ) ;
1154+ let body_expr = body ( self ) ;
1155+ let body_id = self . record_body ( body_expr, arguments) ;
11301156 self . is_generator = prev_is_generator;
11311157
11321158 let capture_clause = self . lower_capture_clause ( capture_clause) ;
@@ -1157,8 +1183,9 @@ impl<'a> LoweringContext<'a> {
11571183 F : FnOnce ( & mut LoweringContext < ' _ > ) -> hir:: Expr ,
11581184 {
11591185 let prev = mem:: replace ( & mut self . is_generator , false ) ;
1186+ let arguments = self . lower_args ( decl) ;
11601187 let result = f ( self ) ;
1161- let r = self . record_body ( result, decl ) ;
1188+ let r = self . record_body ( result, arguments ) ;
11621189 self . is_generator = prev;
11631190 return r;
11641191 }
@@ -2224,22 +2251,41 @@ impl<'a> LoweringContext<'a> {
22242251 init : l. init . as_ref ( ) . map ( |e| P ( self . lower_expr ( e) ) ) ,
22252252 span : l. span ,
22262253 attrs : l. attrs . clone ( ) ,
2227- source : hir :: LocalSource :: Normal ,
2254+ source : self . lower_local_source ( l . source ) ,
22282255 } , ids)
22292256 }
22302257
2258+ fn lower_local_source ( & mut self , ls : LocalSource ) -> hir:: LocalSource {
2259+ match ls {
2260+ LocalSource :: Normal => hir:: LocalSource :: Normal ,
2261+ LocalSource :: AsyncFn => hir:: LocalSource :: AsyncFn ,
2262+ }
2263+ }
2264+
22312265 fn lower_mutability ( & mut self , m : Mutability ) -> hir:: Mutability {
22322266 match m {
22332267 Mutability :: Mutable => hir:: MutMutable ,
22342268 Mutability :: Immutable => hir:: MutImmutable ,
22352269 }
22362270 }
22372271
2272+ fn lower_args ( & mut self , decl : Option < & FnDecl > ) -> HirVec < hir:: Arg > {
2273+ decl. map_or ( hir_vec ! [ ] , |decl| decl. inputs . iter ( ) . map ( |x| self . lower_arg ( x) ) . collect ( ) )
2274+ }
2275+
22382276 fn lower_arg ( & mut self , arg : & Arg ) -> hir:: Arg {
22392277 let LoweredNodeId { node_id : _, hir_id } = self . lower_node_id ( arg. id ) ;
22402278 hir:: Arg {
22412279 hir_id,
22422280 pat : self . lower_pat ( & arg. pat ) ,
2281+ source : self . lower_arg_source ( & arg. source ) ,
2282+ }
2283+ }
2284+
2285+ fn lower_arg_source ( & mut self , source : & ArgSource ) -> hir:: ArgSource {
2286+ match source {
2287+ ArgSource :: Normal => hir:: ArgSource :: Normal ,
2288+ ArgSource :: AsyncFn ( pat) => hir:: ArgSource :: AsyncFn ( self . lower_pat ( pat) ) ,
22432289 }
22442290 }
22452291
@@ -2993,15 +3039,21 @@ impl<'a> LoweringContext<'a> {
29933039 fn lower_async_body (
29943040 & mut self ,
29953041 decl : & FnDecl ,
2996- asyncness : IsAsync ,
3042+ asyncness : & IsAsync ,
29973043 body : & Block ,
29983044 ) -> hir:: BodyId {
2999- self . lower_body ( Some ( decl) , |this| {
3000- if let IsAsync :: Async { closure_id, .. } = asyncness {
3045+ self . lower_body ( Some ( & decl) , |this| {
3046+ if let IsAsync :: Async { closure_id, ref arguments, .. } = asyncness {
3047+ let mut body = body. clone ( ) ;
3048+
3049+ for a in arguments. iter ( ) . rev ( ) {
3050+ body. stmts . insert ( 0 , a. stmt . clone ( ) ) ;
3051+ }
3052+
30013053 let async_expr = this. make_async_expr (
3002- CaptureBy :: Value , closure_id, None ,
3054+ CaptureBy :: Value , * closure_id, None , body . span ,
30033055 |this| {
3004- let body = this. lower_block ( body, false ) ;
3056+ let body = this. lower_block ( & body, false ) ;
30053057 this. expr_block ( body, ThinVec :: new ( ) )
30063058 } ) ;
30073059 this. expr ( body. span , async_expr, ThinVec :: new ( ) )
@@ -3060,26 +3112,42 @@ impl<'a> LoweringContext<'a> {
30603112 value
30613113 )
30623114 }
3063- ItemKind :: Fn ( ref decl, header, ref generics, ref body) => {
3115+ ItemKind :: Fn ( ref decl, ref header, ref generics, ref body) => {
30643116 let fn_def_id = self . resolver . definitions ( ) . local_def_id ( id) ;
30653117 self . with_new_scopes ( |this| {
3066- // Note: we don't need to change the return type from `T` to
3067- // `impl Future<Output = T>` here because lower_body
3068- // only cares about the input argument patterns in the function
3069- // declaration (decl), not the return types.
3070- let body_id = this. lower_async_body ( decl, header. asyncness . node , body) ;
3118+ let mut lower_fn = |decl : & FnDecl | {
3119+ // Note: we don't need to change the return type from `T` to
3120+ // `impl Future<Output = T>` here because lower_body
3121+ // only cares about the input argument patterns in the function
3122+ // declaration (decl), not the return types.
3123+ let body_id = this. lower_async_body ( & decl, & header. asyncness . node , body) ;
3124+
3125+ let ( generics, fn_decl) = this. add_in_band_defs (
3126+ generics,
3127+ fn_def_id,
3128+ AnonymousLifetimeMode :: PassThrough ,
3129+ |this, idty| this. lower_fn_decl (
3130+ & decl,
3131+ Some ( ( fn_def_id, idty) ) ,
3132+ true ,
3133+ header. asyncness . node . opt_return_id ( )
3134+ ) ,
3135+ ) ;
30713136
3072- let ( generics, fn_decl) = this. add_in_band_defs (
3073- generics,
3074- fn_def_id,
3075- AnonymousLifetimeMode :: PassThrough ,
3076- |this, idty| this. lower_fn_decl (
3077- decl,
3078- Some ( ( fn_def_id, idty) ) ,
3079- true ,
3080- header. asyncness . node . opt_return_id ( )
3081- ) ,
3082- ) ;
3137+ ( body_id, generics, fn_decl)
3138+ } ;
3139+
3140+ let ( body_id, generics, fn_decl) = if let IsAsync :: Async {
3141+ arguments, ..
3142+ } = & header. asyncness . node {
3143+ let mut decl = decl. clone ( ) ;
3144+ // Replace the arguments of this async function with the generated
3145+ // arguments that will be moved into the closure.
3146+ decl. inputs = arguments. clone ( ) . drain ( ..) . map ( |a| a. arg ) . collect ( ) ;
3147+ lower_fn ( & decl)
3148+ } else {
3149+ lower_fn ( decl)
3150+ } ;
30833151
30843152 hir:: ItemKind :: Fn (
30853153 fn_decl,
@@ -3558,15 +3626,33 @@ impl<'a> LoweringContext<'a> {
35583626 )
35593627 }
35603628 ImplItemKind :: Method ( ref sig, ref body) => {
3561- let body_id = self . lower_async_body ( & sig. decl , sig. header . asyncness . node , body) ;
3562- let impl_trait_return_allow = !self . is_in_trait_impl ;
3563- let ( generics, sig) = self . lower_method_sig (
3564- & i. generics ,
3565- sig,
3566- impl_item_def_id,
3567- impl_trait_return_allow,
3568- sig. header . asyncness . node . opt_return_id ( ) ,
3569- ) ;
3629+ let mut lower_method = |sig : & MethodSig | {
3630+ let body_id = self . lower_async_body (
3631+ & sig. decl , & sig. header . asyncness . node , body
3632+ ) ;
3633+ let impl_trait_return_allow = !self . is_in_trait_impl ;
3634+ let ( generics, sig) = self . lower_method_sig (
3635+ & i. generics ,
3636+ sig,
3637+ impl_item_def_id,
3638+ impl_trait_return_allow,
3639+ sig. header . asyncness . node . opt_return_id ( ) ,
3640+ ) ;
3641+ ( body_id, generics, sig)
3642+ } ;
3643+
3644+ let ( body_id, generics, sig) = if let IsAsync :: Async {
3645+ ref arguments, ..
3646+ } = sig. header . asyncness . node {
3647+ let mut sig = sig. clone ( ) ;
3648+ // Replace the arguments of this async function with the generated
3649+ // arguments that will be moved into the closure.
3650+ sig. decl . inputs = arguments. clone ( ) . drain ( ..) . map ( |a| a. arg ) . collect ( ) ;
3651+ lower_method ( & sig)
3652+ } else {
3653+ lower_method ( sig)
3654+ } ;
3655+
35703656 ( generics, hir:: ImplItemKind :: Method ( sig, body_id) )
35713657 }
35723658 ImplItemKind :: Type ( ref ty) => (
@@ -3760,7 +3846,7 @@ impl<'a> LoweringContext<'a> {
37603846 impl_trait_return_allow : bool ,
37613847 is_async : Option < NodeId > ,
37623848 ) -> ( hir:: Generics , hir:: MethodSig ) {
3763- let header = self . lower_fn_header ( sig. header ) ;
3849+ let header = self . lower_fn_header ( & sig. header ) ;
37643850 let ( generics, decl) = self . add_in_band_defs (
37653851 generics,
37663852 fn_def_id,
@@ -3782,10 +3868,10 @@ impl<'a> LoweringContext<'a> {
37823868 }
37833869 }
37843870
3785- fn lower_fn_header ( & mut self , h : FnHeader ) -> hir:: FnHeader {
3871+ fn lower_fn_header ( & mut self , h : & FnHeader ) -> hir:: FnHeader {
37863872 hir:: FnHeader {
37873873 unsafety : self . lower_unsafety ( h. unsafety ) ,
3788- asyncness : self . lower_asyncness ( h. asyncness . node ) ,
3874+ asyncness : self . lower_asyncness ( & h. asyncness . node ) ,
37893875 constness : self . lower_constness ( h. constness ) ,
37903876 abi : h. abi ,
37913877 }
@@ -3805,7 +3891,7 @@ impl<'a> LoweringContext<'a> {
38053891 }
38063892 }
38073893
3808- fn lower_asyncness ( & mut self , a : IsAsync ) -> hir:: IsAsync {
3894+ fn lower_asyncness ( & mut self , a : & IsAsync ) -> hir:: IsAsync {
38093895 match a {
38103896 IsAsync :: Async { .. } => hir:: IsAsync :: Async ,
38113897 IsAsync :: NotAsync => hir:: IsAsync :: NotAsync ,
@@ -4110,15 +4196,15 @@ impl<'a> LoweringContext<'a> {
41104196 hir:: MatchSource :: Normal ,
41114197 ) ,
41124198 ExprKind :: Async ( capture_clause, closure_node_id, ref block) => {
4113- self . make_async_expr ( capture_clause, closure_node_id, None , |this| {
4199+ self . make_async_expr ( capture_clause, closure_node_id, None , block . span , |this| {
41144200 this. with_new_scopes ( |this| {
41154201 let block = this. lower_block ( block, false ) ;
41164202 this. expr_block ( block, ThinVec :: new ( ) )
41174203 } )
41184204 } )
41194205 }
41204206 ExprKind :: Closure (
4121- capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
4207+ capture_clause, ref asyncness, movability, ref decl, ref body, fn_decl_span
41224208 ) => {
41234209 if let IsAsync :: Async { closure_id, .. } = asyncness {
41244210 let outer_decl = FnDecl {
@@ -4156,7 +4242,7 @@ impl<'a> LoweringContext<'a> {
41564242 Some ( & * * ty)
41574243 } else { None } ;
41584244 let async_body = this. make_async_expr (
4159- capture_clause, closure_id, async_ret_ty,
4245+ capture_clause, * closure_id, async_ret_ty, body . span ,
41604246 |this| {
41614247 this. with_new_scopes ( |this| this. lower_expr ( body) )
41624248 } ) ;
0 commit comments