@@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6262 sp,
6363 expr,
6464 & err_inputs,
65- & [ ] ,
65+ vec ! [ ] ,
6666 args_no_rcvr,
6767 false ,
6868 tuple_arguments,
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8383 sp,
8484 expr,
8585 & method. sig . inputs ( ) [ 1 ..] ,
86- & expected_input_tys[ .. ] ,
86+ expected_input_tys,
8787 args_no_rcvr,
8888 method. sig . c_variadic ,
8989 tuple_arguments,
@@ -103,7 +103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
103103 // Types (as defined in the *signature* of the target function)
104104 formal_input_tys : & [ Ty < ' tcx > ] ,
105105 // More specific expected types, after unifying with caller output types
106- expected_input_tys : & [ Ty < ' tcx > ] ,
106+ expected_input_tys : Vec < Ty < ' tcx > > ,
107107 // The expressions for each provided argument
108108 provided_args : & ' tcx [ hir:: Expr < ' tcx > ] ,
109109 // Whether the function is variadic, for example when imported from C
@@ -249,25 +249,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
249249 err. emit ( ) ;
250250 } ;
251251
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 {
255253 let tuple_type = self . structurally_resolved_type ( call_span, formal_input_tys[ 0 ] ) ;
256254 match tuple_type. kind ( ) {
257255 ty:: Tuple ( arg_types) if arg_types. len ( ) != provided_args. len ( ) => {
258256 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 ! [ ] )
261258 }
262259 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 ) {
264261 Some ( & ty) => match ty. kind ( ) {
265262 ty:: Tuple ( ref tys) => tys. iter ( ) . map ( |k| k. expect_ty ( ) ) . collect ( ) ,
266263 _ => vec ! [ ] ,
267264 } ,
268265 None => vec ! [ ] ,
269266 } ;
270- arg_types. iter ( ) . map ( |k| k. expect_ty ( ) ) . collect ( )
267+ ( arg_types. iter ( ) . map ( |k| k. expect_ty ( ) ) . collect ( ) , expected_input_tys )
271268 }
272269 _ => {
273270 struct_span_err ! (
@@ -278,19 +275,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
278275 for the function trait is neither a tuple nor unit"
279276 )
280277 . emit ( ) ;
281- expected_input_tys = vec ! [ ] ;
282- self . err_args ( provided_args. len ( ) )
278+ ( self . err_args ( provided_args. len ( ) ) , vec ! [ ] )
283279 }
284280 }
285281 } else if expected_arg_count == supplied_arg_count {
286- formal_input_tys. to_vec ( )
282+ ( formal_input_tys. to_vec ( ) , expected_input_tys )
287283 } else if c_variadic {
288284 if supplied_arg_count >= expected_arg_count {
289- formal_input_tys. to_vec ( )
285+ ( formal_input_tys. to_vec ( ) , expected_input_tys )
290286 } else {
291287 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 ! [ ] )
294289 }
295290 } else {
296291 // is the missing argument of type `()`?
@@ -303,8 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
303298 } ;
304299 param_count_error ( expected_arg_count, supplied_arg_count, "E0061" , false , sugg_unit) ;
305300
306- expected_input_tys = vec ! [ ] ;
307- self . err_args ( supplied_arg_count)
301+ ( self . err_args ( supplied_arg_count) , vec ! [ ] )
308302 } ;
309303
310304 debug ! (
@@ -319,6 +313,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
319313 formal_input_tys. clone ( )
320314 } ;
321315
316+ assert_eq ! ( expected_input_tys. len( ) , formal_input_tys. len( ) ) ;
317+
318+ // Keep track of the fully coerced argument types
322319 let mut final_arg_types: Vec < ( usize , Ty < ' _ > , Ty < ' _ > ) > = vec ! [ ] ;
323320
324321 // 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> {
376373 // that we have more information about the types of arguments when we
377374 // type-check the functions. This isn't really the right way to do this.
378375 for check_closures in [ false , true ] {
379- debug ! ( "check_closures={}" , check_closures) ;
380-
381376 // More awful hacks: before we check argument types, try to do
382377 // an "opportunistic" trait resolution of any trait bounds on
383378 // the call. This helps coercions.
@@ -394,31 +389,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
394389 } )
395390 }
396391
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 ( ) {
408394 // Warn only for the first loop (the "no closures" one).
409395 // Closure arguments themselves can't be diverging, but
410396 // a previous argument can, e.g., `foo(panic!(), || {})`.
411397 if !check_closures {
412398 self . warn_if_unreachable ( arg. hir_id , arg. span , "expression" ) ;
413399 }
414400
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+ }
416409
410+ let is_closure = matches ! ( arg. kind, ExprKind :: Closure ( ..) ) ;
417411 if is_closure != check_closures {
418412 continue ;
419413 }
420414
421- demand_compatible ( i , & mut final_arg_types) ;
415+ demand_compatible ( idx , & mut final_arg_types) ;
422416 }
423417 }
424418
0 commit comments