@@ -430,6 +430,11 @@ fn project_type<'cx,'tcx>(
430
430
& obligation_trait_ref,
431
431
& mut candidates) ;
432
432
433
+ assemble_candidates_from_trait_def ( selcx,
434
+ obligation,
435
+ & obligation_trait_ref,
436
+ & mut candidates) ;
437
+
433
438
if let Err ( e) = assemble_candidates_from_impls ( selcx,
434
439
obligation,
435
440
& obligation_trait_ref,
@@ -474,6 +479,41 @@ fn assemble_candidates_from_param_env<'cx,'tcx>(
474
479
candidate_set, env_predicates) ;
475
480
}
476
481
482
+ /// In the case of a nested projection like <<A as Foo>::FooT as Bar>::BarT, we may find
483
+ /// that the definition of `Foo` has some clues:
484
+ ///
485
+ /// ```rust
486
+ /// trait Foo {
487
+ /// type FooT : Bar<BarT=i32>
488
+ /// }
489
+ /// ```
490
+ ///
491
+ /// Here, for example, we could conclude that the result is `i32`.
492
+ fn assemble_candidates_from_trait_def < ' cx , ' tcx > (
493
+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
494
+ obligation : & ProjectionTyObligation < ' tcx > ,
495
+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
496
+ candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
497
+ {
498
+ // Check whether the self-type is itself a projection.
499
+ let trait_ref = match obligation_trait_ref. self_ty ( ) . sty {
500
+ ty:: ty_projection( ref data) => data. trait_ref . clone ( ) ,
501
+ ty:: ty_infer( ty:: TyVar ( _) ) => {
502
+ // If the self-type is an inference variable, then it MAY wind up
503
+ // being a projected type, so induce an ambiguity.
504
+ candidate_set. ambiguous = true ;
505
+ return ;
506
+ }
507
+ _ => { return ; }
508
+ } ;
509
+
510
+ // If so, extract what we know from the trait and try to come up with a good answer.
511
+ let trait_def = ty:: lookup_trait_def ( selcx. tcx ( ) , trait_ref. def_id ) ;
512
+ let bounds = trait_def. generics . to_bounds ( selcx. tcx ( ) , trait_ref. substs ) ;
513
+ assemble_candidates_from_predicates ( selcx, obligation, obligation_trait_ref,
514
+ candidate_set, bounds. predicates . into_vec ( ) ) ;
515
+ }
516
+
477
517
fn assemble_candidates_from_predicates < ' cx , ' tcx > (
478
518
selcx : & mut SelectionContext < ' cx , ' tcx > ,
479
519
obligation : & ProjectionTyObligation < ' tcx > ,
0 commit comments