@@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
62
62
sp,
63
63
expr,
64
64
& err_inputs,
65
- & [ ] ,
65
+ vec ! [ ] ,
66
66
args_no_rcvr,
67
67
false ,
68
68
tuple_arguments,
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
83
83
sp,
84
84
expr,
85
85
& method. sig . inputs ( ) [ 1 ..] ,
86
- & expected_input_tys[ .. ] ,
86
+ expected_input_tys,
87
87
args_no_rcvr,
88
88
method. sig . c_variadic ,
89
89
tuple_arguments,
@@ -103,7 +103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
103
103
// Types (as defined in the *signature* of the target function)
104
104
formal_input_tys : & [ Ty < ' tcx > ] ,
105
105
// More specific expected types, after unifying with caller output types
106
- expected_input_tys : & [ Ty < ' tcx > ] ,
106
+ expected_input_tys : Vec < Ty < ' tcx > > ,
107
107
// The expressions for each provided argument
108
108
provided_args : & ' tcx [ hir:: Expr < ' tcx > ] ,
109
109
// Whether the function is variadic, for example when imported from C
@@ -249,25 +249,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
249
249
err. emit ( ) ;
250
250
} ;
251
251
252
- let mut expected_input_tys = expected_input_tys. to_vec ( ) ;
253
-
254
- let formal_input_tys = if tuple_arguments == TupleArguments {
252
+ let ( formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
255
253
let tuple_type = self . structurally_resolved_type ( call_span, formal_input_tys[ 0 ] ) ;
256
254
match tuple_type. kind ( ) {
257
255
ty:: Tuple ( arg_types) if arg_types. len ( ) != provided_args. len ( ) => {
258
256
param_count_error ( arg_types. len ( ) , provided_args. len ( ) , "E0057" , false , false ) ;
259
- expected_input_tys = vec ! [ ] ;
260
- self . err_args ( provided_args. len ( ) )
257
+ ( self . err_args ( provided_args. len ( ) ) , vec ! [ ] )
261
258
}
262
259
ty:: Tuple ( arg_types) => {
263
- expected_input_tys = match expected_input_tys. get ( 0 ) {
260
+ let expected_input_tys = match expected_input_tys. get ( 0 ) {
264
261
Some ( & ty) => match ty. kind ( ) {
265
262
ty:: Tuple ( ref tys) => tys. iter ( ) . map ( |k| k. expect_ty ( ) ) . collect ( ) ,
266
263
_ => vec ! [ ] ,
267
264
} ,
268
265
None => vec ! [ ] ,
269
266
} ;
270
- arg_types. iter ( ) . map ( |k| k. expect_ty ( ) ) . collect ( )
267
+ ( arg_types. iter ( ) . map ( |k| k. expect_ty ( ) ) . collect ( ) , expected_input_tys )
271
268
}
272
269
_ => {
273
270
struct_span_err ! (
@@ -278,19 +275,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
278
275
for the function trait is neither a tuple nor unit"
279
276
)
280
277
. emit ( ) ;
281
- expected_input_tys = vec ! [ ] ;
282
- self . err_args ( provided_args. len ( ) )
278
+ ( self . err_args ( provided_args. len ( ) ) , vec ! [ ] )
283
279
}
284
280
}
285
281
} else if expected_arg_count == supplied_arg_count {
286
- formal_input_tys. to_vec ( )
282
+ ( formal_input_tys. to_vec ( ) , expected_input_tys )
287
283
} else if c_variadic {
288
284
if supplied_arg_count >= expected_arg_count {
289
- formal_input_tys. to_vec ( )
285
+ ( formal_input_tys. to_vec ( ) , expected_input_tys )
290
286
} else {
291
287
param_count_error ( expected_arg_count, supplied_arg_count, "E0060" , true , false ) ;
292
- expected_input_tys = vec ! [ ] ;
293
- self . err_args ( supplied_arg_count)
288
+ ( self . err_args ( supplied_arg_count) , vec ! [ ] )
294
289
}
295
290
} else {
296
291
// is the missing argument of type `()`?
@@ -303,8 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
303
298
} ;
304
299
param_count_error ( expected_arg_count, supplied_arg_count, "E0061" , false , sugg_unit) ;
305
300
306
- expected_input_tys = vec ! [ ] ;
307
- self . err_args ( supplied_arg_count)
301
+ ( self . err_args ( supplied_arg_count) , vec ! [ ] )
308
302
} ;
309
303
310
304
debug ! (
@@ -319,6 +313,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
319
313
formal_input_tys. clone ( )
320
314
} ;
321
315
316
+ assert_eq ! ( expected_input_tys. len( ) , formal_input_tys. len( ) ) ;
317
+
318
+ // Keep track of the fully coerced argument types
322
319
let mut final_arg_types: Vec < ( usize , Ty < ' _ > , Ty < ' _ > ) > = vec ! [ ] ;
323
320
324
321
// We introduce a helper function to demand that a given argument satisfy a given input
@@ -376,8 +373,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
376
373
// that we have more information about the types of arguments when we
377
374
// type-check the functions. This isn't really the right way to do this.
378
375
for check_closures in [ false , true ] {
379
- debug ! ( "check_closures={}" , check_closures) ;
380
-
381
376
// More awful hacks: before we check argument types, try to do
382
377
// an "opportunistic" trait resolution of any trait bounds on
383
378
// the call. This helps coercions.
@@ -394,31 +389,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
394
389
} )
395
390
}
396
391
397
- // For C-variadic functions, we don't have a declared type for all of
398
- // the arguments hence we only do our usual type checking with
399
- // the arguments who's types we do know.
400
- let t = if c_variadic {
401
- expected_arg_count
402
- } else if tuple_arguments == TupleArguments {
403
- provided_args. len ( )
404
- } else {
405
- supplied_arg_count
406
- } ;
407
- for ( i, arg) in provided_args. iter ( ) . take ( t) . enumerate ( ) {
392
+ let minimum_input_count = formal_input_tys. len ( ) ;
393
+ for ( idx, arg) in provided_args. iter ( ) . enumerate ( ) {
408
394
// Warn only for the first loop (the "no closures" one).
409
395
// Closure arguments themselves can't be diverging, but
410
396
// a previous argument can, e.g., `foo(panic!(), || {})`.
411
397
if !check_closures {
412
398
self . warn_if_unreachable ( arg. hir_id , arg. span , "expression" ) ;
413
399
}
414
400
415
- let is_closure = matches ! ( arg. kind, ExprKind :: Closure ( ..) ) ;
401
+ // For C-variadic functions, we don't have a declared type for all of
402
+ // the arguments hence we only do our usual type checking with
403
+ // the arguments who's types we do know. However, we *can* check
404
+ // for unreachable expressions (see above).
405
+ // FIXME: unreachable warning current isn't emitted
406
+ if idx >= minimum_input_count {
407
+ continue ;
408
+ }
416
409
410
+ let is_closure = matches ! ( arg. kind, ExprKind :: Closure ( ..) ) ;
417
411
if is_closure != check_closures {
418
412
continue ;
419
413
}
420
414
421
- demand_compatible ( i , & mut final_arg_types) ;
415
+ demand_compatible ( idx , & mut final_arg_types) ;
422
416
}
423
417
}
424
418
0 commit comments