@@ -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,92 @@ impl<'hir> LoweringContext<'_, 'hir> {
123
124
} )
124
125
}
125
126
127
+ fn param_count ( & self , sig_id : DefId ) -> ( usize , bool /*c_variadic*/ ) {
128
+ if let Some ( local_sig_id) = sig_id. as_local ( ) {
129
+ // Map may be filled incorrectly due to recursive delegation.
130
+ // Error will be emmited later in astconv.
131
+ match self . resolver . delegation_fn_sigs . get ( & local_sig_id) {
132
+ Some ( sig) => ( sig. param_count , sig. c_variadic ) ,
133
+ None => ( 0 , false ) ,
134
+ }
135
+ } else {
136
+ let sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ;
137
+ ( sig. inputs ( ) . len ( ) , sig. c_variadic )
138
+ }
139
+ }
140
+
126
141
fn lower_delegation_decl (
127
142
& mut self ,
128
143
sig_id : DefId ,
129
- param_span : Span ,
144
+ param_count : usize ,
145
+ c_variadic : bool ,
146
+ span : Span ,
130
147
) -> & ' 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 {
148
+ // The last parameter in C variadic functions is skipped in the signature,
149
+ // like during regular lowering.
150
+ let decl_param_count = param_count - c_variadic as usize ;
151
+ let inputs = self . arena . alloc_from_iter ( ( 0 ..decl_param_count) . map ( |arg| hir:: Ty {
139
152
hir_id : self . next_id ( ) ,
140
153
kind : hir:: TyKind :: InferDelegation ( sig_id, hir:: InferDelegationKind :: Input ( arg) ) ,
141
- span : self . lower_span ( param_span ) ,
154
+ span,
142
155
} ) ) ;
143
156
144
157
let output = self . arena . alloc ( hir:: Ty {
145
158
hir_id : self . next_id ( ) ,
146
159
kind : hir:: TyKind :: InferDelegation ( sig_id, hir:: InferDelegationKind :: Output ) ,
147
- span : self . lower_span ( param_span ) ,
160
+ span,
148
161
} ) ;
149
162
150
163
self . arena . alloc ( hir:: FnDecl {
151
164
inputs,
152
165
output : hir:: FnRetTy :: Return ( output) ,
153
- c_variadic : false ,
166
+ c_variadic,
154
167
lifetime_elision_allowed : true ,
155
168
implicit_self : hir:: ImplicitSelfKind :: None ,
156
169
} )
157
170
}
158
171
159
172
fn lower_delegation_sig (
160
173
& mut self ,
161
- span : Span ,
174
+ sig_id : DefId ,
162
175
decl : & ' hir hir:: FnDecl < ' hir > ,
176
+ span : Span ,
163
177
) -> 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
- }
178
+ let header = if let Some ( local_sig_id) = sig_id. as_local ( ) {
179
+ match self . resolver . delegation_fn_sigs . get ( & local_sig_id) {
180
+ Some ( sig) => self . lower_fn_header ( sig. header ) ,
181
+ None => self . generate_header_error ( ) ,
182
+ }
183
+ } else {
184
+ let sig = self . tcx . fn_sig ( sig_id) . skip_binder ( ) . skip_binder ( ) ;
185
+ let asyncness = match self . tcx . asyncness ( sig_id) {
186
+ Asyncness :: Yes => hir:: IsAsync :: Async ( span) ,
187
+ Asyncness :: No => hir:: IsAsync :: NotAsync ,
188
+ } ;
189
+ hir:: FnHeader {
190
+ unsafety : sig. unsafety ,
191
+ constness : self . tcx . constness ( sig_id) ,
192
+ asyncness,
193
+ abi : sig. abi ,
194
+ }
195
+ } ;
196
+ hir:: FnSig { decl, header, span }
174
197
}
175
198
176
- fn generate_param ( & mut self , ty : & ' hir hir :: Ty < ' hir > ) -> ( hir:: Param < ' hir > , NodeId ) {
199
+ fn generate_param ( & mut self , span : Span ) -> ( hir:: Param < ' hir > , NodeId ) {
177
200
let pat_node_id = self . next_node_id ( ) ;
178
201
let pat_id = self . lower_node_id ( pat_node_id) ;
179
202
let pat = self . arena . alloc ( hir:: Pat {
180
203
hir_id : pat_id,
181
204
kind : hir:: PatKind :: Binding ( hir:: BindingAnnotation :: NONE , pat_id, Ident :: empty ( ) , None ) ,
182
- span : ty . span ,
205
+ span,
183
206
default_binding_modes : false ,
184
207
} ) ;
185
208
186
- ( hir:: Param { hir_id : self . next_id ( ) , pat, ty_span : ty . span , span : ty . span } , pat_node_id)
209
+ ( hir:: Param { hir_id : self . next_id ( ) , pat, ty_span : span, span } , pat_node_id)
187
210
}
188
211
189
- fn generate_arg ( & mut self , ty : & ' hir hir :: Ty < ' hir > , param_id : HirId ) -> hir:: Expr < ' hir > {
212
+ fn generate_arg ( & mut self , param_id : HirId , span : Span ) -> hir:: Expr < ' hir > {
190
213
let segments = self . arena . alloc_from_iter ( iter:: once ( hir:: PathSegment {
191
214
ident : Ident :: empty ( ) ,
192
215
hir_id : self . next_id ( ) ,
@@ -195,20 +218,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
195
218
infer_args : false ,
196
219
} ) ) ;
197
220
198
- let path =
199
- self . arena . alloc ( hir:: Path { span : ty. span , res : Res :: Local ( param_id) , segments } ) ;
221
+ let path = self . arena . alloc ( hir:: Path { span, res : Res :: Local ( param_id) , segments } ) ;
200
222
201
223
hir:: Expr {
202
224
hir_id : self . next_id ( ) ,
203
225
kind : hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) ,
204
- span : ty . span ,
226
+ span,
205
227
}
206
228
}
207
229
208
230
fn lower_delegation_body (
209
231
& mut self ,
210
- decl : & ' hir hir:: FnDecl < ' hir > ,
211
232
delegation : & Delegation ,
233
+ param_count : usize ,
234
+ span : Span ,
212
235
) -> BodyId {
213
236
let path = self . lower_qpath (
214
237
delegation. id ,
@@ -224,8 +247,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
224
247
let mut parameters: Vec < hir:: Param < ' _ > > = Vec :: new ( ) ;
225
248
let mut args: Vec < hir:: Expr < ' hir > > = Vec :: new ( ) ;
226
249
227
- for ( idx, param_ty ) in decl . inputs . iter ( ) . enumerate ( ) {
228
- let ( param, pat_node_id) = this. generate_param ( param_ty ) ;
250
+ for idx in 0 ..param_count {
251
+ let ( param, pat_node_id) = this. generate_param ( span ) ;
229
252
parameters. push ( param) ;
230
253
231
254
let arg = if let Some ( block) = block
@@ -245,7 +268,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
245
268
}
246
269
} else {
247
270
let pat_hir_id = this. lower_node_id ( pat_node_id) ;
248
- this. generate_arg ( param_ty , pat_hir_id )
271
+ this. generate_arg ( pat_hir_id , span )
249
272
} ;
250
273
args. push ( arg) ;
251
274
}
@@ -304,14 +327,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
304
327
implicit_self : hir:: ImplicitSelfKind :: None ,
305
328
} ) ;
306
329
307
- let sig = self . lower_delegation_sig ( span, decl) ;
330
+ let header = self . generate_header_error ( ) ;
331
+ let sig = hir:: FnSig { decl, header, span } ;
332
+
308
333
let body_id = self . lower_body ( |this| {
309
334
let expr =
310
335
hir:: Expr { hir_id : this. next_id ( ) , kind : hir:: ExprKind :: Err ( err) , span : span } ;
311
336
( & [ ] , expr)
312
337
} ) ;
313
338
DelegationResults { generics, body_id, sig }
314
339
}
340
+
341
+ fn generate_header_error ( & self ) -> hir:: FnHeader {
342
+ hir:: FnHeader {
343
+ unsafety : hir:: Unsafety :: Normal ,
344
+ constness : hir:: Constness :: NotConst ,
345
+ asyncness : hir:: IsAsync :: NotAsync ,
346
+ abi : abi:: Abi :: Rust ,
347
+ }
348
+ }
315
349
}
316
350
317
351
struct SelfResolver < ' a > {
0 commit comments