@@ -27,8 +27,9 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
2727use rustc_middle:: ty:: error:: TypeErrorToStringExt ;
2828use rustc_middle:: ty:: print:: { PrintTraitRefExt as _, with_no_trimmed_paths} ;
2929use rustc_middle:: ty:: {
30- self , DeepRejectCtxt , GenericArgsRef , PolyProjectionPredicate , SizedTraitKind , Ty , TyCtxt ,
31- TypeFoldable , TypeVisitableExt , TypingMode , Upcast , elaborate, may_use_unstable_feature,
30+ self , CandidatePreferenceMode , DeepRejectCtxt , GenericArgsRef , PolyProjectionPredicate ,
31+ SizedTraitKind , Ty , TyCtxt , TypeFoldable , TypeVisitableExt , TypingMode , Upcast , elaborate,
32+ may_use_unstable_feature,
3233} ;
3334use rustc_span:: { Symbol , sym} ;
3435use tracing:: { debug, instrument, trace} ;
@@ -473,7 +474,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
473474 }
474475 } else {
475476 let has_non_region_infer = stack. obligation . predicate . has_non_region_infer ( ) ;
476- if let Some ( candidate) = self . winnow_candidates ( has_non_region_infer, candidates) {
477+ let candidate_preference_mode =
478+ CandidatePreferenceMode :: compute ( self . tcx ( ) , stack. obligation . predicate . def_id ( ) ) ;
479+ if let Some ( candidate) =
480+ self . winnow_candidates ( has_non_region_infer, candidate_preference_mode, candidates)
481+ {
477482 self . filter_reservation_impls ( candidate)
478483 } else {
479484 Ok ( None )
@@ -1822,6 +1827,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18221827 fn winnow_candidates (
18231828 & mut self ,
18241829 has_non_region_infer : bool ,
1830+ candidate_preference_mode : CandidatePreferenceMode ,
18251831 mut candidates : Vec < EvaluatedCandidate < ' tcx > > ,
18261832 ) -> Option < SelectionCandidate < ' tcx > > {
18271833 if candidates. len ( ) == 1 {
@@ -1875,6 +1881,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18751881 break ;
18761882 }
18771883
1884+ let alias_bound = candidates
1885+ . iter ( )
1886+ . filter_map ( |c| if let ProjectionCandidate ( i) = c. candidate { Some ( i) } else { None } )
1887+ . try_reduce ( |c1, c2| if has_non_region_infer { None } else { Some ( c1. min ( c2) ) } ) ;
1888+
1889+ if matches ! ( candidate_preference_mode, CandidatePreferenceMode :: Marker ) {
1890+ match alias_bound {
1891+ Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
1892+ Some ( None ) => { }
1893+ None => return None ,
1894+ }
1895+ }
1896+
18781897 // The next highest priority is for non-global where-bounds. However, while we don't
18791898 // prefer global where-clauses here, we do bail with ambiguity when encountering both
18801899 // a global and a non-global where-clause.
@@ -1908,10 +1927,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
19081927 // fairly arbitrary but once again necessary for backwards compatibility.
19091928 // If there are multiple applicable candidates which don't affect type inference,
19101929 // choose the one with the lowest index.
1911- let alias_bound = candidates
1912- . iter ( )
1913- . filter_map ( |c| if let ProjectionCandidate ( i) = c. candidate { Some ( i) } else { None } )
1914- . try_reduce ( |c1, c2| if has_non_region_infer { None } else { Some ( c1. min ( c2) ) } ) ;
19151930 match alias_bound {
19161931 Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
19171932 Some ( None ) => { }
0 commit comments