@@ -49,7 +49,7 @@ use rustc_errors::ErrorGuaranteed;
4949use  rustc_hir as  hir; 
5050use  rustc_hir:: def_id:: DefId ; 
5151use  rustc_middle:: span_bug; 
52- use  rustc_middle:: ty:: ResolverAstLowering ; 
52+ use  rustc_middle:: ty:: { Asyncness ,   ResolverAstLowering } ; 
5353use  rustc_span:: { symbol:: Ident ,  Span } ; 
5454use  rustc_target:: spec:: abi; 
5555use  std:: iter; 
@@ -67,7 +67,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
6767            return  false ; 
6868        } ; 
6969        if  let  Some ( local_sig_id)  = sig_id. as_local ( )  { 
70-             self . resolver . has_self . contains ( & local_sig_id) 
70+             self . resolver . delegation_fn_sigs [ & local_sig_id] . has_self 
7171        }  else  { 
7272            match  self . tcx . def_kind ( sig_id)  { 
7373                DefKind :: Fn  => false , 
@@ -82,13 +82,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
8282        delegation :  & Delegation , 
8383        item_id :  NodeId , 
8484    )  -> DelegationResults < ' hir >  { 
85-         let  span = delegation. path . segments . last ( ) . unwrap ( ) . ident . span ; 
85+         let  span = self . lower_span ( delegation. path . segments . last ( ) . unwrap ( ) . ident . span ) ; 
8686        let  sig_id = self . get_delegation_sig_id ( item_id,  delegation. id ,  span) ; 
8787        match  sig_id { 
8888            Ok ( sig_id)  => { 
89-                 let  decl = self . lower_delegation_decl ( sig_id,  span) ; 
90-                 let  sig = self . lower_delegation_sig ( span,  decl) ; 
91-                 let  body_id = self . lower_delegation_body ( sig. decl ,  delegation) ; 
89+                 let  ( param_count,  c_variadic)  = self . param_count ( sig_id) ; 
90+                 let  decl = self . lower_delegation_decl ( sig_id,  param_count,  c_variadic,  span) ; 
91+                 let  sig = self . lower_delegation_sig ( sig_id,  decl,  span) ; 
92+                 let  body_id = self . lower_delegation_body ( delegation,  param_count,  span) ; 
9293
9394                let  generics = self . lower_delegation_generics ( span) ; 
9495                DelegationResults  {  body_id,  sig,  generics } 
@@ -123,70 +124,93 @@ impl<'hir> LoweringContext<'_, 'hir> {
123124        } ) 
124125    } 
125126
127+     // Function parameter count, including C variadic `...` if present. 
128+     fn  param_count ( & self ,  sig_id :  DefId )  -> ( usize ,  bool  /*c_variadic*/ )  { 
129+         if  let  Some ( local_sig_id)  = sig_id. as_local ( )  { 
130+             // Map may be filled incorrectly due to recursive delegation. 
131+             // Error will be emmited later during HIR ty lowering. 
132+             match  self . resolver . delegation_fn_sigs . get ( & local_sig_id)  { 
133+                 Some ( sig)  => ( sig. param_count ,  sig. c_variadic ) , 
134+                 None  => ( 0 ,  false ) , 
135+             } 
136+         }  else  { 
137+             let  sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ; 
138+             ( sig. inputs ( ) . len ( )  + usize:: from ( sig. c_variadic ) ,  sig. c_variadic ) 
139+         } 
140+     } 
141+ 
126142    fn  lower_delegation_decl ( 
127143        & mut  self , 
128144        sig_id :  DefId , 
129-         param_span :  Span , 
145+         param_count :  usize , 
146+         c_variadic :  bool , 
147+         span :  Span , 
130148    )  -> & ' hir  hir:: FnDecl < ' hir >  { 
131-         let  args_count = if  let  Some ( local_sig_id)  = sig_id. as_local ( )  { 
132-             // Map may be filled incorrectly due to recursive delegation. 
133-             // Error will be emitted later during HIR ty lowering. 
134-             self . resolver . fn_parameter_counts . get ( & local_sig_id) . cloned ( ) . unwrap_or_default ( ) 
135-         }  else  { 
136-             self . tcx . fn_arg_names ( sig_id) . len ( ) 
137-         } ; 
138-         let  inputs = self . arena . alloc_from_iter ( ( 0 ..args_count) . map ( |arg| hir:: Ty  { 
149+         // The last parameter in C variadic functions is skipped in the signature, 
150+         // like during regular lowering. 
151+         let  decl_param_count = param_count - c_variadic as  usize ; 
152+         let  inputs = self . arena . alloc_from_iter ( ( 0 ..decl_param_count) . map ( |arg| hir:: Ty  { 
139153            hir_id :  self . next_id ( ) , 
140154            kind :  hir:: TyKind :: InferDelegation ( sig_id,  hir:: InferDelegationKind :: Input ( arg) ) , 
141-             span :   self . lower_span ( param_span ) , 
155+             span, 
142156        } ) ) ; 
143157
144158        let  output = self . arena . alloc ( hir:: Ty  { 
145159            hir_id :  self . next_id ( ) , 
146160            kind :  hir:: TyKind :: InferDelegation ( sig_id,  hir:: InferDelegationKind :: Output ) , 
147-             span :   self . lower_span ( param_span ) , 
161+             span, 
148162        } ) ; 
149163
150164        self . arena . alloc ( hir:: FnDecl  { 
151165            inputs, 
152166            output :  hir:: FnRetTy :: Return ( output) , 
153-             c_variadic :   false , 
167+             c_variadic, 
154168            lifetime_elision_allowed :  true , 
155169            implicit_self :  hir:: ImplicitSelfKind :: None , 
156170        } ) 
157171    } 
158172
159173    fn  lower_delegation_sig ( 
160174        & mut  self , 
161-         span :   Span , 
175+         sig_id :   DefId , 
162176        decl :  & ' hir  hir:: FnDecl < ' hir > , 
177+         span :  Span , 
163178    )  -> hir:: FnSig < ' hir >  { 
164-         hir:: FnSig  { 
165-             decl, 
166-             header :  hir:: FnHeader  { 
167-                 unsafety :  hir:: Unsafety :: Normal , 
168-                 constness :  hir:: Constness :: NotConst , 
169-                 asyncness :  hir:: IsAsync :: NotAsync , 
170-                 abi :  abi:: Abi :: Rust , 
171-             } , 
172-             span :  self . lower_span ( span) , 
173-         } 
179+         let  header = if  let  Some ( local_sig_id)  = sig_id. as_local ( )  { 
180+             match  self . resolver . delegation_fn_sigs . get ( & local_sig_id)  { 
181+                 Some ( sig)  => self . lower_fn_header ( sig. header ) , 
182+                 None  => self . generate_header_error ( ) , 
183+             } 
184+         }  else  { 
185+             let  sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ; 
186+             let  asyncness = match  self . tcx . asyncness ( sig_id)  { 
187+                 Asyncness :: Yes  => hir:: IsAsync :: Async ( span) , 
188+                 Asyncness :: No  => hir:: IsAsync :: NotAsync , 
189+             } ; 
190+             hir:: FnHeader  { 
191+                 unsafety :  sig. unsafety , 
192+                 constness :  self . tcx . constness ( sig_id) , 
193+                 asyncness, 
194+                 abi :  sig. abi , 
195+             } 
196+         } ; 
197+         hir:: FnSig  {  decl,  header,  span } 
174198    } 
175199
176-     fn  generate_param ( & mut  self ,  ty :   & ' hir  hir :: Ty < ' hir > )  -> ( hir:: Param < ' hir > ,  NodeId )  { 
200+     fn  generate_param ( & mut  self ,  span :   Span )  -> ( hir:: Param < ' hir > ,  NodeId )  { 
177201        let  pat_node_id = self . next_node_id ( ) ; 
178202        let  pat_id = self . lower_node_id ( pat_node_id) ; 
179203        let  pat = self . arena . alloc ( hir:: Pat  { 
180204            hir_id :  pat_id, 
181205            kind :  hir:: PatKind :: Binding ( hir:: BindingMode :: NONE ,  pat_id,  Ident :: empty ( ) ,  None ) , 
182-             span :  ty . span , 
206+             span, 
183207            default_binding_modes :  false , 
184208        } ) ; 
185209
186-         ( hir:: Param  {  hir_id :  self . next_id ( ) ,  pat,  ty_span :  ty . span ,  span :  ty . span  } ,  pat_node_id) 
210+         ( hir:: Param  {  hir_id :  self . next_id ( ) ,  pat,  ty_span :  span,  span } ,  pat_node_id) 
187211    } 
188212
189-     fn  generate_arg ( & mut  self ,  ty :   & ' hir  hir :: Ty < ' hir > ,   param_id :   HirId )  -> hir:: Expr < ' hir >  { 
213+     fn  generate_arg ( & mut  self ,  param_id :   HirId ,   span :   Span )  -> hir:: Expr < ' hir >  { 
190214        let  segments = self . arena . alloc_from_iter ( iter:: once ( hir:: PathSegment  { 
191215            ident :  Ident :: empty ( ) , 
192216            hir_id :  self . next_id ( ) , 
@@ -195,20 +219,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
195219            infer_args :  false , 
196220        } ) ) ; 
197221
198-         let  path =
199-             self . arena . alloc ( hir:: Path  {  span :  ty. span ,  res :  Res :: Local ( param_id) ,  segments } ) ; 
222+         let  path = self . arena . alloc ( hir:: Path  {  span,  res :  Res :: Local ( param_id) ,  segments } ) ; 
200223
201224        hir:: Expr  { 
202225            hir_id :  self . next_id ( ) , 
203226            kind :  hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None ,  path) ) , 
204-             span :  ty . span , 
227+             span, 
205228        } 
206229    } 
207230
208231    fn  lower_delegation_body ( 
209232        & mut  self , 
210-         decl :  & ' hir  hir:: FnDecl < ' hir > , 
211233        delegation :  & Delegation , 
234+         param_count :  usize , 
235+         span :  Span , 
212236    )  -> BodyId  { 
213237        let  path = self . lower_qpath ( 
214238            delegation. id , 
@@ -224,8 +248,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
224248            let  mut  parameters:  Vec < hir:: Param < ' _ > >  = Vec :: new ( ) ; 
225249            let  mut  args:  Vec < hir:: Expr < ' hir > >  = Vec :: new ( ) ; 
226250
227-             for  ( idx,  param_ty )   in  decl . inputs . iter ( ) . enumerate ( )  { 
228-                 let  ( param,  pat_node_id)  = this. generate_param ( param_ty ) ; 
251+             for  idx  in  0 ..param_count  { 
252+                 let  ( param,  pat_node_id)  = this. generate_param ( span ) ; 
229253                parameters. push ( param) ; 
230254
231255                let  arg = if  let  Some ( block)  = block
@@ -245,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
245269                    } 
246270                }  else  { 
247271                    let  pat_hir_id = this. lower_node_id ( pat_node_id) ; 
248-                     this. generate_arg ( param_ty ,  pat_hir_id ) 
272+                     this. generate_arg ( pat_hir_id ,  span ) 
249273                } ; 
250274                args. push ( arg) ; 
251275            } 
@@ -304,14 +328,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
304328            implicit_self :  hir:: ImplicitSelfKind :: None , 
305329        } ) ; 
306330
307-         let  sig = self . lower_delegation_sig ( span,  decl) ; 
331+         let  header = self . generate_header_error ( ) ; 
332+         let  sig = hir:: FnSig  {  decl,  header,  span } ; 
333+ 
308334        let  body_id = self . lower_body ( |this| { 
309335            let  expr =
310336                hir:: Expr  {  hir_id :  this. next_id ( ) ,  kind :  hir:: ExprKind :: Err ( err) ,  span :  span } ; 
311337            ( & [ ] ,  expr) 
312338        } ) ; 
313339        DelegationResults  {  generics,  body_id,  sig } 
314340    } 
341+ 
342+     fn  generate_header_error ( & self )  -> hir:: FnHeader  { 
343+         hir:: FnHeader  { 
344+             unsafety :  hir:: Unsafety :: Normal , 
345+             constness :  hir:: Constness :: NotConst , 
346+             asyncness :  hir:: IsAsync :: NotAsync , 
347+             abi :  abi:: Abi :: Rust , 
348+         } 
349+     } 
315350} 
316351
317352struct  SelfResolver < ' a >  { 
0 commit comments