@@ -27,8 +27,9 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
27
27
use rustc_middle:: ty:: error:: TypeErrorToStringExt ;
28
28
use rustc_middle:: ty:: print:: { PrintTraitRefExt as _, with_no_trimmed_paths} ;
29
29
use 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,
32
33
} ;
33
34
use rustc_span:: { Symbol , sym} ;
34
35
use tracing:: { debug, instrument, trace} ;
@@ -473,7 +474,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
473
474
}
474
475
} else {
475
476
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
+ {
477
482
self . filter_reservation_impls ( candidate)
478
483
} else {
479
484
Ok ( None )
@@ -1822,6 +1827,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1822
1827
fn winnow_candidates (
1823
1828
& mut self ,
1824
1829
has_non_region_infer : bool ,
1830
+ candidate_preference_mode : CandidatePreferenceMode ,
1825
1831
mut candidates : Vec < EvaluatedCandidate < ' tcx > > ,
1826
1832
) -> Option < SelectionCandidate < ' tcx > > {
1827
1833
if candidates. len ( ) == 1 {
@@ -1875,6 +1881,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1875
1881
break ;
1876
1882
}
1877
1883
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
+
1878
1897
// The next highest priority is for non-global where-bounds. However, while we don't
1879
1898
// prefer global where-clauses here, we do bail with ambiguity when encountering both
1880
1899
// a global and a non-global where-clause.
@@ -1908,10 +1927,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1908
1927
// fairly arbitrary but once again necessary for backwards compatibility.
1909
1928
// If there are multiple applicable candidates which don't affect type inference,
1910
1929
// 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) ) } ) ;
1915
1930
match alias_bound {
1916
1931
Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
1917
1932
Some ( None ) => { }
0 commit comments