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