@@ -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  tracing:: debug; 
3031use  { rustc_ast as  ast,  rustc_hir as  hir} ; 
3132
@@ -124,6 +125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
124125        } ; 
125126        if  let  Err ( guar)  = has_error { 
126127            let  err_inputs = self . err_args ( args_no_rcvr. len ( ) ,  guar) ; 
128+             let  err_output = Ty :: new_error ( self . tcx ,  guar) ; 
127129
128130            let  err_inputs = match  tuple_arguments { 
129131                DontTupleArguments  => err_inputs, 
@@ -134,28 +136,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
134136                sp, 
135137                expr, 
136138                & err_inputs, 
137-                 None , 
139+                 err_output, 
140+                 NoExpectation , 
138141                args_no_rcvr, 
139142                false , 
140143                tuple_arguments, 
141144                method. ok ( ) . map ( |method| method. def_id ) , 
142145            ) ; 
143-             return  Ty :: new_error ( self . tcx ,  guar ) ; 
146+             return  err_output ; 
144147        } 
145148
146149        let  method = method. unwrap ( ) ; 
147-         // HACK(eddyb) ignore self in the definition (see above). 
148-         let  expected_input_tys = self . expected_inputs_for_expected_output ( 
149-             sp, 
150-             expected, 
151-             method. sig . output ( ) , 
152-             & method. sig . inputs ( ) [ 1 ..] , 
153-         ) ; 
154150        self . check_argument_types ( 
155151            sp, 
156152            expr, 
157153            & method. sig . inputs ( ) [ 1 ..] , 
158-             expected_input_tys, 
154+             method. sig . output ( ) , 
155+             expected, 
159156            args_no_rcvr, 
160157            method. sig . c_variadic , 
161158            tuple_arguments, 
@@ -175,8 +172,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
175172        call_expr :  & ' tcx  hir:: Expr < ' tcx > , 
176173        // Types (as defined in the *signature* of the target function) 
177174        formal_input_tys :  & [ Ty < ' tcx > ] , 
178-         // More specific expected types, after unifying with caller output types 
179-         expected_input_tys :  Option < Vec < Ty < ' tcx > > > , 
175+         formal_output :  Ty < ' tcx > , 
176+         // Expected output from the parent expression or statement 
177+         expectation :  Expectation < ' tcx > , 
180178        // The expressions for each provided argument 
181179        provided_args :  & ' tcx  [ hir:: Expr < ' tcx > ] , 
182180        // Whether the function is variadic, for example when imported from C 
@@ -210,6 +208,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
210208            ) ; 
211209        } 
212210
211+         // First, let's unify the formal method signature with the expectation eagerly. 
212+         // We use this to guide coercion inference; it's output is "fudged" which means 
213+         // any remaining type variables are assigned to new, unrelated variables. This 
214+         // is because the inference guidance here is only speculative. 
215+         let  formal_output = self . resolve_vars_with_obligations ( formal_output) ; 
216+         let  expected_input_tys:  Option < Vec < _ > >  = expectation
217+             . only_has_type ( self ) 
218+             . and_then ( |expected_output| { 
219+                 self . fudge_inference_if_ok ( || { 
220+                     let  ocx = ObligationCtxt :: new ( self ) ; 
221+ 
222+                     // Attempt to apply a subtyping relationship between the formal 
223+                     // return type (likely containing type variables if the function 
224+                     // is polymorphic) and the expected return type. 
225+                     // No argument expectations are produced if unification fails. 
226+                     let  origin = self . misc ( call_span) ; 
227+                     ocx. sup ( & origin,  self . param_env ,  expected_output,  formal_output) ?; 
228+                     if  !ocx. select_where_possible ( ) . is_empty ( )  { 
229+                         return  Err ( TypeError :: Mismatch ) ; 
230+                     } 
231+ 
232+                     // Record all the argument types, with the args 
233+                     // produced from the above subtyping unification. 
234+                     Ok ( Some ( 
235+                         formal_input_tys
236+                             . iter ( ) 
237+                             . map ( |& ty| self . resolve_vars_if_possible ( ty) ) 
238+                             . collect ( ) , 
239+                     ) ) 
240+                 } ) 
241+                 . ok ( ) 
242+             } ) 
243+             . unwrap_or_default ( ) ; 
244+ 
213245        let  mut  err_code = E0061 ; 
214246
215247        // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here 
@@ -292,21 +324,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
292324
293325            let  coerce_error =
294326                self . coerce ( provided_arg,  checked_ty,  coerced_ty,  AllowTwoPhase :: Yes ,  None ) . err ( ) ; 
295- 
296327            if  coerce_error. is_some ( )  { 
297328                return  Compatibility :: Incompatible ( coerce_error) ; 
298329            } 
299330
300-             // 3. Check if the formal type is a supertype of  the checked one 
301-             //    and register any such obligations for future type checks 
302-             let  supertype_error  = self . at ( & self . misc ( provided_arg. span ) ,  self . param_env ) . sup ( 
331+             // 3. Check if the formal type is actually equal to  the checked one 
332+             //    and register any such obligations for future type checks.  
333+             let  formal_ty_error  = self . at ( & self . misc ( provided_arg. span ) ,  self . param_env ) . eq ( 
303334                DefineOpaqueTypes :: Yes , 
304335                formal_input_ty, 
305336                coerced_ty, 
306337            ) ; 
307338
308339            // If neither check failed, the types are compatible 
309-             match  supertype_error  { 
340+             match  formal_ty_error  { 
310341                Ok ( InferOk  {  obligations,  value :  ( )  } )  => { 
311342                    self . register_predicates ( obligations) ; 
312343                    Compatibility :: Compatible 
0 commit comments