@@ -10,7 +10,7 @@ mod suggest;
1010pub use self :: suggest:: SelfSource ;
1111pub use self :: MethodError :: * ;
1212
13- use crate :: check:: FnCtxt ;
13+ use crate :: check:: { Expectation , FnCtxt } ;
1414use crate :: ObligationCause ;
1515use rustc_data_structures:: sync:: Lrc ;
1616use rustc_errors:: { Applicability , Diagnostic } ;
@@ -20,8 +20,10 @@ use rustc_hir::def_id::DefId;
2020use rustc_infer:: infer:: { self , InferOk } ;
2121use rustc_middle:: ty:: subst:: Subst ;
2222use rustc_middle:: ty:: subst:: { InternalSubsts , SubstsRef } ;
23- use rustc_middle:: ty:: { self , ToPredicate , Ty , TypeVisitable } ;
24- use rustc_middle:: ty:: { DefIdTree , GenericParamDefKind } ;
23+ use rustc_middle:: ty:: {
24+ self , AssocKind , DefIdTree , GenericParamDefKind , ProjectionPredicate , ProjectionTy , Term ,
25+ ToPredicate , Ty , TypeVisitable ,
26+ } ;
2527use rustc_span:: symbol:: Ident ;
2628use rustc_span:: Span ;
2729use rustc_trait_selection:: traits;
@@ -318,6 +320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
318320 self_ty : Ty < ' tcx > ,
319321 opt_input_type : Option < Ty < ' tcx > > ,
320322 opt_input_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
323+ expected : Expectation < ' tcx > ,
321324 ) -> ( traits:: Obligation < ' tcx , ty:: Predicate < ' tcx > > , & ' tcx ty:: List < ty:: subst:: GenericArg < ' tcx > > )
322325 {
323326 // Construct a trait-reference `self_ty : Trait<input_tys>`
@@ -339,6 +342,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339342
340343 // Construct an obligation
341344 let poly_trait_ref = ty:: Binder :: dummy ( trait_ref) ;
345+ let opt_output_ty =
346+ expected. only_has_type ( self ) . and_then ( |ty| ( !ty. needs_infer ( ) ) . then ( || ty) ) ;
347+ let opt_output_assoc_item = self . tcx . associated_items ( trait_def_id) . find_by_name_and_kind (
348+ self . tcx ,
349+ Ident :: from_str ( "Output" ) ,
350+ AssocKind :: Type ,
351+ trait_def_id,
352+ ) ;
353+ let output_pred =
354+ opt_output_ty. zip ( opt_output_assoc_item) . map ( |( output_ty, output_assoc_item) | {
355+ ty:: Binder :: dummy ( ty:: PredicateKind :: Projection ( ProjectionPredicate {
356+ projection_ty : ProjectionTy { substs, item_def_id : output_assoc_item. def_id } ,
357+ term : Term :: Ty ( output_ty) ,
358+ } ) )
359+ . to_predicate ( self . tcx )
360+ } ) ;
361+
342362 (
343363 traits:: Obligation :: new (
344364 traits:: ObligationCause :: new (
@@ -348,6 +368,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348368 rhs_span : opt_input_expr. map ( |expr| expr. span ) ,
349369 is_lit : opt_input_expr
350370 . map_or ( false , |expr| matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) ) ,
371+ output_pred,
351372 } ,
352373 ) ,
353374 self . param_env ,
@@ -397,13 +418,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
397418 self_ty : Ty < ' tcx > ,
398419 opt_input_type : Option < Ty < ' tcx > > ,
399420 opt_input_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
421+ expected : Expectation < ' tcx > ,
400422 ) -> Option < InferOk < ' tcx , MethodCallee < ' tcx > > > {
401423 let ( obligation, substs) = self . obligation_for_op_method (
402424 span,
403425 trait_def_id,
404426 self_ty,
405427 opt_input_type,
406428 opt_input_expr,
429+ expected,
407430 ) ;
408431 self . construct_obligation_for_trait (
409432 span,
@@ -505,6 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
505528 rhs_span : opt_input_expr. map ( |expr| expr. span ) ,
506529 is_lit : opt_input_expr
507530 . map_or ( false , |expr| matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) ) ,
531+ output_pred : None ,
508532 } ,
509533 )
510534 } else {
0 commit comments