@@ -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,7 +2529,6 @@ 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
2534
let param_count_error = |expected_count : usize ,
@@ -2616,6 +2615,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2616
2615
expected_arg_tys = & [ ] ;
2617
2616
self . err_args ( supplied_arg_count)
2618
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
+ } ;
2619
2624
2620
2625
debug ! ( "check_argument_types: formal_tys={:?}" ,
2621
2626
formal_tys. iter( ) . map( |t| self . ty_to_string( * t) ) . collect:: <Vec <String >>( ) ) ;
@@ -2667,23 +2672,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2667
2672
2668
2673
// The special-cased logic below has three functions:
2669
2674
// 1. Provide as good of an expected type as possible.
2670
- let expected = expected_arg_tys. get ( i) . map ( |& ty| {
2671
- Expectation :: rvalue_hint ( self , ty)
2672
- } ) ;
2675
+ let expected = Expectation :: rvalue_hint ( self , expected_arg_tys[ i] ) ;
2673
2676
2674
- let checked_ty = self . check_expr_with_expectation (
2675
- & arg,
2676
- expected. unwrap_or ( ExpectHasType ( formal_ty) ) ) ;
2677
+ let checked_ty = self . check_expr_with_expectation ( & arg, expected) ;
2677
2678
2678
2679
// 2. Coerce to the most detailed type that could be coerced
2679
2680
// to, which is `expected_ty` if `rvalue_hint` returns an
2680
2681
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2681
- let coerce_ty = expected. and_then ( |e| e . only_has_type ( self ) ) ;
2682
- 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) ;
2683
2684
2684
2685
// 3. Relate the expected type and the formal one,
2685
2686
// if the expected type was used for the coercion.
2686
- coerce_ty . map ( |ty| self . demand_suptype ( arg. span , formal_ty, ty ) ) ;
2687
+ self . demand_suptype ( arg. span , formal_ty, coerce_ty ) ;
2687
2688
}
2688
2689
}
2689
2690
@@ -2878,45 +2879,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2878
2879
formal_args : & [ Ty < ' tcx > ] )
2879
2880
-> Vec < Ty < ' tcx > > {
2880
2881
let formal_ret = self . resolve_type_vars_with_obligations ( formal_ret) ;
2881
- let expected_args = expected_ret. only_has_type ( self ) . and_then ( |ret_ty| {
2882
- self . fudge_regions_if_ok ( & RegionVariableOrigin :: Coercion ( call_span) , || {
2883
- // Attempt to apply a subtyping relationship between the formal
2884
- // return type (likely containing type variables if the function
2885
- // is polymorphic) and the expected return type.
2886
- // No argument expectations are produced if unification fails.
2887
- let origin = self . misc ( call_span) ;
2888
- let ures = self . at ( & origin, self . param_env ) . sup ( ret_ty, & formal_ret) ;
2889
-
2890
- // FIXME(#27336) can't use ? here, Try::from_error doesn't default
2891
- // to identity so the resulting type is not constrained.
2892
- match ures {
2893
- Ok ( ok) => {
2894
- // Process any obligations locally as much as
2895
- // we can. We don't care if some things turn
2896
- // out unconstrained or ambiguous, as we're
2897
- // just trying to get hints here.
2898
- self . save_and_restore_in_snapshot_flag ( |_| {
2899
- let mut fulfill = TraitEngine :: new ( self . tcx ) ;
2900
- for obligation in ok. obligations {
2901
- fulfill. register_predicate_obligation ( self , obligation) ;
2902
- }
2903
- fulfill. select_where_possible ( self )
2904
- } ) . map_err ( |_| ( ) ) ?;
2905
- }
2906
- 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 ( |_| ( ) ) ?;
2907
2909
}
2910
+ Err ( _) => return Err ( ( ) ) ,
2911
+ }
2908
2912
2909
- // Record all the argument types, with the substitutions
2910
- // produced from the above subtyping unification.
2911
- Ok ( formal_args. iter ( ) . map ( |ty| {
2912
- self . resolve_type_vars_if_possible ( ty)
2913
- } ) . collect ( ) )
2914
- } ) . ok ( )
2915
- } ) . 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 ( ) ) ;
2916
2919
debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
2917
2920
formal_args, formal_ret,
2918
- expected_args , expected_ret) ;
2919
- expected_args
2921
+ expect_args , expected_ret) ;
2922
+ expect_args
2920
2923
}
2921
2924
2922
2925
// Checks a method call.
0 commit comments