@@ -17,6 +17,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
1717use rustc_index:: IndexVec ;
1818use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk , TypeTrace } ;
1919use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
20+ use rustc_middle:: ty:: error:: TypeError ;
2021use rustc_middle:: ty:: visit:: TypeVisitableExt ;
2122use rustc_middle:: ty:: { self , IsSuggestable , Ty , TyCtxt } ;
2223use rustc_middle:: { bug, span_bug} ;
@@ -25,7 +26,7 @@ use rustc_span::symbol::{kw, Ident};
2526use rustc_span:: { sym, Span , DUMMY_SP } ;
2627use rustc_trait_selection:: error_reporting:: infer:: { FailureCode , ObligationCauseExt } ;
2728use rustc_trait_selection:: infer:: InferCtxtExt ;
28- use rustc_trait_selection:: traits:: { self , ObligationCauseCode , SelectionContext } ;
29+ use rustc_trait_selection:: traits:: { self , ObligationCauseCode , ObligationCtxt , SelectionContext } ;
2930use { rustc_ast as ast, rustc_hir as hir} ;
3031
3132use crate :: coercion:: CoerceMany ;
@@ -123,6 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
123124 } ;
124125 if let Err ( guar) = has_error {
125126 let err_inputs = self . err_args ( args_no_rcvr. len ( ) , guar) ;
127+ let err_output = Ty :: new_error ( self . tcx , guar) ;
126128
127129 let err_inputs = match tuple_arguments {
128130 DontTupleArguments => err_inputs,
@@ -133,28 +135,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
133135 sp,
134136 expr,
135137 & err_inputs,
136- None ,
138+ err_output,
139+ NoExpectation ,
137140 args_no_rcvr,
138141 false ,
139142 tuple_arguments,
140143 method. ok ( ) . map ( |method| method. def_id ) ,
141144 ) ;
142- return Ty :: new_error ( self . tcx , guar ) ;
145+ return err_output ;
143146 }
144147
145148 let method = method. unwrap ( ) ;
146- // HACK(eddyb) ignore self in the definition (see above).
147- let expected_input_tys = self . expected_inputs_for_expected_output (
148- sp,
149- expected,
150- method. sig . output ( ) ,
151- & method. sig . inputs ( ) [ 1 ..] ,
152- ) ;
153149 self . check_argument_types (
154150 sp,
155151 expr,
156152 & method. sig . inputs ( ) [ 1 ..] ,
157- expected_input_tys,
153+ method. sig . output ( ) ,
154+ expected,
158155 args_no_rcvr,
159156 method. sig . c_variadic ,
160157 tuple_arguments,
@@ -174,8 +171,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
174171 call_expr : & ' tcx hir:: Expr < ' tcx > ,
175172 // Types (as defined in the *signature* of the target function)
176173 formal_input_tys : & [ Ty < ' tcx > ] ,
177- // More specific expected types, after unifying with caller output types
178- expected_input_tys : Option < Vec < Ty < ' tcx > > > ,
174+ formal_output : Ty < ' tcx > ,
175+ // Expected output from the parent expression or statement
176+ expectation : Expectation < ' tcx > ,
179177 // The expressions for each provided argument
180178 provided_args : & ' tcx [ hir:: Expr < ' tcx > ] ,
181179 // Whether the function is variadic, for example when imported from C
@@ -209,6 +207,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
209207 ) ;
210208 }
211209
210+ // First, let's unify the formal method signature with the expectation eagerly.
211+ // We use this to guide coercion inference; it's output is "fudged" which means
212+ // any remaining type variables are assigned to new, unrelated variables. This
213+ // is because the inference guidance here is only speculative.
214+ let expected_input_tys: Option < Vec < _ > > = expectation
215+ . only_has_type ( self )
216+ . and_then ( |expected_output| {
217+ self . fudge_inference_if_ok ( || {
218+ let ocx = ObligationCtxt :: new ( self ) ;
219+
220+ // Attempt to apply a subtyping relationship between the formal
221+ // return type (likely containing type variables if the function
222+ // is polymorphic) and the expected return type.
223+ // No argument expectations are produced if unification fails.
224+ let origin = self . misc ( call_span) ;
225+ ocx. sup ( & origin, self . param_env , expected_output, formal_output) ?;
226+ if !ocx. select_where_possible ( ) . is_empty ( ) {
227+ return Err ( TypeError :: Mismatch ) ;
228+ }
229+
230+ // Record all the argument types, with the args
231+ // produced from the above subtyping unification.
232+ Ok ( Some (
233+ formal_input_tys
234+ . iter ( )
235+ . map ( |& ty| self . resolve_vars_if_possible ( ty) )
236+ . collect ( ) ,
237+ ) )
238+ } )
239+ . ok ( )
240+ } )
241+ . unwrap_or_default ( ) ;
242+
212243 let mut err_code = E0061 ;
213244
214245 // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
0 commit comments