@@ -2508,7 +2508,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25082508 sp : Span ,
25092509 expr_sp : Span ,
25102510 fn_inputs : & [ Ty < ' tcx > ] ,
2511- expected_arg_tys : & [ Ty < ' tcx > ] ,
2511+ mut expected_arg_tys : & [ Ty < ' tcx > ] ,
25122512 args : & ' gcx [ hir:: Expr ] ,
25132513 variadic : bool ,
25142514 tuple_arguments : TupleArgumentsFlag ,
@@ -2529,7 +2529,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25292529 self . register_wf_obligation ( fn_input_ty, sp, traits:: MiscObligation ) ;
25302530 }
25312531
2532- let mut expected_arg_tys = expected_arg_tys;
25332532 let expected_arg_count = fn_inputs. len ( ) ;
25342533
25352534 let param_count_error = |expected_count : usize ,
@@ -2616,6 +2615,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26162615 expected_arg_tys = & [ ] ;
26172616 self . err_args ( supplied_arg_count)
26182617 } ;
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+ } ;
26192624
26202625 debug ! ( "check_argument_types: formal_tys={:?}" ,
26212626 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> {
26672672
26682673 // The special-cased logic below has three functions:
26692674 // 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] ) ;
26732676
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) ;
26772678
26782679 // 2. Coerce to the most detailed type that could be coerced
26792680 // to, which is `expected_ty` if `rvalue_hint` returns an
26802681 // `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) ;
26832684
26842685 // 3. Relate the expected type and the formal one,
26852686 // 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 ) ;
26872688 }
26882689 }
26892690
@@ -2878,45 +2879,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28782879 formal_args : & [ Ty < ' tcx > ] )
28792880 -> Vec < Ty < ' tcx > > {
28802881 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 ( |_| ( ) ) ?;
29072909 }
2910+ Err ( _) => return Err ( ( ) ) ,
2911+ }
29082912
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 ( ) ) ;
29162919 debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
29172920 formal_args, formal_ret,
2918- expected_args , expected_ret) ;
2919- expected_args
2921+ expect_args , expected_ret) ;
2922+ expect_args
29202923 }
29212924
29222925 // Checks a method call.
0 commit comments