@@ -62,6 +62,7 @@ enum CandidateKind<'tcx> {
62
62
subst:: Substs < ' tcx > , MethodIndex ) ,
63
63
UnboxedClosureCandidate ( /* Trait */ ast:: DefId , MethodIndex ) ,
64
64
WhereClauseCandidate ( ty:: PolyTraitRef < ' tcx > , MethodIndex ) ,
65
+ ProjectionCandidate ( ast:: DefId , MethodIndex ) ,
65
66
}
66
67
67
68
pub struct Pick < ' tcx > {
@@ -479,6 +480,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
479
480
method. clone ( ) ,
480
481
matching_index) ;
481
482
483
+ self . assemble_projection_candidates ( trait_def_id,
484
+ method. clone ( ) ,
485
+ matching_index) ;
486
+
482
487
self . assemble_where_clause_candidates ( trait_def_id,
483
488
method,
484
489
matching_index) ;
@@ -608,6 +613,64 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
608
613
}
609
614
}
610
615
616
+ fn assemble_projection_candidates ( & mut self ,
617
+ trait_def_id : ast:: DefId ,
618
+ method : Rc < ty:: Method < ' tcx > > ,
619
+ method_index : uint )
620
+ {
621
+ debug ! ( "assemble_projection_candidates(\
622
+ trait_def_id={}, \
623
+ method={}, \
624
+ method_index={})",
625
+ trait_def_id. repr( self . tcx( ) ) ,
626
+ method. repr( self . tcx( ) ) ,
627
+ method_index) ;
628
+
629
+ for step in self . steps . iter ( ) {
630
+ debug ! ( "assemble_projection_candidates: step={}" ,
631
+ step. repr( self . tcx( ) ) ) ;
632
+
633
+ let projection_trait_ref = match step. self_ty . sty {
634
+ ty:: ty_projection( ref data) => & data. trait_ref ,
635
+ _ => continue ,
636
+ } ;
637
+
638
+ debug ! ( "assemble_projection_candidates: projection_trait_ref={}" ,
639
+ projection_trait_ref. repr( self . tcx( ) ) ) ;
640
+
641
+ let trait_def = ty:: lookup_trait_def ( self . tcx ( ) , projection_trait_ref. def_id ) ;
642
+ let bounds = trait_def. generics . to_bounds ( self . tcx ( ) , projection_trait_ref. substs ) ;
643
+ let predicates = bounds. predicates . into_vec ( ) ;
644
+ debug ! ( "assemble_projection_candidates: predicates={}" ,
645
+ predicates. repr( self . tcx( ) ) ) ;
646
+ for poly_bound in
647
+ traits:: elaborate_predicates ( self . tcx ( ) , predicates)
648
+ . filter_map ( |p| p. to_opt_poly_trait_ref ( ) ) // TODO filter_to_traits()
649
+ . filter ( |b| b. def_id ( ) == trait_def_id)
650
+ {
651
+ let bound = self . erase_late_bound_regions ( & poly_bound) ;
652
+
653
+ debug ! ( "assemble_projection_candidates: projection_trait_ref={} bound={}" ,
654
+ projection_trait_ref. repr( self . tcx( ) ) ,
655
+ bound. repr( self . tcx( ) ) ) ;
656
+
657
+ if self . infcx ( ) . can_equate ( & step. self_ty , & bound. self_ty ( ) ) . is_ok ( ) {
658
+ let xform_self_ty = self . xform_self_ty ( & method, bound. substs ) ;
659
+
660
+ debug ! ( "assemble_projection_candidates: bound={} xform_self_ty={}" ,
661
+ bound. repr( self . tcx( ) ) ,
662
+ xform_self_ty. repr( self . tcx( ) ) ) ;
663
+
664
+ self . extension_candidates . push ( Candidate {
665
+ xform_self_ty : xform_self_ty,
666
+ method_ty : method. clone ( ) ,
667
+ kind : ProjectionCandidate ( trait_def_id, method_index)
668
+ } ) ;
669
+ }
670
+ }
671
+ }
672
+ }
673
+
611
674
fn assemble_where_clause_candidates ( & mut self ,
612
675
trait_def_id : ast:: DefId ,
613
676
method_ty : Rc < ty:: Method < ' tcx > > ,
@@ -616,7 +679,6 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
616
679
debug ! ( "assemble_where_clause_candidates(trait_def_id={})" ,
617
680
trait_def_id. repr( self . tcx( ) ) ) ;
618
681
619
- // Check whether there are any where-clauses pertaining to this trait.
620
682
let caller_predicates =
621
683
self . fcx . inh . param_env . caller_bounds . predicates . as_slice ( ) . to_vec ( ) ;
622
684
for poly_bound in traits:: elaborate_predicates ( self . tcx ( ) , caller_predicates)
@@ -835,6 +897,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
835
897
norm_obligations. iter ( ) . all ( |o| selcx. evaluate_obligation ( o) )
836
898
}
837
899
900
+ ProjectionCandidate ( ..) |
838
901
ObjectCandidate ( ..) |
839
902
UnboxedClosureCandidate ( ..) |
840
903
WhereClauseCandidate ( ..) => {
@@ -1072,6 +1135,9 @@ impl<'tcx> Candidate<'tcx> {
1072
1135
1073
1136
WhereClausePick ( ( * trait_ref) . clone ( ) , index)
1074
1137
}
1138
+ ProjectionCandidate ( def_id, index) => {
1139
+ TraitPick ( def_id, index)
1140
+ }
1075
1141
}
1076
1142
}
1077
1143
}
@@ -1083,6 +1149,7 @@ impl<'tcx> Candidate<'tcx> {
1083
1149
ExtensionImplCandidate ( def_id, _, _, _) => ImplSource ( def_id) ,
1084
1150
UnboxedClosureCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
1085
1151
WhereClauseCandidate ( ref trait_ref, _) => TraitSource ( trait_ref. def_id ( ) ) ,
1152
+ ProjectionCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
1086
1153
}
1087
1154
}
1088
1155
@@ -1101,6 +1168,9 @@ impl<'tcx> Candidate<'tcx> {
1101
1168
WhereClauseCandidate ( ref trait_ref, method_num) => {
1102
1169
Some ( ( trait_ref. def_id ( ) , method_num) )
1103
1170
}
1171
+ ProjectionCandidate ( trait_def_id, method_num) => {
1172
+ Some ( ( trait_def_id, method_num) )
1173
+ }
1104
1174
}
1105
1175
}
1106
1176
}
@@ -1127,6 +1197,8 @@ impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
1127
1197
format ! ( "UnboxedClosureCandidate({},{})" , a. repr( tcx) , b) ,
1128
1198
WhereClauseCandidate ( ref a, ref b) =>
1129
1199
format ! ( "WhereClauseCandidate({},{})" , a. repr( tcx) , b) ,
1200
+ ProjectionCandidate ( ref a, ref b) =>
1201
+ format ! ( "ProjectionCandidate({},{})" , a. repr( tcx) , b) ,
1130
1202
}
1131
1203
}
1132
1204
}
0 commit comments