@@ -28,8 +28,9 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
2828use rustc_middle:: ty:: error:: TypeErrorToStringExt ;
2929use rustc_middle:: ty:: print:: { PrintTraitRefExt as _, with_no_trimmed_paths} ;
3030use rustc_middle:: ty:: {
31- self , DeepRejectCtxt , GenericArgsRef , PolyProjectionPredicate , SizedTraitKind , Ty , TyCtxt ,
32- TypeFoldable , TypeVisitableExt , TypingMode , Upcast , elaborate, may_use_unstable_feature,
31+ self , CandidatePreferenceMode , DeepRejectCtxt , GenericArgsRef , PolyProjectionPredicate ,
32+ SizedTraitKind , Ty , TyCtxt , TypeFoldable , TypeVisitableExt , TypingMode , Upcast , elaborate,
33+ may_use_unstable_feature,
3334} ;
3435use rustc_span:: { Symbol , sym} ;
3536use tracing:: { debug, instrument, trace} ;
@@ -474,7 +475,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
474475 }
475476 } else {
476477 let has_non_region_infer = stack. obligation . predicate . has_non_region_infer ( ) ;
477- if let Some ( candidate) = self . winnow_candidates ( has_non_region_infer, candidates) {
478+ let candidate_preference_mode =
479+ CandidatePreferenceMode :: compute ( self . tcx ( ) , stack. obligation . predicate . def_id ( ) ) ;
480+ if let Some ( candidate) =
481+ self . winnow_candidates ( has_non_region_infer, candidate_preference_mode, candidates)
482+ {
478483 self . filter_reservation_impls ( candidate)
479484 } else {
480485 Ok ( None )
@@ -1824,6 +1829,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18241829 fn winnow_candidates (
18251830 & mut self ,
18261831 has_non_region_infer : bool ,
1832+ candidate_preference_mode : CandidatePreferenceMode ,
18271833 mut candidates : Vec < EvaluatedCandidate < ' tcx > > ,
18281834 ) -> Option < SelectionCandidate < ' tcx > > {
18291835 if candidates. len ( ) == 1 {
@@ -1877,6 +1883,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18771883 break ;
18781884 }
18791885
1886+ let alias_bound = candidates
1887+ . iter ( )
1888+ . filter_map ( |c| if let ProjectionCandidate ( i) = c. candidate { Some ( i) } else { None } )
1889+ . try_reduce ( |c1, c2| if has_non_region_infer { None } else { Some ( c1. min ( c2) ) } ) ;
1890+
1891+ if matches ! ( candidate_preference_mode, CandidatePreferenceMode :: Marker ) {
1892+ match alias_bound {
1893+ Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
1894+ Some ( None ) => { }
1895+ None => return None ,
1896+ }
1897+ }
1898+
18801899 // The next highest priority is for non-global where-bounds. However, while we don't
18811900 // prefer global where-clauses here, we do bail with ambiguity when encountering both
18821901 // a global and a non-global where-clause.
@@ -1910,10 +1929,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
19101929 // fairly arbitrary but once again necessary for backwards compatibility.
19111930 // If there are multiple applicable candidates which don't affect type inference,
19121931 // choose the one with the lowest index.
1913- let alias_bound = candidates
1914- . iter ( )
1915- . filter_map ( |c| if let ProjectionCandidate ( i) = c. candidate { Some ( i) } else { None } )
1916- . try_reduce ( |c1, c2| if has_non_region_infer { None } else { Some ( c1. min ( c2) ) } ) ;
19171932 match alias_bound {
19181933 Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
19191934 Some ( None ) => { }
0 commit comments