@@ -18,7 +18,7 @@ use middle::fast_reject;
1818use middle:: subst;
1919use middle:: subst:: Subst ;
2020use middle:: traits;
21- use middle:: ty:: { self , Ty , ToPolyTraitRef } ;
21+ use middle:: ty:: { self , RegionEscape , Ty , ToPolyTraitRef } ;
2222use middle:: ty_fold:: TypeFoldable ;
2323use middle:: infer;
2424use middle:: infer:: InferCtxt ;
@@ -62,6 +62,7 @@ enum CandidateKind<'tcx> {
6262 subst:: Substs < ' tcx > , MethodIndex ) ,
6363 UnboxedClosureCandidate ( /* Trait */ ast:: DefId , MethodIndex ) ,
6464 WhereClauseCandidate ( ty:: PolyTraitRef < ' tcx > , MethodIndex ) ,
65+ ProjectionCandidate ( ast:: DefId , MethodIndex ) ,
6566}
6667
6768pub struct Pick < ' tcx > {
@@ -309,18 +310,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
309310 // argument type like `&Trait`.
310311 let trait_ref = data. principal_trait_ref_with_self_ty ( self . tcx ( ) , self_ty) ;
311312 self . elaborate_bounds ( & [ trait_ref. clone ( ) ] , false , |this, new_trait_ref, m, method_num| {
313+ let new_trait_ref = this. erase_late_bound_regions ( & new_trait_ref) ;
314+
312315 let vtable_index =
313316 traits:: get_vtable_index_of_object_method ( tcx,
314317 trait_ref. clone ( ) ,
315- new_trait_ref. def_id ( ) ,
318+ new_trait_ref. def_id ,
316319 method_num) ;
317320
318- let xform_self_ty = this. xform_self_ty ( & m, new_trait_ref. substs ( ) ) ;
321+ let xform_self_ty = this. xform_self_ty ( & m, new_trait_ref. substs ) ;
319322
320323 this. inherent_candidates . push ( Candidate {
321324 xform_self_ty : xform_self_ty,
322325 method_ty : m,
323- kind : ObjectCandidate ( new_trait_ref. def_id ( ) , method_num, vtable_index)
326+ kind : ObjectCandidate ( new_trait_ref. def_id , method_num, vtable_index)
324327 } ) ;
325328 } ) ;
326329 }
@@ -353,34 +356,37 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
353356 } )
354357 . collect ( ) ;
355358
356- self . elaborate_bounds ( bounds. as_slice ( ) , true , |this, trait_ref, m, method_num| {
359+ self . elaborate_bounds ( bounds. as_slice ( ) , true , |this, poly_trait_ref, m, method_num| {
360+ let trait_ref =
361+ this. erase_late_bound_regions ( & poly_trait_ref) ;
362+
357363 let xform_self_ty =
358- this. xform_self_ty ( & m, trait_ref. substs ( ) ) ;
364+ this. xform_self_ty ( & m, trait_ref. substs ) ;
359365
360366 debug ! ( "found match: trait_ref={} substs={} m={}" ,
361367 trait_ref. repr( this. tcx( ) ) ,
362- trait_ref. substs( ) . repr( this. tcx( ) ) ,
368+ trait_ref. substs. repr( this. tcx( ) ) ,
363369 m. repr( this. tcx( ) ) ) ;
364370 assert_eq ! ( m. generics. types. get_slice( subst:: TypeSpace ) . len( ) ,
365- trait_ref. substs( ) . types. get_slice( subst:: TypeSpace ) . len( ) ) ;
371+ trait_ref. substs. types. get_slice( subst:: TypeSpace ) . len( ) ) ;
366372 assert_eq ! ( m. generics. regions. get_slice( subst:: TypeSpace ) . len( ) ,
367- trait_ref. substs( ) . regions( ) . get_slice( subst:: TypeSpace ) . len( ) ) ;
373+ trait_ref. substs. regions( ) . get_slice( subst:: TypeSpace ) . len( ) ) ;
368374 assert_eq ! ( m. generics. types. get_slice( subst:: SelfSpace ) . len( ) ,
369- trait_ref. substs( ) . types. get_slice( subst:: SelfSpace ) . len( ) ) ;
375+ trait_ref. substs. types. get_slice( subst:: SelfSpace ) . len( ) ) ;
370376 assert_eq ! ( m. generics. regions. get_slice( subst:: SelfSpace ) . len( ) ,
371- trait_ref. substs( ) . regions( ) . get_slice( subst:: SelfSpace ) . len( ) ) ;
377+ trait_ref. substs. regions( ) . get_slice( subst:: SelfSpace ) . len( ) ) ;
372378
373379 // Because this trait derives from a where-clause, it
374380 // should not contain any inference variables or other
375381 // artifacts. This means it is safe to put into the
376382 // `WhereClauseCandidate` and (eventually) into the
377383 // `WhereClausePick`.
378- assert ! ( trait_ref. substs( ) . types. iter( ) . all( |& t| !ty:: type_needs_infer( t) ) ) ;
384+ assert ! ( trait_ref. substs. types. iter( ) . all( |& t| !ty:: type_needs_infer( t) ) ) ;
379385
380386 this. inherent_candidates . push ( Candidate {
381387 xform_self_ty : xform_self_ty,
382388 method_ty : m,
383- kind : WhereClauseCandidate ( trait_ref , method_num)
389+ kind : WhereClauseCandidate ( poly_trait_ref , method_num)
384390 } ) ;
385391 } ) ;
386392 }
@@ -474,6 +480,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
474480 method. clone ( ) ,
475481 matching_index) ;
476482
483+ self . assemble_projection_candidates ( trait_def_id,
484+ method. clone ( ) ,
485+ matching_index) ;
486+
477487 self . assemble_where_clause_candidates ( trait_def_id,
478488 method,
479489 matching_index) ;
@@ -603,6 +613,64 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
603613 }
604614 }
605615
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 ( ) )
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+
606674 fn assemble_where_clause_candidates ( & mut self ,
607675 trait_def_id : ast:: DefId ,
608676 method_ty : Rc < ty:: Method < ' tcx > > ,
@@ -611,14 +679,14 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
611679 debug ! ( "assemble_where_clause_candidates(trait_def_id={})" ,
612680 trait_def_id. repr( self . tcx( ) ) ) ;
613681
614- // Check whether there are any where-clauses pertaining to this trait.
615682 let caller_predicates =
616683 self . fcx . inh . param_env . caller_bounds . predicates . as_slice ( ) . to_vec ( ) ;
617- for bound in traits:: elaborate_predicates ( self . tcx ( ) , caller_predicates)
618- . filter_map ( |p| p. to_opt_poly_trait_ref ( ) )
619- . filter ( |b| b. def_id ( ) == trait_def_id)
684+ for poly_bound in traits:: elaborate_predicates ( self . tcx ( ) , caller_predicates)
685+ . filter_map ( |p| p. to_opt_poly_trait_ref ( ) )
686+ . filter ( |b| b. def_id ( ) == trait_def_id)
620687 {
621- let xform_self_ty = self . xform_self_ty ( & method_ty, bound. substs ( ) ) ;
688+ let bound = self . erase_late_bound_regions ( & poly_bound) ;
689+ let xform_self_ty = self . xform_self_ty ( & method_ty, bound. substs ) ;
622690
623691 debug ! ( "assemble_where_clause_candidates: bound={} xform_self_ty={}" ,
624692 bound. repr( self . tcx( ) ) ,
@@ -627,7 +695,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
627695 self . extension_candidates . push ( Candidate {
628696 xform_self_ty : xform_self_ty,
629697 method_ty : method_ty. clone ( ) ,
630- kind : WhereClauseCandidate ( bound , method_index)
698+ kind : WhereClauseCandidate ( poly_bound , method_index)
631699 } ) ;
632700 }
633701 }
@@ -829,6 +897,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
829897 norm_obligations. iter ( ) . all ( |o| selcx. evaluate_obligation ( o) )
830898 }
831899
900+ ProjectionCandidate ( ..) |
832901 ObjectCandidate ( ..) |
833902 UnboxedClosureCandidate ( ..) |
834903 WhereClauseCandidate ( ..) => {
@@ -920,6 +989,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
920989 method. fty. sig. 0 . inputs[ 0 ] . repr( self . tcx( ) ) ,
921990 substs. repr( self . tcx( ) ) ) ;
922991
992+ assert ! ( !substs. has_escaping_regions( ) ) ;
993+
923994 // It is possible for type parameters or early-bound lifetimes
924995 // to appear in the signature of `self`. The substitutions we
925996 // are given do not include type/lifetime parameters for the
@@ -949,14 +1020,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
9491020 substs = & placeholder;
9501021 }
9511022
952- // Replace early-bound regions and types.
953- let xform_self_ty = method. fty . sig . 0 . inputs [ 0 ] . subst ( self . tcx ( ) , substs) ;
1023+ // Erase any late-bound regions from the method and substitute
1024+ // in the values from the substitution.
1025+ let xform_self_ty = method. fty . sig . input ( 0 ) ;
1026+ let xform_self_ty = self . erase_late_bound_regions ( & xform_self_ty) ;
1027+ let xform_self_ty = xform_self_ty. subst ( self . tcx ( ) , substs) ;
9541028
955- // Replace late-bound regions bound in the impl or
956- // where-clause (2 levels of binding) and method (1 level of binding).
957- self . erase_late_bound_regions (
958- & self . erase_late_bound_regions (
959- & ty:: Binder ( ty:: Binder ( xform_self_ty) ) ) )
1029+ xform_self_ty
9601030 }
9611031
9621032 fn impl_substs ( & self ,
@@ -1065,6 +1135,9 @@ impl<'tcx> Candidate<'tcx> {
10651135
10661136 WhereClausePick ( ( * trait_ref) . clone ( ) , index)
10671137 }
1138+ ProjectionCandidate ( def_id, index) => {
1139+ TraitPick ( def_id, index)
1140+ }
10681141 }
10691142 }
10701143 }
@@ -1076,6 +1149,7 @@ impl<'tcx> Candidate<'tcx> {
10761149 ExtensionImplCandidate ( def_id, _, _, _) => ImplSource ( def_id) ,
10771150 UnboxedClosureCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
10781151 WhereClauseCandidate ( ref trait_ref, _) => TraitSource ( trait_ref. def_id ( ) ) ,
1152+ ProjectionCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
10791153 }
10801154 }
10811155
@@ -1094,6 +1168,9 @@ impl<'tcx> Candidate<'tcx> {
10941168 WhereClauseCandidate ( ref trait_ref, method_num) => {
10951169 Some ( ( trait_ref. def_id ( ) , method_num) )
10961170 }
1171+ ProjectionCandidate ( trait_def_id, method_num) => {
1172+ Some ( ( trait_def_id, method_num) )
1173+ }
10971174 }
10981175 }
10991176}
@@ -1120,6 +1197,8 @@ impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
11201197 format ! ( "UnboxedClosureCandidate({},{})" , a. repr( tcx) , b) ,
11211198 WhereClauseCandidate ( ref a, ref b) =>
11221199 format ! ( "WhereClauseCandidate({},{})" , a. repr( tcx) , b) ,
1200+ ProjectionCandidate ( ref a, ref b) =>
1201+ format ! ( "ProjectionCandidate({},{})" , a. repr( tcx) , b) ,
11231202 }
11241203 }
11251204}
0 commit comments