@@ -2508,7 +2508,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2508
2508
sp : Span ,
2509
2509
expr_sp : Span ,
2510
2510
fn_inputs : & [ Ty < ' tcx > ] ,
2511
- expected_arg_tys : & [ Ty < ' tcx > ] ,
2511
+ mut expected_arg_tys : & [ Ty < ' tcx > ] ,
2512
2512
args : & ' gcx [ hir:: Expr ] ,
2513
2513
variadic : bool ,
2514
2514
tuple_arguments : TupleArgumentsFlag ,
@@ -2529,19 +2529,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2529
2529
self . register_wf_obligation ( fn_input_ty, sp, traits:: MiscObligation ) ;
2530
2530
}
2531
2531
2532
- let mut expected_arg_tys = expected_arg_tys;
2533
2532
let expected_arg_count = fn_inputs. len ( ) ;
2534
2533
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,
2545
2540
& format ! ( "this function takes {}{} parameter{} but {} parameter{} supplied" ,
2546
2541
if variadic { "at least " } else { "" } ,
2547
2542
expected_count,
@@ -2550,11 +2545,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2550
2545
if arg_count == 1 { " was" } else { "s were" } ) ,
2551
2546
DiagnosticId :: Error ( error_code. to_owned ( ) ) ) ;
2552
2547
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) ) {
2554
2549
err. span_label ( def_s, "defined here" ) ;
2555
2550
}
2556
2551
if sugg_unit {
2557
- let sugg_span = sess. codemap ( ) . end_point ( expr_sp) ;
2552
+ let sugg_span = tcx . sess . codemap ( ) . end_point ( expr_sp) ;
2558
2553
// remove closing `)` from the span
2559
2554
let sugg_span = sugg_span. shrink_to_lo ( ) ;
2560
2555
err. span_suggestion (
@@ -2568,14 +2563,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2568
2563
if expected_count == 1 { "" } else { "s" } ) ) ;
2569
2564
}
2570
2565
err. emit ( ) ;
2571
- }
2566
+ } ;
2572
2567
2573
2568
let formal_tys = if tuple_arguments == TupleArguments {
2574
2569
let tuple_type = self . structurally_resolved_type ( sp, fn_inputs[ 0 ] ) ;
2575
2570
match tuple_type. sty {
2576
2571
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 ) ;
2579
2573
expected_arg_tys = & [ ] ;
2580
2574
self . err_args ( args. len ( ) )
2581
2575
}
@@ -2603,8 +2597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2603
2597
if supplied_arg_count >= expected_arg_count {
2604
2598
fn_inputs. to_vec ( )
2605
2599
} 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 ) ;
2608
2601
expected_arg_tys = & [ ] ;
2609
2602
self . err_args ( supplied_arg_count)
2610
2603
}
@@ -2617,11 +2610,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2617
2610
} else {
2618
2611
false
2619
2612
} ;
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
+
2622
2615
expected_arg_tys = & [ ] ;
2623
2616
self . err_args ( supplied_arg_count)
2624
2617
} ;
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
+ } ;
2625
2624
2626
2625
debug ! ( "check_argument_types: formal_tys={:?}" ,
2627
2626
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> {
2673
2672
2674
2673
// The special-cased logic below has three functions:
2675
2674
// 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] ) ;
2679
2676
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) ;
2683
2678
2684
2679
// 2. Coerce to the most detailed type that could be coerced
2685
2680
// to, which is `expected_ty` if `rvalue_hint` returns an
2686
2681
// `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) ;
2689
2684
2690
2685
// 3. Relate the expected type and the formal one,
2691
2686
// 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 ) ;
2693
2688
}
2694
2689
}
2695
2690
@@ -2835,18 +2830,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2835
2830
fn check_expr_coercable_to_type ( & self ,
2836
2831
expr : & ' gcx hir:: Expr ,
2837
2832
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) ;
2850
2834
self . demand_coerce ( expr, ty, expected)
2851
2835
}
2852
2836
@@ -2895,45 +2879,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2895
2879
formal_args : & [ Ty < ' tcx > ] )
2896
2880
-> Vec < Ty < ' tcx > > {
2897
2881
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 ( |_| ( ) ) ?;
2924
2909
}
2910
+ Err ( _) => return Err ( ( ) ) ,
2911
+ }
2925
2912
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 ( ) ) ;
2933
2919
debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
2934
2920
formal_args, formal_ret,
2935
- expected_args , expected_ret) ;
2936
- expected_args
2921
+ expect_args , expected_ret) ;
2922
+ expect_args
2937
2923
}
2938
2924
2939
2925
// Checks a method call.
0 commit comments