@@ -2508,7 +2508,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25082508 sp : Span ,
25092509 expr_sp : Span ,
25102510 fn_inputs : & [ Ty < ' tcx > ] ,
2511- expected_arg_tys : & [ Ty < ' tcx > ] ,
2511+ mut expected_arg_tys : & [ Ty < ' tcx > ] ,
25122512 args : & ' gcx [ hir:: Expr ] ,
25132513 variadic : bool ,
25142514 tuple_arguments : TupleArgumentsFlag ,
@@ -2529,19 +2529,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25292529 self . register_wf_obligation ( fn_input_ty, sp, traits:: MiscObligation ) ;
25302530 }
25312531
2532- let mut expected_arg_tys = expected_arg_tys;
25332532 let expected_arg_count = fn_inputs. len ( ) ;
25342533
2535- fn parameter_count_error < ' tcx > ( sess : & Session ,
2536- sp : Span ,
2537- expr_sp : Span ,
2538- expected_count : usize ,
2539- arg_count : usize ,
2540- error_code : & str ,
2541- variadic : bool ,
2542- def_span : Option < Span > ,
2543- sugg_unit : bool ) {
2544- let mut err = sess. struct_span_err_with_code ( sp,
2534+ let param_count_error = |expected_count : usize ,
2535+ arg_count : usize ,
2536+ error_code : & str ,
2537+ variadic : bool ,
2538+ sugg_unit : bool | {
2539+ let mut err = tcx. sess . struct_span_err_with_code ( sp,
25452540 & format ! ( "this function takes {}{} parameter{} but {} parameter{} supplied" ,
25462541 if variadic { "at least " } else { "" } ,
25472542 expected_count,
@@ -2550,11 +2545,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25502545 if arg_count == 1 { " was" } else { "s were" } ) ,
25512546 DiagnosticId :: Error ( error_code. to_owned ( ) ) ) ;
25522547
2553- if let Some ( def_s) = def_span. map ( |sp| sess. codemap ( ) . def_span ( sp) ) {
2548+ if let Some ( def_s) = def_span. map ( |sp| tcx . sess . codemap ( ) . def_span ( sp) ) {
25542549 err. span_label ( def_s, "defined here" ) ;
25552550 }
25562551 if sugg_unit {
2557- let sugg_span = sess. codemap ( ) . end_point ( expr_sp) ;
2552+ let sugg_span = tcx . sess . codemap ( ) . end_point ( expr_sp) ;
25582553 // remove closing `)` from the span
25592554 let sugg_span = sugg_span. shrink_to_lo ( ) ;
25602555 err. span_suggestion (
@@ -2568,14 +2563,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25682563 if expected_count == 1 { "" } else { "s" } ) ) ;
25692564 }
25702565 err. emit ( ) ;
2571- }
2566+ } ;
25722567
25732568 let formal_tys = if tuple_arguments == TupleArguments {
25742569 let tuple_type = self . structurally_resolved_type ( sp, fn_inputs[ 0 ] ) ;
25752570 match tuple_type. sty {
25762571 ty:: TyTuple ( arg_types) if arg_types. len ( ) != args. len ( ) => {
2577- parameter_count_error ( tcx. sess , sp, expr_sp, arg_types. len ( ) , args. len ( ) ,
2578- "E0057" , false , def_span, false ) ;
2572+ param_count_error ( arg_types. len ( ) , args. len ( ) , "E0057" , false , false ) ;
25792573 expected_arg_tys = & [ ] ;
25802574 self . err_args ( args. len ( ) )
25812575 }
@@ -2603,8 +2597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26032597 if supplied_arg_count >= expected_arg_count {
26042598 fn_inputs. to_vec ( )
26052599 } else {
2606- parameter_count_error ( tcx. sess , sp, expr_sp, expected_arg_count,
2607- supplied_arg_count, "E0060" , true , def_span, false ) ;
2600+ param_count_error ( expected_arg_count, supplied_arg_count, "E0060" , true , false ) ;
26082601 expected_arg_tys = & [ ] ;
26092602 self . err_args ( supplied_arg_count)
26102603 }
@@ -2617,11 +2610,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26172610 } else {
26182611 false
26192612 } ;
2620- parameter_count_error ( tcx . sess , sp , expr_sp , expected_arg_count ,
2621- supplied_arg_count , "E0061" , false , def_span , sugg_unit ) ;
2613+ param_count_error ( expected_arg_count , supplied_arg_count , "E0061" , false , sugg_unit ) ;
2614+
26222615 expected_arg_tys = & [ ] ;
26232616 self . err_args ( supplied_arg_count)
26242617 } ;
2618+ // If there is no expectation, expect formal_tys.
2619+ let expected_arg_tys = if !expected_arg_tys. is_empty ( ) {
2620+ expected_arg_tys
2621+ } else {
2622+ & formal_tys
2623+ } ;
26252624
26262625 debug ! ( "check_argument_types: formal_tys={:?}" ,
26272626 formal_tys. iter( ) . map( |t| self . ty_to_string( * t) ) . collect:: <Vec <String >>( ) ) ;
@@ -2673,23 +2672,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26732672
26742673 // The special-cased logic below has three functions:
26752674 // 1. Provide as good of an expected type as possible.
2676- let expected = expected_arg_tys. get ( i) . map ( |& ty| {
2677- Expectation :: rvalue_hint ( self , ty)
2678- } ) ;
2675+ let expected = Expectation :: rvalue_hint ( self , expected_arg_tys[ i] ) ;
26792676
2680- let checked_ty = self . check_expr_with_expectation (
2681- & arg,
2682- expected. unwrap_or ( ExpectHasType ( formal_ty) ) ) ;
2677+ let checked_ty = self . check_expr_with_expectation ( & arg, expected) ;
26832678
26842679 // 2. Coerce to the most detailed type that could be coerced
26852680 // to, which is `expected_ty` if `rvalue_hint` returns an
26862681 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2687- let coerce_ty = expected. and_then ( |e| e . only_has_type ( self ) ) ;
2688- self . demand_coerce ( & arg, checked_ty, coerce_ty. unwrap_or ( formal_ty ) ) ;
2682+ let coerce_ty = expected. only_has_type ( self ) . unwrap_or ( formal_ty ) ;
2683+ self . demand_coerce ( & arg, checked_ty, coerce_ty) ;
26892684
26902685 // 3. Relate the expected type and the formal one,
26912686 // if the expected type was used for the coercion.
2692- coerce_ty . map ( |ty| self . demand_suptype ( arg. span , formal_ty, ty ) ) ;
2687+ self . demand_suptype ( arg. span , formal_ty, coerce_ty ) ;
26932688 }
26942689 }
26952690
@@ -2835,18 +2830,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28352830 fn check_expr_coercable_to_type ( & self ,
28362831 expr : & ' gcx hir:: Expr ,
28372832 expected : Ty < ' tcx > ) -> Ty < ' tcx > {
2838- self . check_expr_coercable_to_type_with_needs ( expr, expected, Needs :: None )
2839- }
2840-
2841- fn check_expr_coercable_to_type_with_needs ( & self ,
2842- expr : & ' gcx hir:: Expr ,
2843- expected : Ty < ' tcx > ,
2844- needs : Needs )
2845- -> Ty < ' tcx > {
2846- let ty = self . check_expr_with_expectation_and_needs (
2847- expr,
2848- ExpectHasType ( expected) ,
2849- needs) ;
2833+ let ty = self . check_expr_with_hint ( expr, expected) ;
28502834 self . demand_coerce ( expr, ty, expected)
28512835 }
28522836
@@ -2895,45 +2879,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28952879 formal_args : & [ Ty < ' tcx > ] )
28962880 -> Vec < Ty < ' tcx > > {
28972881 let formal_ret = self . resolve_type_vars_with_obligations ( formal_ret) ;
2898- let expected_args = expected_ret. only_has_type ( self ) . and_then ( |ret_ty| {
2899- self . fudge_regions_if_ok ( & RegionVariableOrigin :: Coercion ( call_span) , || {
2900- // Attempt to apply a subtyping relationship between the formal
2901- // return type (likely containing type variables if the function
2902- // is polymorphic) and the expected return type.
2903- // No argument expectations are produced if unification fails.
2904- let origin = self . misc ( call_span) ;
2905- let ures = self . at ( & origin, self . param_env ) . sup ( ret_ty, & formal_ret) ;
2906-
2907- // FIXME(#27336) can't use ? here, Try::from_error doesn't default
2908- // to identity so the resulting type is not constrained.
2909- match ures {
2910- Ok ( ok) => {
2911- // Process any obligations locally as much as
2912- // we can. We don't care if some things turn
2913- // out unconstrained or ambiguous, as we're
2914- // just trying to get hints here.
2915- self . save_and_restore_in_snapshot_flag ( |_| {
2916- let mut fulfill = TraitEngine :: new ( self . tcx ) ;
2917- for obligation in ok. obligations {
2918- fulfill. register_predicate_obligation ( self , obligation) ;
2919- }
2920- fulfill. select_where_possible ( self )
2921- } ) . map_err ( |_| ( ) ) ?;
2922- }
2923- Err ( _) => return Err ( ( ) ) ,
2882+ let ret_ty = match expected_ret. only_has_type ( self ) {
2883+ Some ( ret) => ret,
2884+ None => return Vec :: new ( )
2885+ } ;
2886+ let expect_args = self . fudge_regions_if_ok ( & RegionVariableOrigin :: Coercion ( call_span) , || {
2887+ // Attempt to apply a subtyping relationship between the formal
2888+ // return type (likely containing type variables if the function
2889+ // is polymorphic) and the expected return type.
2890+ // No argument expectations are produced if unification fails.
2891+ let origin = self . misc ( call_span) ;
2892+ let ures = self . at ( & origin, self . param_env ) . sup ( ret_ty, & formal_ret) ;
2893+
2894+ // FIXME(#27336) can't use ? here, Try::from_error doesn't default
2895+ // to identity so the resulting type is not constrained.
2896+ match ures {
2897+ Ok ( ok) => {
2898+ // Process any obligations locally as much as
2899+ // we can. We don't care if some things turn
2900+ // out unconstrained or ambiguous, as we're
2901+ // just trying to get hints here.
2902+ self . save_and_restore_in_snapshot_flag ( |_| {
2903+ let mut fulfill = TraitEngine :: new ( self . tcx ) ;
2904+ for obligation in ok. obligations {
2905+ fulfill. register_predicate_obligation ( self , obligation) ;
2906+ }
2907+ fulfill. select_where_possible ( self )
2908+ } ) . map_err ( |_| ( ) ) ?;
29242909 }
2910+ Err ( _) => return Err ( ( ) ) ,
2911+ }
29252912
2926- // Record all the argument types, with the substitutions
2927- // produced from the above subtyping unification.
2928- Ok ( formal_args. iter ( ) . map ( |ty| {
2929- self . resolve_type_vars_if_possible ( ty)
2930- } ) . collect ( ) )
2931- } ) . ok ( )
2932- } ) . unwrap_or ( vec ! [ ] ) ;
2913+ // Record all the argument types, with the substitutions
2914+ // produced from the above subtyping unification.
2915+ Ok ( formal_args. iter ( ) . map ( |ty| {
2916+ self . resolve_type_vars_if_possible ( ty)
2917+ } ) . collect ( ) )
2918+ } ) . unwrap_or ( Vec :: new ( ) ) ;
29332919 debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
29342920 formal_args, formal_ret,
2935- expected_args , expected_ret) ;
2936- expected_args
2921+ expect_args , expected_ret) ;
2922+ expect_args
29372923 }
29382924
29392925 // Checks a method call.
0 commit comments