@@ -96,34 +96,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
96
96
/// method calls and overloaded operators.
97
97
pub ( in super :: super ) fn check_argument_types (
98
98
& self ,
99
- sp : Span ,
100
- expr : & ' tcx hir:: Expr < ' tcx > ,
101
- fn_inputs : & [ Ty < ' tcx > ] ,
102
- expected_arg_tys : & [ Ty < ' tcx > ] ,
103
- args : & ' tcx [ hir:: Expr < ' tcx > ] ,
99
+ // Span enclosing the call site
100
+ call_span : Span ,
101
+ // Expression of the call site
102
+ call_expr : & ' tcx hir:: Expr < ' tcx > ,
103
+ // Types (as defined in the *signature* of the target function)
104
+ formal_input_tys : & [ Ty < ' tcx > ] ,
105
+ // More specific expected types, after unifying with caller output types
106
+ expected_input_tys : & [ Ty < ' tcx > ] ,
107
+ // The expressions for each provided argument
108
+ provided_args : & ' tcx [ hir:: Expr < ' tcx > ] ,
109
+ // Whether the function is variadic, for example when imported from C
104
110
c_variadic : bool ,
111
+ // Whether the arguments have been bundled in a tuple (ex: closures)
105
112
tuple_arguments : TupleArgumentsFlag ,
106
- def_id : Option < DefId > ,
113
+ // The DefId for the function being called, for better error messages
114
+ fn_def_id : Option < DefId > ,
107
115
) {
108
116
let tcx = self . tcx ;
109
117
// Grab the argument types, supplying fresh type variables
110
118
// if the wrong number of arguments were supplied
111
- let supplied_arg_count = if tuple_arguments == DontTupleArguments { args. len ( ) } else { 1 } ;
119
+ let supplied_arg_count =
120
+ if tuple_arguments == DontTupleArguments { provided_args. len ( ) } else { 1 } ;
112
121
113
122
// All the input types from the fn signature must outlive the call
114
123
// so as to validate implied bounds.
115
- for ( & fn_input_ty, arg_expr) in iter:: zip ( fn_inputs , args ) {
124
+ for ( & fn_input_ty, arg_expr) in iter:: zip ( formal_input_tys , provided_args ) {
116
125
self . register_wf_obligation ( fn_input_ty. into ( ) , arg_expr. span , traits:: MiscObligation ) ;
117
126
}
118
127
119
- let expected_arg_count = fn_inputs . len ( ) ;
128
+ let expected_arg_count = formal_input_tys . len ( ) ;
120
129
121
130
let param_count_error = |expected_count : usize ,
122
131
arg_count : usize ,
123
132
error_code : & str ,
124
133
c_variadic : bool ,
125
134
sugg_unit : bool | {
126
- let ( span, start_span, args, ctor_of) = match & expr . kind {
135
+ let ( span, start_span, args, ctor_of) = match & call_expr . kind {
127
136
hir:: ExprKind :: Call (
128
137
hir:: Expr {
129
138
span,
@@ -156,14 +165,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
156
165
& args[ 1 ..] , // Skip the receiver.
157
166
None , // methods are never ctors
158
167
) ,
159
- k => span_bug ! ( sp , "checking argument types on a non-call: `{:?}`" , k) ,
168
+ k => span_bug ! ( call_span , "checking argument types on a non-call: `{:?}`" , k) ,
160
169
} ;
161
- let arg_spans = if args . is_empty ( ) {
170
+ let arg_spans = if provided_args . is_empty ( ) {
162
171
// foo()
163
172
// ^^^-- supplied 0 arguments
164
173
// |
165
174
// expected 2 arguments
166
- vec ! [ tcx. sess. source_map( ) . next_point( start_span) . with_hi( sp . hi( ) ) ]
175
+ vec ! [ tcx. sess. source_map( ) . next_point( start_span) . with_hi( call_span . hi( ) ) ]
167
176
} else {
168
177
// foo(1, 2, 3)
169
178
// ^^^ - - - supplied 3 arguments
@@ -196,7 +205,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
196
205
) ;
197
206
}
198
207
199
- if let Some ( def_id) = def_id {
208
+ if let Some ( def_id) = fn_def_id {
200
209
if let Some ( def_span) = tcx. def_ident_span ( def_id) {
201
210
let mut spans: MultiSpan = def_span. into ( ) ;
202
211
@@ -218,7 +227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
218
227
}
219
228
220
229
if sugg_unit {
221
- let sugg_span = tcx. sess . source_map ( ) . end_point ( expr . span ) ;
230
+ let sugg_span = tcx. sess . source_map ( ) . end_point ( call_expr . span ) ;
222
231
// remove closing `)` from the span
223
232
let sugg_span = sugg_span. shrink_to_lo ( ) ;
224
233
err. span_suggestion (
@@ -240,15 +249,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
240
249
err. emit ( ) ;
241
250
} ;
242
251
243
- let mut expected_arg_tys = expected_arg_tys . to_vec ( ) ;
252
+ let mut expected_arg_tys = expected_input_tys . to_vec ( ) ;
244
253
245
254
let formal_tys = if tuple_arguments == TupleArguments {
246
- let tuple_type = self . structurally_resolved_type ( sp , fn_inputs [ 0 ] ) ;
255
+ let tuple_type = self . structurally_resolved_type ( call_span , formal_input_tys [ 0 ] ) ;
247
256
match tuple_type. kind ( ) {
248
- ty:: Tuple ( arg_types) if arg_types. len ( ) != args . len ( ) => {
249
- param_count_error ( arg_types. len ( ) , args . len ( ) , "E0057" , false , false ) ;
257
+ ty:: Tuple ( arg_types) if arg_types. len ( ) != provided_args . len ( ) => {
258
+ param_count_error ( arg_types. len ( ) , provided_args . len ( ) , "E0057" , false , false ) ;
250
259
expected_arg_tys = vec ! [ ] ;
251
- self . err_args ( args . len ( ) )
260
+ self . err_args ( provided_args . len ( ) )
252
261
}
253
262
ty:: Tuple ( arg_types) => {
254
263
expected_arg_tys = match expected_arg_tys. get ( 0 ) {
@@ -263,21 +272,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
263
272
_ => {
264
273
struct_span_err ! (
265
274
tcx. sess,
266
- sp ,
275
+ call_span ,
267
276
E0059 ,
268
277
"cannot use call notation; the first type parameter \
269
278
for the function trait is neither a tuple nor unit"
270
279
)
271
280
. emit ( ) ;
272
281
expected_arg_tys = vec ! [ ] ;
273
- self . err_args ( args . len ( ) )
282
+ self . err_args ( provided_args . len ( ) )
274
283
}
275
284
}
276
285
} else if expected_arg_count == supplied_arg_count {
277
- fn_inputs . to_vec ( )
286
+ formal_input_tys . to_vec ( )
278
287
} else if c_variadic {
279
288
if supplied_arg_count >= expected_arg_count {
280
- fn_inputs . to_vec ( )
289
+ formal_input_tys . to_vec ( )
281
290
} else {
282
291
param_count_error ( expected_arg_count, supplied_arg_count, "E0060" , true , false ) ;
283
292
expected_arg_tys = vec ! [ ] ;
@@ -287,8 +296,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
287
296
// is the missing argument of type `()`?
288
297
let sugg_unit = if expected_arg_tys. len ( ) == 1 && supplied_arg_count == 0 {
289
298
self . resolve_vars_if_possible ( expected_arg_tys[ 0 ] ) . is_unit ( )
290
- } else if fn_inputs . len ( ) == 1 && supplied_arg_count == 0 {
291
- self . resolve_vars_if_possible ( fn_inputs [ 0 ] ) . is_unit ( )
299
+ } else if formal_input_tys . len ( ) == 1 && supplied_arg_count == 0 {
300
+ self . resolve_vars_if_possible ( formal_input_tys [ 0 ] ) . is_unit ( )
292
301
} else {
293
302
false
294
303
} ;
@@ -322,13 +331,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
322
331
// the call. This helps coercions.
323
332
if check_closures {
324
333
self . select_obligations_where_possible ( false , |errors| {
325
- self . point_at_type_arg_instead_of_call_if_possible ( errors, expr ) ;
334
+ self . point_at_type_arg_instead_of_call_if_possible ( errors, call_expr ) ;
326
335
self . point_at_arg_instead_of_call_if_possible (
327
336
errors,
328
337
& final_arg_types,
329
- expr ,
330
- sp ,
331
- & args ,
338
+ call_expr ,
339
+ call_span ,
340
+ & provided_args ,
332
341
) ;
333
342
} )
334
343
}
@@ -339,11 +348,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339
348
let t = if c_variadic {
340
349
expected_arg_count
341
350
} else if tuple_arguments == TupleArguments {
342
- args . len ( )
351
+ provided_args . len ( )
343
352
} else {
344
353
supplied_arg_count
345
354
} ;
346
- for ( i, arg) in args . iter ( ) . take ( t) . enumerate ( ) {
355
+ for ( i, arg) in provided_args . iter ( ) . take ( t) . enumerate ( ) {
347
356
// Warn only for the first loop (the "no closures" one).
348
357
// Closure arguments themselves can't be diverging, but
349
358
// a previous argument can, e.g., `foo(panic!(), || {})`.
@@ -380,13 +389,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
380
389
let _ = self . resolve_vars_with_obligations_and_mutate_fulfillment (
381
390
coerce_ty,
382
391
|errors| {
383
- self . point_at_type_arg_instead_of_call_if_possible ( errors, expr ) ;
392
+ self . point_at_type_arg_instead_of_call_if_possible ( errors, call_expr ) ;
384
393
self . point_at_arg_instead_of_call_if_possible (
385
394
errors,
386
395
& final_arg_types,
387
- expr ,
388
- sp ,
389
- args ,
396
+ call_expr ,
397
+ call_span ,
398
+ provided_args ,
390
399
) ;
391
400
} ,
392
401
) ;
@@ -410,7 +419,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
410
419
MissingCastForVariadicArg { sess, span, ty, cast_ty } . diagnostic ( ) . emit ( )
411
420
}
412
421
413
- for arg in args . iter ( ) . skip ( expected_arg_count) {
422
+ for arg in provided_args . iter ( ) . skip ( expected_arg_count) {
414
423
let arg_ty = self . check_expr ( & arg) ;
415
424
416
425
// There are a few types which get autopromoted when passed via varargs
0 commit comments