@@ -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