@@ -48,7 +48,7 @@ use rustc_errors::ErrorGuaranteed;
4848use rustc_hir as hir;
4949use rustc_hir:: def_id:: DefId ;
5050use rustc_middle:: span_bug;
51- use rustc_middle:: ty:: ResolverAstLowering ;
51+ use rustc_middle:: ty:: { Asyncness , ResolverAstLowering } ;
5252use rustc_span:: { symbol:: Ident , Span } ;
5353use rustc_target:: spec:: abi;
5454use std:: iter;
@@ -66,7 +66,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
6666 return false ;
6767 } ;
6868 if let Some ( local_sig_id) = sig_id. as_local ( ) {
69- self . resolver . has_self . contains ( & local_sig_id)
69+ self . resolver . delegation_fn_sigs [ & local_sig_id] . has_self
7070 } else {
7171 match self . tcx . def_kind ( sig_id) {
7272 DefKind :: Fn => false ,
@@ -81,13 +81,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
8181 delegation : & Delegation ,
8282 item_id : NodeId ,
8383 ) -> DelegationResults < ' hir > {
84- let span = delegation. path . segments . last ( ) . unwrap ( ) . ident . span ;
84+ let span = self . lower_span ( delegation. path . segments . last ( ) . unwrap ( ) . ident . span ) ;
8585 let sig_id = self . get_delegation_sig_id ( item_id, delegation. id , span) ;
8686 match sig_id {
8787 Ok ( sig_id) => {
88- let decl = self . lower_delegation_decl ( sig_id, span) ;
89- let sig = self . lower_delegation_sig ( span, decl) ;
90- let body_id = self . lower_delegation_body ( sig. decl , delegation) ;
88+ let ( param_count, c_variadic) = self . param_count ( sig_id) ;
89+ let decl = self . lower_delegation_decl ( sig_id, param_count, c_variadic, span) ;
90+ let sig = self . lower_delegation_sig ( sig_id, decl, span) ;
91+ let body_id = self . lower_delegation_body ( delegation, param_count, span) ;
9192
9293 let generics = self . lower_delegation_generics ( span) ;
9394 DelegationResults { body_id, sig, generics }
@@ -122,70 +123,92 @@ impl<'hir> LoweringContext<'_, 'hir> {
122123 } )
123124 }
124125
126+ fn param_count ( & self , sig_id : DefId ) -> ( usize , bool /*c_variadic*/ ) {
127+ if let Some ( local_sig_id) = sig_id. as_local ( ) {
128+ // Map may be filled incorrectly due to recursive delegation.
129+ // Error will be emmited later in astconv.
130+ match self . resolver . delegation_fn_sigs . get ( & local_sig_id) {
131+ Some ( sig) => ( sig. param_count , sig. c_variadic ) ,
132+ None => ( 0 , false ) ,
133+ }
134+ } else {
135+ let sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ;
136+ ( sig. inputs ( ) . len ( ) , sig. c_variadic )
137+ }
138+ }
139+
125140 fn lower_delegation_decl (
126141 & mut self ,
127142 sig_id : DefId ,
128- param_span : Span ,
143+ param_count : usize ,
144+ c_variadic : bool ,
145+ span : Span ,
129146 ) -> & ' hir hir:: FnDecl < ' hir > {
130- let args_count = if let Some ( local_sig_id) = sig_id. as_local ( ) {
131- // Map may be filled incorrectly due to recursive delegation.
132- // Error will be emmited later in astconv.
133- self . resolver . fn_parameter_counts . get ( & local_sig_id) . cloned ( ) . unwrap_or_default ( )
134- } else {
135- self . tcx . fn_arg_names ( sig_id) . len ( )
136- } ;
137- let inputs = self . arena . alloc_from_iter ( ( 0 ..args_count) . map ( |arg| hir:: Ty {
147+ // The last parameter in C variadic functions is skipped in the signature,
148+ // like during regular lowering.
149+ let decl_param_count = param_count - c_variadic as usize ;
150+ let inputs = self . arena . alloc_from_iter ( ( 0 ..decl_param_count) . map ( |arg| hir:: Ty {
138151 hir_id : self . next_id ( ) ,
139152 kind : hir:: TyKind :: InferDelegation ( sig_id, hir:: InferDelegationKind :: Input ( arg) ) ,
140- span : self . lower_span ( param_span ) ,
153+ span,
141154 } ) ) ;
142155
143156 let output = self . arena . alloc ( hir:: Ty {
144157 hir_id : self . next_id ( ) ,
145158 kind : hir:: TyKind :: InferDelegation ( sig_id, hir:: InferDelegationKind :: Output ) ,
146- span : self . lower_span ( param_span ) ,
159+ span,
147160 } ) ;
148161
149162 self . arena . alloc ( hir:: FnDecl {
150163 inputs,
151164 output : hir:: FnRetTy :: Return ( output) ,
152- c_variadic : false ,
165+ c_variadic,
153166 lifetime_elision_allowed : true ,
154167 implicit_self : hir:: ImplicitSelfKind :: None ,
155168 } )
156169 }
157170
158171 fn lower_delegation_sig (
159172 & mut self ,
160- span : Span ,
173+ sig_id : DefId ,
161174 decl : & ' hir hir:: FnDecl < ' hir > ,
175+ span : Span ,
162176 ) -> hir:: FnSig < ' hir > {
163- hir:: FnSig {
164- decl,
165- header : hir:: FnHeader {
166- unsafety : hir:: Unsafety :: Normal ,
167- constness : hir:: Constness :: NotConst ,
168- asyncness : hir:: IsAsync :: NotAsync ,
169- abi : abi:: Abi :: Rust ,
170- } ,
171- span : self . lower_span ( span) ,
172- }
177+ let header = if let Some ( local_sig_id) = sig_id. as_local ( ) {
178+ match self . resolver . delegation_fn_sigs . get ( & local_sig_id) {
179+ Some ( sig) => self . lower_fn_header ( sig. header ) ,
180+ None => self . generate_header_error ( ) ,
181+ }
182+ } else {
183+ let sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ;
184+ let asyncness = match self . tcx . asyncness ( sig_id) {
185+ Asyncness :: Yes => hir:: IsAsync :: Async ( span) ,
186+ Asyncness :: No => hir:: IsAsync :: NotAsync ,
187+ } ;
188+ hir:: FnHeader {
189+ unsafety : sig. unsafety ,
190+ constness : self . tcx . constness ( sig_id) ,
191+ asyncness,
192+ abi : sig. abi ,
193+ }
194+ } ;
195+ hir:: FnSig { decl, header, span }
173196 }
174197
175- fn generate_param ( & mut self , ty : & ' hir hir :: Ty < ' hir > ) -> ( hir:: Param < ' hir > , NodeId ) {
198+ fn generate_param ( & mut self , span : Span ) -> ( hir:: Param < ' hir > , NodeId ) {
176199 let pat_node_id = self . next_node_id ( ) ;
177200 let pat_id = self . lower_node_id ( pat_node_id) ;
178201 let pat = self . arena . alloc ( hir:: Pat {
179202 hir_id : pat_id,
180203 kind : hir:: PatKind :: Binding ( hir:: BindingAnnotation :: NONE , pat_id, Ident :: empty ( ) , None ) ,
181- span : ty . span ,
204+ span,
182205 default_binding_modes : false ,
183206 } ) ;
184207
185- ( hir:: Param { hir_id : self . next_id ( ) , pat, ty_span : ty . span , span : ty . span } , pat_node_id)
208+ ( hir:: Param { hir_id : self . next_id ( ) , pat, ty_span : span, span } , pat_node_id)
186209 }
187210
188- fn generate_arg ( & mut self , ty : & ' hir hir :: Ty < ' hir > , param_id : HirId ) -> hir:: Expr < ' hir > {
211+ fn generate_arg ( & mut self , param_id : HirId , span : Span ) -> hir:: Expr < ' hir > {
189212 let segments = self . arena . alloc_from_iter ( iter:: once ( hir:: PathSegment {
190213 ident : Ident :: empty ( ) ,
191214 hir_id : self . next_id ( ) ,
@@ -194,20 +217,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
194217 infer_args : false ,
195218 } ) ) ;
196219
197- let path =
198- self . arena . alloc ( hir:: Path { span : ty. span , res : Res :: Local ( param_id) , segments } ) ;
220+ let path = self . arena . alloc ( hir:: Path { span, res : Res :: Local ( param_id) , segments } ) ;
199221
200222 hir:: Expr {
201223 hir_id : self . next_id ( ) ,
202224 kind : hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) ,
203- span : ty . span ,
225+ span,
204226 }
205227 }
206228
207229 fn lower_delegation_body (
208230 & mut self ,
209- decl : & ' hir hir:: FnDecl < ' hir > ,
210231 delegation : & Delegation ,
232+ param_count : usize ,
233+ span : Span ,
211234 ) -> BodyId {
212235 let path = self . lower_qpath (
213236 delegation. id ,
@@ -223,8 +246,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
223246 let mut parameters: Vec < hir:: Param < ' _ > > = Vec :: new ( ) ;
224247 let mut args: Vec < hir:: Expr < ' hir > > = Vec :: new ( ) ;
225248
226- for ( idx, param_ty ) in decl . inputs . iter ( ) . enumerate ( ) {
227- let ( param, pat_node_id) = this. generate_param ( param_ty ) ;
249+ for idx in 0 ..param_count {
250+ let ( param, pat_node_id) = this. generate_param ( span ) ;
228251 parameters. push ( param) ;
229252
230253 let arg = if let Some ( block) = block
@@ -244,7 +267,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
244267 }
245268 } else {
246269 let pat_hir_id = this. lower_node_id ( pat_node_id) ;
247- this. generate_arg ( param_ty , pat_hir_id )
270+ this. generate_arg ( pat_hir_id , span )
248271 } ;
249272 args. push ( arg) ;
250273 }
@@ -303,14 +326,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
303326 implicit_self : hir:: ImplicitSelfKind :: None ,
304327 } ) ;
305328
306- let sig = self . lower_delegation_sig ( span, decl) ;
329+ let header = self . generate_header_error ( ) ;
330+ let sig = hir:: FnSig { decl, header, span } ;
331+
307332 let body_id = self . lower_body ( |this| {
308333 let expr =
309334 hir:: Expr { hir_id : this. next_id ( ) , kind : hir:: ExprKind :: Err ( err) , span : span } ;
310335 ( & [ ] , expr)
311336 } ) ;
312337 DelegationResults { generics, body_id, sig }
313338 }
339+
340+ fn generate_header_error ( & self ) -> hir:: FnHeader {
341+ hir:: FnHeader {
342+ unsafety : hir:: Unsafety :: Normal ,
343+ constness : hir:: Constness :: NotConst ,
344+ asyncness : hir:: IsAsync :: NotAsync ,
345+ abi : abi:: Abi :: Rust ,
346+ }
347+ }
314348}
315349
316350struct SelfResolver < ' a > {
0 commit comments