@@ -206,7 +206,7 @@ enum SelectionCandidate<'tcx> {
206206
207207 /// This is a trait matching with a projected type as `Self`, and
208208 /// we found an applicable bound in the trait definition.
209- ProjectionCandidate ,
209+ ProjectionCandidate ( ty :: PolyTraitRef < ' tcx > ) ,
210210
211211 /// Implementation of a `Fn`-family trait by one of the anonymous types
212212 /// generated for a `||` expression. The ty::ClosureKind informs the
@@ -238,7 +238,9 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
238238 DefaultImplObjectCandidate ( def_id) => {
239239 DefaultImplObjectCandidate ( def_id)
240240 }
241- ProjectionCandidate => ProjectionCandidate ,
241+ ProjectionCandidate ( ref bound) => {
242+ return tcx. lift ( bound) . map ( ProjectionCandidate ) ;
243+ }
242244 FnPointerCandidate => FnPointerCandidate ,
243245 ObjectCandidate => ObjectCandidate ,
244246 BuiltinObjectCandidate => BuiltinObjectCandidate ,
@@ -1170,22 +1172,20 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11701172 debug ! ( "assemble_candidates_for_projected_tys: trait_def_id={:?}" ,
11711173 trait_def_id) ;
11721174
1173- let result = self . probe ( |this, snapshot| {
1175+ self . in_snapshot ( |this, snapshot| {
11741176 this. match_projection_obligation_against_bounds_from_trait ( obligation,
1175- snapshot)
1177+ candidates,
1178+ snapshot) ;
11761179 } ) ;
1177-
1178- if result {
1179- candidates. vec . push ( ProjectionCandidate ) ;
1180- }
11811180 }
11821181
11831182 fn match_projection_obligation_against_bounds_from_trait (
11841183 & mut self ,
11851184 obligation : & TraitObligation < ' tcx > ,
1185+ candidates : & mut SelectionCandidateSet < ' tcx > ,
11861186 snapshot : & infer:: CombinedSnapshot )
1187- -> bool
11881187 {
1188+
11891189 let poly_trait_predicate =
11901190 self . infcx ( ) . resolve_type_vars_if_possible ( & obligation. predicate ) ;
11911191 let ( skol_trait_predicate, skol_map) =
@@ -1215,36 +1215,19 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12151215 bounds={:?}",
12161216 bounds) ;
12171217
1218- let matching_bound =
1218+ let matching_bounds =
12191219 util:: elaborate_predicates ( self . tcx ( ) , bounds. predicates . into_vec ( ) )
12201220 . filter_to_traits ( )
1221- . find (
1221+ . filter (
12221222 |bound| self . probe (
12231223 |this, _| this. match_projection ( obligation,
12241224 bound. clone ( ) ,
12251225 skol_trait_predicate. trait_ref . clone ( ) ,
12261226 & skol_map,
1227- snapshot) ) ) ;
1228-
1229- debug ! ( "match_projection_obligation_against_bounds_from_trait: \
1230- matching_bound={:?}",
1231- matching_bound) ;
1232- match matching_bound {
1233- None => false ,
1234- Some ( bound) => {
1235- // Repeat the successful match, if any, this time outside of a probe.
1236- let result = self . match_projection ( obligation,
1237- bound,
1238- skol_trait_predicate. trait_ref . clone ( ) ,
1239- & skol_map,
1240- snapshot) ;
1241-
1242- self . infcx . pop_skolemized ( skol_map, snapshot) ;
1227+ snapshot) ) )
1228+ . map ( |bound| ProjectionCandidate ( bound) ) ;
12431229
1244- assert ! ( result) ;
1245- true
1246- }
1247- }
1230+ candidates. vec . extend ( matching_bounds) ;
12481231 }
12491232
12501233 fn match_projection ( & mut self ,
@@ -1684,7 +1667,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
16841667
16851668 match other. candidate {
16861669 ObjectCandidate |
1687- ParamCandidate ( _) | ProjectionCandidate => match victim. candidate {
1670+ ParamCandidate ( _) | ProjectionCandidate ( .. ) => match victim. candidate {
16881671 DefaultImplCandidate ( ..) => {
16891672 bug ! (
16901673 "default implementations shouldn't be recorded \
@@ -1701,11 +1684,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
17011684 // for impls.
17021685 true
17031686 }
1704- ObjectCandidate |
1705- ProjectionCandidate => {
1706- // Arbitrarily give param candidates priority
1707- // over projection and object candidates.
1708- true
1687+ // Arbitrarily give param candidates priority
1688+ // over projection and object candidates.
1689+ ObjectCandidate => true ,
1690+ ProjectionCandidate ( ..) => {
1691+ if let ProjectionCandidate ( ..) = other. candidate {
1692+ // Not identical, since equality is checked at the start
1693+ false
1694+ } else {
1695+ true
1696+ }
17091697 } ,
17101698 ParamCandidate ( ..) => false ,
17111699 } ,
@@ -2056,8 +2044,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
20562044 Ok ( VtableFnPointer ( data) )
20572045 }
20582046
2059- ProjectionCandidate => {
2060- self . confirm_projection_candidate ( obligation) ;
2047+ ProjectionCandidate ( bound ) => {
2048+ self . confirm_projection_candidate ( obligation, bound ) ;
20612049 Ok ( VtableParam ( Vec :: new ( ) ) )
20622050 }
20632051
@@ -2069,14 +2057,27 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
20692057 }
20702058
20712059 fn confirm_projection_candidate ( & mut self ,
2072- obligation : & TraitObligation < ' tcx > )
2060+ obligation : & TraitObligation < ' tcx > ,
2061+ matching_bound : ty:: PolyTraitRef < ' tcx > )
20732062 {
2063+ debug ! ( "confirm_projection_candidate: matching_bound={:?}" , matching_bound) ;
2064+
20742065 self . in_snapshot ( |this, snapshot| {
2075- let result =
2076- this. match_projection_obligation_against_bounds_from_trait ( obligation,
2077- snapshot) ;
2066+ let poly_trait_predicate =
2067+ this. infcx ( ) . resolve_type_vars_if_possible ( & obligation. predicate ) ;
2068+ let ( skol_trait_predicate, skol_map) =
2069+ this. infcx ( ) . skolemize_late_bound_regions ( & poly_trait_predicate, snapshot) ;
2070+
2071+ // Repeat the successful match, if any, this time outside of a probe.
2072+ let result = this. match_projection ( obligation,
2073+ matching_bound,
2074+ skol_trait_predicate. trait_ref . clone ( ) ,
2075+ & skol_map,
2076+ snapshot) ;
2077+ this. infcx . pop_skolemized ( skol_map, snapshot) ;
2078+
20782079 assert ! ( result) ;
2079- } )
2080+ } ) ;
20802081 }
20812082
20822083 fn confirm_param_candidate ( & mut self ,
0 commit comments