@@ -10,7 +10,7 @@ mod suggest;
10
10
pub use self :: suggest:: SelfSource ;
11
11
pub use self :: MethodError :: * ;
12
12
13
- use crate :: check:: FnCtxt ;
13
+ use crate :: check:: { Expectation , FnCtxt } ;
14
14
use crate :: ObligationCause ;
15
15
use rustc_data_structures:: sync:: Lrc ;
16
16
use rustc_errors:: { Applicability , Diagnostic } ;
@@ -20,8 +20,10 @@ use rustc_hir::def_id::DefId;
20
20
use rustc_infer:: infer:: { self , InferOk } ;
21
21
use rustc_middle:: ty:: subst:: Subst ;
22
22
use 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
+ } ;
25
27
use rustc_span:: symbol:: Ident ;
26
28
use rustc_span:: Span ;
27
29
use rustc_trait_selection:: traits;
@@ -318,6 +320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
318
320
self_ty : Ty < ' tcx > ,
319
321
opt_input_type : Option < Ty < ' tcx > > ,
320
322
opt_input_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
323
+ expected : Expectation < ' tcx > ,
321
324
) -> ( traits:: Obligation < ' tcx , ty:: Predicate < ' tcx > > , & ' tcx ty:: List < ty:: subst:: GenericArg < ' tcx > > )
322
325
{
323
326
// Construct a trait-reference `self_ty : Trait<input_tys>`
@@ -339,6 +342,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339
342
340
343
// Construct an obligation
341
344
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
+
342
362
(
343
363
traits:: Obligation :: new (
344
364
traits:: ObligationCause :: new (
@@ -348,6 +368,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348
368
rhs_span : opt_input_expr. map ( |expr| expr. span ) ,
349
369
is_lit : opt_input_expr
350
370
. map_or ( false , |expr| matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) ) ,
371
+ output_pred,
351
372
} ,
352
373
) ,
353
374
self . param_env ,
@@ -397,13 +418,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
397
418
self_ty : Ty < ' tcx > ,
398
419
opt_input_type : Option < Ty < ' tcx > > ,
399
420
opt_input_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
421
+ expected : Expectation < ' tcx > ,
400
422
) -> Option < InferOk < ' tcx , MethodCallee < ' tcx > > > {
401
423
let ( obligation, substs) = self . obligation_for_op_method (
402
424
span,
403
425
trait_def_id,
404
426
self_ty,
405
427
opt_input_type,
406
428
opt_input_expr,
429
+ expected,
407
430
) ;
408
431
self . construct_obligation_for_trait (
409
432
span,
@@ -505,6 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
505
528
rhs_span : opt_input_expr. map ( |expr| expr. span ) ,
506
529
is_lit : opt_input_expr
507
530
. map_or ( false , |expr| matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) ) ,
531
+ output_pred : None ,
508
532
} ,
509
533
)
510
534
} else {
0 commit comments