@@ -49,7 +49,7 @@ use rustc_errors::ErrorGuaranteed;
49
49
use rustc_hir as hir;
50
50
use rustc_hir:: def_id:: DefId ;
51
51
use rustc_middle:: span_bug;
52
- use rustc_middle:: ty:: ResolverAstLowering ;
52
+ use rustc_middle:: ty:: { Asyncness , ResolverAstLowering } ;
53
53
use rustc_span:: { symbol:: Ident , Span } ;
54
54
use rustc_target:: spec:: abi;
55
55
use std:: iter;
@@ -67,7 +67,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
67
67
return false ;
68
68
} ;
69
69
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
71
71
} else {
72
72
match self . tcx . def_kind ( sig_id) {
73
73
DefKind :: Fn => false ,
@@ -82,13 +82,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
82
82
delegation : & Delegation ,
83
83
item_id : NodeId ,
84
84
) -> 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 ) ;
86
86
let sig_id = self . get_delegation_sig_id ( item_id, delegation. id , span) ;
87
87
match sig_id {
88
88
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) ;
92
93
93
94
let generics = self . lower_delegation_generics ( span) ;
94
95
DelegationResults { body_id, sig, generics }
@@ -123,70 +124,93 @@ impl<'hir> LoweringContext<'_, 'hir> {
123
124
} )
124
125
}
125
126
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
+
126
142
fn lower_delegation_decl (
127
143
& mut self ,
128
144
sig_id : DefId ,
129
- param_span : Span ,
145
+ param_count : usize ,
146
+ c_variadic : bool ,
147
+ span : Span ,
130
148
) -> & ' 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 {
139
153
hir_id : self . next_id ( ) ,
140
154
kind : hir:: TyKind :: InferDelegation ( sig_id, hir:: InferDelegationKind :: Input ( arg) ) ,
141
- span : self . lower_span ( param_span ) ,
155
+ span,
142
156
} ) ) ;
143
157
144
158
let output = self . arena . alloc ( hir:: Ty {
145
159
hir_id : self . next_id ( ) ,
146
160
kind : hir:: TyKind :: InferDelegation ( sig_id, hir:: InferDelegationKind :: Output ) ,
147
- span : self . lower_span ( param_span ) ,
161
+ span,
148
162
} ) ;
149
163
150
164
self . arena . alloc ( hir:: FnDecl {
151
165
inputs,
152
166
output : hir:: FnRetTy :: Return ( output) ,
153
- c_variadic : false ,
167
+ c_variadic,
154
168
lifetime_elision_allowed : true ,
155
169
implicit_self : hir:: ImplicitSelfKind :: None ,
156
170
} )
157
171
}
158
172
159
173
fn lower_delegation_sig (
160
174
& mut self ,
161
- span : Span ,
175
+ sig_id : DefId ,
162
176
decl : & ' hir hir:: FnDecl < ' hir > ,
177
+ span : Span ,
163
178
) -> 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 }
174
198
}
175
199
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 ) {
177
201
let pat_node_id = self . next_node_id ( ) ;
178
202
let pat_id = self . lower_node_id ( pat_node_id) ;
179
203
let pat = self . arena . alloc ( hir:: Pat {
180
204
hir_id : pat_id,
181
205
kind : hir:: PatKind :: Binding ( hir:: BindingMode :: NONE , pat_id, Ident :: empty ( ) , None ) ,
182
- span : ty . span ,
206
+ span,
183
207
default_binding_modes : false ,
184
208
} ) ;
185
209
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)
187
211
}
188
212
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 > {
190
214
let segments = self . arena . alloc_from_iter ( iter:: once ( hir:: PathSegment {
191
215
ident : Ident :: empty ( ) ,
192
216
hir_id : self . next_id ( ) ,
@@ -195,20 +219,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
195
219
infer_args : false ,
196
220
} ) ) ;
197
221
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 } ) ;
200
223
201
224
hir:: Expr {
202
225
hir_id : self . next_id ( ) ,
203
226
kind : hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) ,
204
- span : ty . span ,
227
+ span,
205
228
}
206
229
}
207
230
208
231
fn lower_delegation_body (
209
232
& mut self ,
210
- decl : & ' hir hir:: FnDecl < ' hir > ,
211
233
delegation : & Delegation ,
234
+ param_count : usize ,
235
+ span : Span ,
212
236
) -> BodyId {
213
237
let path = self . lower_qpath (
214
238
delegation. id ,
@@ -224,8 +248,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
224
248
let mut parameters: Vec < hir:: Param < ' _ > > = Vec :: new ( ) ;
225
249
let mut args: Vec < hir:: Expr < ' hir > > = Vec :: new ( ) ;
226
250
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 ) ;
229
253
parameters. push ( param) ;
230
254
231
255
let arg = if let Some ( block) = block
@@ -245,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
245
269
}
246
270
} else {
247
271
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 )
249
273
} ;
250
274
args. push ( arg) ;
251
275
}
@@ -304,14 +328,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
304
328
implicit_self : hir:: ImplicitSelfKind :: None ,
305
329
} ) ;
306
330
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
+
308
334
let body_id = self . lower_body ( |this| {
309
335
let expr =
310
336
hir:: Expr { hir_id : this. next_id ( ) , kind : hir:: ExprKind :: Err ( err) , span : span } ;
311
337
( & [ ] , expr)
312
338
} ) ;
313
339
DelegationResults { generics, body_id, sig }
314
340
}
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
+ }
315
350
}
316
351
317
352
struct SelfResolver < ' a > {
0 commit comments