@@ -2507,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25072507 sp : Span ,
25082508 expr_sp : Span ,
25092509 fn_inputs : & [ Ty < ' tcx > ] ,
2510- expected_arg_tys : & [ Ty < ' tcx > ] ,
2510+ mut expected_arg_tys : & [ Ty < ' tcx > ] ,
25112511 args : & ' gcx [ hir:: Expr ] ,
25122512 variadic : bool ,
25132513 tuple_arguments : TupleArgumentsFlag ,
@@ -2528,7 +2528,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25282528 self . register_wf_obligation ( fn_input_ty, sp, traits:: MiscObligation ) ;
25292529 }
25302530
2531- let mut expected_arg_tys = expected_arg_tys;
25322531 let expected_arg_count = fn_inputs. len ( ) ;
25332532
25342533 let param_count_error = |expected_count : usize ,
@@ -2615,6 +2614,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26152614 expected_arg_tys = & [ ] ;
26162615 self . err_args ( supplied_arg_count)
26172616 } ;
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+ } ;
26182623
26192624 debug ! ( "check_argument_types: formal_tys={:?}" ,
26202625 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> {
26662671
26672672 // The special-cased logic below has three functions:
26682673 // 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] ) ;
26722675
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) ;
26762677
26772678 // 2. Coerce to the most detailed type that could be coerced
26782679 // to, which is `expected_ty` if `rvalue_hint` returns an
26792680 // `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 ) ;
26812682 // We're processing function arguments so we definitely want to use
26822683 // 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 ) ;
26872685
26882686 // 3. Relate the expected type and the formal one,
26892687 // 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 ) ;
26912689 }
26922690 }
26932691
@@ -2834,6 +2832,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28342832 expr : & ' gcx hir:: Expr ,
28352833 expected : Ty < ' tcx > ) -> Ty < ' tcx > {
28362834 let ty = self . check_expr_with_hint ( expr, expected) ;
2835+ // checks don't need two phase
28372836 self . demand_coerce ( expr, ty, expected, AllowTwoPhase :: No )
28382837 }
28392838
@@ -2882,45 +2881,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28822881 formal_args : & [ Ty < ' tcx > ] )
28832882 -> Vec < Ty < ' tcx > > {
28842883 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 ( |_| ( ) ) ?;
29112911 }
2912+ Err ( _) => return Err ( ( ) ) ,
2913+ }
29122914
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 ( ) ) ;
29202921 debug ! ( "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})" ,
29212922 formal_args, formal_ret,
2922- expected_args , expected_ret) ;
2923- expected_args
2923+ expect_args , expected_ret) ;
2924+ expect_args
29242925 }
29252926
29262927 // Checks a method call.
0 commit comments