@@ -18,7 +18,7 @@ use middle::fast_reject;
18
18
use middle:: subst;
19
19
use middle:: subst:: Subst ;
20
20
use middle:: traits;
21
- use middle:: ty:: { self , Ty , ToPolyTraitRef } ;
21
+ use middle:: ty:: { self , RegionEscape , Ty , ToPolyTraitRef } ;
22
22
use middle:: ty_fold:: TypeFoldable ;
23
23
use middle:: infer;
24
24
use middle:: infer:: InferCtxt ;
@@ -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 > {
@@ -309,18 +310,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
309
310
// argument type like `&Trait`.
310
311
let trait_ref = data. principal_trait_ref_with_self_ty ( self . tcx ( ) , self_ty) ;
311
312
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
+
312
315
let vtable_index =
313
316
traits:: get_vtable_index_of_object_method ( tcx,
314
317
trait_ref. clone ( ) ,
315
- new_trait_ref. def_id ( ) ,
318
+ new_trait_ref. def_id ,
316
319
method_num) ;
317
320
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 ) ;
319
322
320
323
this. inherent_candidates . push ( Candidate {
321
324
xform_self_ty : xform_self_ty,
322
325
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)
324
327
} ) ;
325
328
} ) ;
326
329
}
@@ -353,34 +356,37 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
353
356
} )
354
357
. collect ( ) ;
355
358
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
+
357
363
let xform_self_ty =
358
- this. xform_self_ty ( & m, trait_ref. substs ( ) ) ;
364
+ this. xform_self_ty ( & m, trait_ref. substs ) ;
359
365
360
366
debug ! ( "found match: trait_ref={} substs={} m={}" ,
361
367
trait_ref. repr( this. tcx( ) ) ,
362
- trait_ref. substs( ) . repr( this. tcx( ) ) ,
368
+ trait_ref. substs. repr( this. tcx( ) ) ,
363
369
m. repr( this. tcx( ) ) ) ;
364
370
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( ) ) ;
366
372
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( ) ) ;
368
374
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( ) ) ;
370
376
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( ) ) ;
372
378
373
379
// Because this trait derives from a where-clause, it
374
380
// should not contain any inference variables or other
375
381
// artifacts. This means it is safe to put into the
376
382
// `WhereClauseCandidate` and (eventually) into the
377
383
// `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) ) ) ;
379
385
380
386
this. inherent_candidates . push ( Candidate {
381
387
xform_self_ty : xform_self_ty,
382
388
method_ty : m,
383
- kind : WhereClauseCandidate ( trait_ref , method_num)
389
+ kind : WhereClauseCandidate ( poly_trait_ref , method_num)
384
390
} ) ;
385
391
} ) ;
386
392
}
@@ -474,6 +480,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
474
480
method. clone ( ) ,
475
481
matching_index) ;
476
482
483
+ self . assemble_projection_candidates ( trait_def_id,
484
+ method. clone ( ) ,
485
+ matching_index) ;
486
+
477
487
self . assemble_where_clause_candidates ( trait_def_id,
478
488
method,
479
489
matching_index) ;
@@ -603,6 +613,64 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
603
613
}
604
614
}
605
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 ( ) )
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
+
606
674
fn assemble_where_clause_candidates ( & mut self ,
607
675
trait_def_id : ast:: DefId ,
608
676
method_ty : Rc < ty:: Method < ' tcx > > ,
@@ -611,14 +679,14 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
611
679
debug ! ( "assemble_where_clause_candidates(trait_def_id={})" ,
612
680
trait_def_id. repr( self . tcx( ) ) ) ;
613
681
614
- // Check whether there are any where-clauses pertaining to this trait.
615
682
let caller_predicates =
616
683
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)
620
687
{
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 ) ;
622
690
623
691
debug ! ( "assemble_where_clause_candidates: bound={} xform_self_ty={}" ,
624
692
bound. repr( self . tcx( ) ) ,
@@ -627,7 +695,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
627
695
self . extension_candidates . push ( Candidate {
628
696
xform_self_ty : xform_self_ty,
629
697
method_ty : method_ty. clone ( ) ,
630
- kind : WhereClauseCandidate ( bound , method_index)
698
+ kind : WhereClauseCandidate ( poly_bound , method_index)
631
699
} ) ;
632
700
}
633
701
}
@@ -829,6 +897,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
829
897
norm_obligations. iter ( ) . all ( |o| selcx. evaluate_obligation ( o) )
830
898
}
831
899
900
+ ProjectionCandidate ( ..) |
832
901
ObjectCandidate ( ..) |
833
902
UnboxedClosureCandidate ( ..) |
834
903
WhereClauseCandidate ( ..) => {
@@ -920,6 +989,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
920
989
method. fty. sig. 0 . inputs[ 0 ] . repr( self . tcx( ) ) ,
921
990
substs. repr( self . tcx( ) ) ) ;
922
991
992
+ assert ! ( !substs. has_escaping_regions( ) ) ;
993
+
923
994
// It is possible for type parameters or early-bound lifetimes
924
995
// to appear in the signature of `self`. The substitutions we
925
996
// are given do not include type/lifetime parameters for the
@@ -949,14 +1020,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
949
1020
substs = & placeholder;
950
1021
}
951
1022
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) ;
954
1028
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
960
1030
}
961
1031
962
1032
fn impl_substs ( & self ,
@@ -1065,6 +1135,9 @@ impl<'tcx> Candidate<'tcx> {
1065
1135
1066
1136
WhereClausePick ( ( * trait_ref) . clone ( ) , index)
1067
1137
}
1138
+ ProjectionCandidate ( def_id, index) => {
1139
+ TraitPick ( def_id, index)
1140
+ }
1068
1141
}
1069
1142
}
1070
1143
}
@@ -1076,6 +1149,7 @@ impl<'tcx> Candidate<'tcx> {
1076
1149
ExtensionImplCandidate ( def_id, _, _, _) => ImplSource ( def_id) ,
1077
1150
UnboxedClosureCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
1078
1151
WhereClauseCandidate ( ref trait_ref, _) => TraitSource ( trait_ref. def_id ( ) ) ,
1152
+ ProjectionCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
1079
1153
}
1080
1154
}
1081
1155
@@ -1094,6 +1168,9 @@ impl<'tcx> Candidate<'tcx> {
1094
1168
WhereClauseCandidate ( ref trait_ref, method_num) => {
1095
1169
Some ( ( trait_ref. def_id ( ) , method_num) )
1096
1170
}
1171
+ ProjectionCandidate ( trait_def_id, method_num) => {
1172
+ Some ( ( trait_def_id, method_num) )
1173
+ }
1097
1174
}
1098
1175
}
1099
1176
}
@@ -1120,6 +1197,8 @@ impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
1120
1197
format ! ( "UnboxedClosureCandidate({},{})" , a. repr( tcx) , b) ,
1121
1198
WhereClauseCandidate ( ref a, ref b) =>
1122
1199
format ! ( "WhereClauseCandidate({},{})" , a. repr( tcx) , b) ,
1200
+ ProjectionCandidate ( ref a, ref b) =>
1201
+ format ! ( "ProjectionCandidate({},{})" , a. repr( tcx) , b) ,
1123
1202
}
1124
1203
}
1125
1204
}
0 commit comments