@@ -2507,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25072507 sp : Span ,
25082508 expr_sp : Span ,
25092509 fn_inputs : & [ Ty < ' tcx > ] ,
2510- expected_arg_tys : & [ Ty < ' tcx > ] ,
2510+ mut expected_arg_tys : & [ Ty < ' tcx > ] ,
25112511 args : & ' gcx [ hir:: Expr ] ,
25122512 variadic : bool ,
25132513 tuple_arguments : TupleArgumentsFlag ,
@@ -2528,19 +2528,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25282528 self . register_wf_obligation ( fn_input_ty, sp, traits:: MiscObligation ) ;
25292529 }
25302530
2531- let mut expected_arg_tys = expected_arg_tys;
25322531 let expected_arg_count = fn_inputs. len ( ) ;
25332532
2534- fn parameter_count_error < ' tcx > ( sess : & Session ,
2535- sp : Span ,
2536- expr_sp : Span ,
2537- expected_count : usize ,
2538- arg_count : usize ,
2539- error_code : & str ,
2540- variadic : bool ,
2541- def_span : Option < Span > ,
2542- sugg_unit : bool ) {
2543- let mut err = sess. struct_span_err_with_code ( sp,
2533+ let param_count_error = |expected_count : usize ,
2534+ arg_count : usize ,
2535+ error_code : & str ,
2536+ variadic : bool ,
2537+ sugg_unit : bool | {
2538+ let mut err = tcx. sess . struct_span_err_with_code ( sp,
25442539 & format ! ( "this function takes {}{} parameter{} but {} parameter{} supplied" ,
25452540 if variadic { "at least " } else { "" } ,
25462541 expected_count,
@@ -2549,11 +2544,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25492544 if arg_count == 1 { " was" } else { "s were" } ) ,
25502545 DiagnosticId :: Error ( error_code. to_owned ( ) ) ) ;
25512546
2552- if let Some ( def_s) = def_span. map ( |sp| sess. codemap ( ) . def_span ( sp) ) {
2547+ if let Some ( def_s) = def_span. map ( |sp| tcx . sess . codemap ( ) . def_span ( sp) ) {
25532548 err. span_label ( def_s, "defined here" ) ;
25542549 }
25552550 if sugg_unit {
2556- let sugg_span = sess. codemap ( ) . end_point ( expr_sp) ;
2551+ let sugg_span = tcx . sess . codemap ( ) . end_point ( expr_sp) ;
25572552 // remove closing `)` from the span
25582553 let sugg_span = sugg_span. shrink_to_lo ( ) ;
25592554 err. span_suggestion (
@@ -2567,14 +2562,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25672562 if expected_count == 1 { "" } else { "s" } ) ) ;
25682563 }
25692564 err. emit ( ) ;
2570- }
2565+ } ;
25712566
25722567 let formal_tys = if tuple_arguments == TupleArguments {
25732568 let tuple_type = self . structurally_resolved_type ( sp, fn_inputs[ 0 ] ) ;
25742569 match tuple_type. sty {
25752570 ty:: TyTuple ( arg_types) if arg_types. len ( ) != args. len ( ) => {
2576- parameter_count_error ( tcx. sess , sp, expr_sp, arg_types. len ( ) , args. len ( ) ,
2577- "E0057" , false , def_span, false ) ;
2571+ param_count_error ( arg_types. len ( ) , args. len ( ) , "E0057" , false , false ) ;
25782572 expected_arg_tys = & [ ] ;
25792573 self . err_args ( args. len ( ) )
25802574 }
@@ -2602,8 +2596,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26022596 if supplied_arg_count >= expected_arg_count {
26032597 fn_inputs. to_vec ( )
26042598 } else {
2605- parameter_count_error ( tcx. sess , sp, expr_sp, expected_arg_count,
2606- supplied_arg_count, "E0060" , true , def_span, false ) ;
2599+ param_count_error ( expected_arg_count, supplied_arg_count, "E0060" , true , false ) ;
26072600 expected_arg_tys = & [ ] ;
26082601 self . err_args ( supplied_arg_count)
26092602 }
@@ -2616,11 +2609,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26162609 } else {
26172610 false
26182611 } ;
2619- parameter_count_error ( tcx . sess , sp , expr_sp , expected_arg_count ,
2620- supplied_arg_count , "E0061" , false , def_span , sugg_unit ) ;
2612+ param_count_error ( expected_arg_count , supplied_arg_count , "E0061" , false , sugg_unit ) ;
2613+
26212614 expected_arg_tys = & [ ] ;
26222615 self . err_args ( supplied_arg_count)
26232616 } ;
2617+ // If there is no expectation, expect formal_tys.
2618+ let expected_arg_tys = if !expected_arg_tys. is_empty ( ) {
2619+ expected_arg_tys
2620+ } else {
2621+ & formal_tys
2622+ } ;
26242623
26252624 debug ! ( "check_argument_types: formal_tys={:?}" ,
26262625 formal_tys. iter( ) . map( |t| self . ty_to_string( * t) ) . collect:: <Vec <String >>( ) ) ;
@@ -2672,28 +2671,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26722671
26732672 // The special-cased logic below has three functions:
26742673 // 1. Provide as good of an expected type as possible.
2675- let expected = expected_arg_tys. get ( i) . map ( |& ty| {
2676- Expectation :: rvalue_hint ( self , ty)
2677- } ) ;
2674+ let expected = Expectation :: rvalue_hint ( self , expected_arg_tys[ i] ) ;
26782675
2679- let checked_ty = self . check_expr_with_expectation (
2680- & arg,
2681- expected. unwrap_or ( ExpectHasType ( formal_ty) ) ) ;
2676+ let checked_ty = self . check_expr_with_expectation ( & arg, expected) ;
26822677
26832678 // 2. Coerce to the most detailed type that could be coerced
26842679 // to, which is `expected_ty` if `rvalue_hint` returns an
26852680 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2686- let coerce_ty = expected. and_then ( |e| e . only_has_type ( self ) ) ;
2681+ let coerce_ty = expected. only_has_type ( self ) . unwrap_or ( formal_ty ) ;
26872682 // We're processing function arguments so we definitely want to use
26882683 // two-phase borrows.
2689- self . demand_coerce ( & arg,
2690- checked_ty,
2691- coerce_ty. unwrap_or ( formal_ty) ,
2692- AllowTwoPhase :: Yes ) ;
2684+ self . demand_coerce ( & arg, checked_ty, coerce_ty, AllowTwoPhase :: Yes ) ;
26932685
26942686 // 3. Relate the expected type and the formal one,
26952687 // if the expected type was used for the coercion.
2696- coerce_ty . map ( |ty| self . demand_suptype ( arg. span , formal_ty, ty ) ) ;
2688+ self . demand_suptype ( arg. span , formal_ty, coerce_ty ) ;
26972689 }
26982690 }
26992691
@@ -2839,18 +2831,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28392831 fn check_expr_coercable_to_type ( & self ,
28402832 expr : & ' gcx hir:: Expr ,
28412833 expected : Ty < ' tcx > ) -> Ty < ' tcx > {
2842- self . check_expr_coercable_to_type_with_needs ( expr, expected, Needs :: None )
2843- }
2844-
2845- fn check_expr_coercable_to_type_with_needs ( & self ,
2846- expr : & ' gcx hir:: Expr ,
2847- expected : Ty < ' tcx > ,
2848- needs : Needs )
2849- -> Ty < ' tcx > {
2850- let ty = self . check_expr_with_expectation_and_needs (
2851- expr,
2852- ExpectHasType ( expected) ,
2853- needs) ;
2834+ let ty = self . check_expr_with_hint ( expr, expected) ;
28542835 // checks don't need two phase
28552836 self . demand_coerce ( expr, ty, expected, AllowTwoPhase :: No )
28562837 }
@@ -2900,45 +2881,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
29002881 formal_args : & [ Ty < ' tcx > ] )
29012882 -> Vec < Ty < ' tcx > > {
29022883 let formal_ret = self . resolve_type_vars_with_obligations ( formal_ret) ;
2903- let expected_args = expected_ret. only_has_type ( self ) . and_then ( |ret_ty| {
2904- self . fudge_regions_if_ok ( & RegionVariableOrigin :: Coercion ( call_span) , || {
2905- // Attempt to apply a subtyping relationship between the formal
2906- // return type (likely containing type variables if the function
2907- // is polymorphic) and the expected return type.
2908- // No argument expectations are produced if unification fails.
2909- let origin = self . misc ( call_span) ;
2910- let ures = self . at ( & origin, self . param_env ) . sup ( ret_ty, & formal_ret) ;
2911-
2912- // FIXME(#27336) can't use ? here, Try::from_error doesn't default
2913- // to identity so the resulting type is not constrained.
2914- match ures {
2915- Ok ( ok) => {
2916- // Process any obligations locally as much as
2917- // we can. We don't care if some things turn
2918- // out unconstrained or ambiguous, as we're
2919- // just trying to get hints here.
2920- self . save_and_restore_in_snapshot_flag ( |_| {
2921- let mut fulfill = TraitEngine :: new ( self . tcx ) ;
2922- for obligation in ok. obligations {
2923- fulfill. register_predicate_obligation ( self , obligation) ;
2924- }
2925- fulfill. select_where_possible ( self )
2926- } ) . map_err ( |_| ( ) ) ?;
2927- }
2928- Err ( _) => return Err ( ( ) ) ,
2884+ let ret_ty = match expected_ret. only_has_type ( self ) {
2885+ Some ( ret) => ret,
2886+ None => return Vec :: new ( )
2887+ } ;
2888+ let expect_args = self . fudge_regions_if_ok ( & RegionVariableOrigin :: Coercion ( call_span) , || {
2889+ // Attempt to apply a subtyping relationship between the formal
2890+ // return type (likely containing type variables if the function
2891+ // is polymorphic) and the expected return type.
2892+ // No argument expectations are produced if unification fails.
2893+ let origin = self . misc ( call_span) ;
2894+ let ures = self . at ( & origin, self . param_env ) . sup ( ret_ty, & formal_ret) ;
2895+
2896+ // FIXME(#27336) can't use ? here, Try::from_error doesn't default
2897+ // to identity so the resulting type is not constrained.
2898+ match ures {
2899+ Ok ( ok) => {
2900+ // Process any obligations locally as much as
2901+ // we can. We don't care if some things turn
2902+ // out unconstrained or ambiguous, as we're
2903+ // just trying to get hints here.
2904+ self . save_and_restore_in_snapshot_flag ( |_| {
2905+ let mut fulfill = TraitEngine :: new ( self . tcx ) ;
2906+ for obligation in ok. obligations {
2907+ fulfill. register_predicate_obligation ( self , obligation) ;
2908+ }
2909+ fulfill. select_where_possible ( self )
2910+ } ) . map_err ( |_| ( ) ) ?;
29292911 }
2912+ Err ( _) => return Err ( ( ) ) ,
2913+ }
29302914
2931- // Record all the argument types, with the substitutions
2932- // produced from the above subtyping unification.
2933- Ok ( formal_args. iter ( ) . map ( |ty| {
2934- self . resolve_type_vars_if_possible ( ty)
2935- } ) . collect ( ) )
2936- } ) . ok ( )
2937- } ) . unwrap_or ( vec ! [ ] ) ;
2915+ // Record all the argument types, with the substitutions
2916+ // produced from the above subtyping unification.
2917+ Ok ( formal_args. iter ( ) . map ( |ty| {
2918+ self . resolve_type_vars_if_possible ( ty)
2919+ } ) . collect ( ) )
2920+ } ) . unwrap_or ( Vec :: new ( ) ) ;
29382921 debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
29392922 formal_args, formal_ret,
2940- expected_args , expected_ret) ;
2941- expected_args
2923+ expect_args , expected_ret) ;
2924+ expect_args
29422925 }
29432926
29442927 // Checks a method call.
0 commit comments