@@ -2507,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2507
2507
sp : Span ,
2508
2508
expr_sp : Span ,
2509
2509
fn_inputs : & [ Ty < ' tcx > ] ,
2510
- expected_arg_tys : & [ Ty < ' tcx > ] ,
2510
+ mut expected_arg_tys : & [ Ty < ' tcx > ] ,
2511
2511
args : & ' gcx [ hir:: Expr ] ,
2512
2512
variadic : bool ,
2513
2513
tuple_arguments : TupleArgumentsFlag ,
@@ -2528,19 +2528,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2528
2528
self . register_wf_obligation ( fn_input_ty, sp, traits:: MiscObligation ) ;
2529
2529
}
2530
2530
2531
- let mut expected_arg_tys = expected_arg_tys;
2532
2531
let expected_arg_count = fn_inputs. len ( ) ;
2533
2532
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,
2544
2539
& format ! ( "this function takes {}{} parameter{} but {} parameter{} supplied" ,
2545
2540
if variadic { "at least " } else { "" } ,
2546
2541
expected_count,
@@ -2549,11 +2544,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2549
2544
if arg_count == 1 { " was" } else { "s were" } ) ,
2550
2545
DiagnosticId :: Error ( error_code. to_owned ( ) ) ) ;
2551
2546
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) ) {
2553
2548
err. span_label ( def_s, "defined here" ) ;
2554
2549
}
2555
2550
if sugg_unit {
2556
- let sugg_span = sess. codemap ( ) . end_point ( expr_sp) ;
2551
+ let sugg_span = tcx . sess . codemap ( ) . end_point ( expr_sp) ;
2557
2552
// remove closing `)` from the span
2558
2553
let sugg_span = sugg_span. shrink_to_lo ( ) ;
2559
2554
err. span_suggestion (
@@ -2567,14 +2562,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2567
2562
if expected_count == 1 { "" } else { "s" } ) ) ;
2568
2563
}
2569
2564
err. emit ( ) ;
2570
- }
2565
+ } ;
2571
2566
2572
2567
let formal_tys = if tuple_arguments == TupleArguments {
2573
2568
let tuple_type = self . structurally_resolved_type ( sp, fn_inputs[ 0 ] ) ;
2574
2569
match tuple_type. sty {
2575
2570
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 ) ;
2578
2572
expected_arg_tys = & [ ] ;
2579
2573
self . err_args ( args. len ( ) )
2580
2574
}
@@ -2602,8 +2596,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2602
2596
if supplied_arg_count >= expected_arg_count {
2603
2597
fn_inputs. to_vec ( )
2604
2598
} 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 ) ;
2607
2600
expected_arg_tys = & [ ] ;
2608
2601
self . err_args ( supplied_arg_count)
2609
2602
}
@@ -2616,11 +2609,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2616
2609
} else {
2617
2610
false
2618
2611
} ;
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
+
2621
2614
expected_arg_tys = & [ ] ;
2622
2615
self . err_args ( supplied_arg_count)
2623
2616
} ;
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
+ } ;
2624
2623
2625
2624
debug ! ( "check_argument_types: formal_tys={:?}" ,
2626
2625
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> {
2672
2671
2673
2672
// The special-cased logic below has three functions:
2674
2673
// 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] ) ;
2678
2675
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) ;
2682
2677
2683
2678
// 2. Coerce to the most detailed type that could be coerced
2684
2679
// to, which is `expected_ty` if `rvalue_hint` returns an
2685
2680
// `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 ) ;
2687
2682
// We're processing function arguments so we definitely want to use
2688
2683
// 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 ) ;
2693
2685
2694
2686
// 3. Relate the expected type and the formal one,
2695
2687
// 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 ) ;
2697
2689
}
2698
2690
}
2699
2691
@@ -2839,18 +2831,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2839
2831
fn check_expr_coercable_to_type ( & self ,
2840
2832
expr : & ' gcx hir:: Expr ,
2841
2833
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) ;
2854
2835
// checks don't need two phase
2855
2836
self . demand_coerce ( expr, ty, expected, AllowTwoPhase :: No )
2856
2837
}
@@ -2900,45 +2881,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2900
2881
formal_args : & [ Ty < ' tcx > ] )
2901
2882
-> Vec < Ty < ' tcx > > {
2902
2883
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 ( |_| ( ) ) ?;
2929
2911
}
2912
+ Err ( _) => return Err ( ( ) ) ,
2913
+ }
2930
2914
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 ( ) ) ;
2938
2921
debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
2939
2922
formal_args, formal_ret,
2940
- expected_args , expected_ret) ;
2941
- expected_args
2923
+ expect_args , expected_ret) ;
2924
+ expect_args
2942
2925
}
2943
2926
2944
2927
// Checks a method call.
0 commit comments