@@ -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,7 +2528,6 @@ 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
2533
let param_count_error = |expected_count : usize ,
@@ -2615,6 +2614,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2615
2614
expected_arg_tys = & [ ] ;
2616
2615
self . err_args ( supplied_arg_count)
2617
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
+ } ;
2618
2623
2619
2624
debug ! ( "check_argument_types: formal_tys={:?}" ,
2620
2625
formal_tys. iter( ) . map( |t| self . ty_to_string( * t) ) . collect:: <Vec <String >>( ) ) ;
@@ -2666,28 +2671,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2666
2671
2667
2672
// The special-cased logic below has three functions:
2668
2673
// 1. Provide as good of an expected type as possible.
2669
- let expected = expected_arg_tys. get ( i) . map ( |& ty| {
2670
- Expectation :: rvalue_hint ( self , ty)
2671
- } ) ;
2674
+ let expected = Expectation :: rvalue_hint ( self , expected_arg_tys[ i] ) ;
2672
2675
2673
- let checked_ty = self . check_expr_with_expectation (
2674
- & arg,
2675
- expected. unwrap_or ( ExpectHasType ( formal_ty) ) ) ;
2676
+ let checked_ty = self . check_expr_with_expectation ( & arg, expected) ;
2676
2677
2677
2678
// 2. Coerce to the most detailed type that could be coerced
2678
2679
// to, which is `expected_ty` if `rvalue_hint` returns an
2679
2680
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2680
- 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 ) ;
2681
2682
// We're processing function arguments so we definitely want to use
2682
2683
// two-phase borrows.
2683
- self . demand_coerce ( & arg,
2684
- checked_ty,
2685
- coerce_ty. unwrap_or ( formal_ty) ,
2686
- AllowTwoPhase :: Yes ) ;
2684
+ self . demand_coerce ( & arg, checked_ty, coerce_ty, AllowTwoPhase :: Yes ) ;
2687
2685
2688
2686
// 3. Relate the expected type and the formal one,
2689
2687
// if the expected type was used for the coercion.
2690
- coerce_ty . map ( |ty| self . demand_suptype ( arg. span , formal_ty, ty ) ) ;
2688
+ self . demand_suptype ( arg. span , formal_ty, coerce_ty ) ;
2691
2689
}
2692
2690
}
2693
2691
@@ -2834,6 +2832,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2834
2832
expr : & ' gcx hir:: Expr ,
2835
2833
expected : Ty < ' tcx > ) -> Ty < ' tcx > {
2836
2834
let ty = self . check_expr_with_hint ( expr, expected) ;
2835
+ // checks don't need two phase
2837
2836
self . demand_coerce ( expr, ty, expected, AllowTwoPhase :: No )
2838
2837
}
2839
2838
@@ -2882,45 +2881,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2882
2881
formal_args : & [ Ty < ' tcx > ] )
2883
2882
-> Vec < Ty < ' tcx > > {
2884
2883
let formal_ret = self . resolve_type_vars_with_obligations ( formal_ret) ;
2885
- let expected_args = expected_ret. only_has_type ( self ) . and_then ( |ret_ty| {
2886
- 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 ( |_| ( ) ) ?;
2909
- }
2910
- 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 ( |_| ( ) ) ?;
2911
2911
}
2912
+ Err ( _) => return Err ( ( ) ) ,
2913
+ }
2912
2914
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
- } ) . ok ( )
2919
- } ) . 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 ( ) ) ;
2920
2921
debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
2921
2922
formal_args, formal_ret,
2922
- expected_args , expected_ret) ;
2923
- expected_args
2923
+ expect_args , expected_ret) ;
2924
+ expect_args
2924
2925
}
2925
2926
2926
2927
// Checks a method call.
0 commit comments