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