@@ -401,6 +401,11 @@ fn project_type<'cx,'tcx>(
401
401
& obligation_trait_ref,
402
402
& mut candidates) ;
403
403
404
+ assemble_candidates_from_trait_def ( selcx,
405
+ obligation,
406
+ & obligation_trait_ref,
407
+ & mut candidates) ;
408
+
404
409
if let Err ( e) = assemble_candidates_from_impls ( selcx,
405
410
obligation,
406
411
& obligation_trait_ref,
@@ -446,6 +451,41 @@ fn assemble_candidates_from_param_env<'cx,'tcx>(
446
451
candidate_set, env_predicates) ;
447
452
}
448
453
454
+ /// In the case of a nested projection like <<A as Foo>::FooT as Bar>::BarT, we may find
455
+ /// that the definition of `Foo` has some clues:
456
+ ///
457
+ /// ```rust
458
+ /// trait Foo {
459
+ /// type FooT : Bar<BarT=i32>
460
+ /// }
461
+ /// ```
462
+ ///
463
+ /// Here, for example, we could conclude that the result is `i32`.
464
+ fn assemble_candidates_from_trait_def < ' cx , ' tcx > (
465
+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
466
+ obligation : & ProjectionTyObligation < ' tcx > ,
467
+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
468
+ candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
469
+ {
470
+ // Check whether the self-type is itself a projection.
471
+ let trait_ref = match obligation_trait_ref. self_ty ( ) . sty {
472
+ ty:: ty_projection( ref data) => data. trait_ref . clone ( ) ,
473
+ ty:: ty_infer( ty:: TyVar ( _) ) => {
474
+ // If the self-type is an inference variable, then it MAY wind up
475
+ // being a projected type, so induce an ambiguity.
476
+ candidate_set. ambiguous = true ;
477
+ return ;
478
+ }
479
+ _ => { return ; }
480
+ } ;
481
+
482
+ // If so, extract what we know from the trait and try to come up with a good answer.
483
+ let trait_def = ty:: lookup_trait_def ( selcx. tcx ( ) , trait_ref. def_id ) ;
484
+ let bounds = trait_def. generics . to_bounds ( selcx. tcx ( ) , trait_ref. substs ) ;
485
+ assemble_candidates_from_predicates ( selcx, obligation, obligation_trait_ref,
486
+ candidate_set, bounds. predicates . into_vec ( ) ) ;
487
+ }
488
+
449
489
fn assemble_candidates_from_predicates < ' cx , ' tcx > (
450
490
selcx : & mut SelectionContext < ' cx , ' tcx > ,
451
491
obligation : & ProjectionTyObligation < ' tcx > ,
0 commit comments