@@ -32,6 +32,7 @@ use rustc_middle::ty::{
3232 SizedTraitKind , Ty , TyCtxt , TypeFoldable , TypeVisitableExt , TypingMode , Upcast , elaborate,
3333 may_use_unstable_feature,
3434} ;
35+ use rustc_next_trait_solver:: solve:: AliasBoundKind ;
3536use rustc_span:: { Symbol , sym} ;
3637use tracing:: { debug, instrument, trace} ;
3738
@@ -1628,11 +1629,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16281629 pub ( super ) fn for_each_item_bound < T > (
16291630 & mut self ,
16301631 mut self_ty : Ty < ' tcx > ,
1631- mut for_each : impl FnMut ( & mut Self , ty:: Clause < ' tcx > , usize ) -> ControlFlow < T , ( ) > ,
1632+ mut for_each : impl FnMut (
1633+ & mut Self ,
1634+ ty:: Clause < ' tcx > ,
1635+ usize ,
1636+ AliasBoundKind ,
1637+ ) -> ControlFlow < T , ( ) > ,
16321638 on_ambiguity : impl FnOnce ( ) ,
16331639 ) -> ControlFlow < T , ( ) > {
16341640 let mut idx = 0 ;
1635- let mut in_parent_alias_type = false ;
1641+ let mut alias_bound_kind = AliasBoundKind :: SelfBounds ;
16361642
16371643 loop {
16381644 let ( kind, alias_ty) = match * self_ty. kind ( ) {
@@ -1648,14 +1654,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16481654 // share the same type as `self_ty`. This is because for truly rigid
16491655 // projections, we will never be able to equate, e.g. `<T as Tr>::A`
16501656 // with `<<T as Tr>::A as Tr>::A`.
1651- let relevant_bounds = if in_parent_alias_type {
1657+ let relevant_bounds = if matches ! ( alias_bound_kind , AliasBoundKind :: NonSelfBounds ) {
16521658 self . tcx ( ) . item_non_self_bounds ( alias_ty. def_id )
16531659 } else {
16541660 self . tcx ( ) . item_self_bounds ( alias_ty. def_id )
16551661 } ;
16561662
16571663 for bound in relevant_bounds. instantiate ( self . tcx ( ) , alias_ty. args ) {
1658- for_each ( self , bound, idx) ?;
1664+ for_each ( self , bound, idx, alias_bound_kind ) ?;
16591665 idx += 1 ;
16601666 }
16611667
@@ -1665,7 +1671,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16651671 return ControlFlow :: Continue ( ( ) ) ;
16661672 }
16671673
1668- in_parent_alias_type = true ;
1674+ alias_bound_kind = AliasBoundKind :: NonSelfBounds ;
16691675 }
16701676 }
16711677
@@ -1880,14 +1886,24 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18801886 break ;
18811887 }
18821888
1883- let alias_bound = candidates
1884- . iter ( )
1885- . filter_map ( |c| if let ProjectionCandidate ( i) = c. candidate { Some ( i) } else { None } )
1886- . try_reduce ( |c1, c2| if has_non_region_infer { None } else { Some ( c1. min ( c2) ) } ) ;
1887-
1889+ let mut alias_bounds = candidates. iter ( ) . filter_map ( |c| {
1890+ if let ProjectionCandidate { idx, kind } = c. candidate {
1891+ Some ( ( idx, kind) )
1892+ } else {
1893+ None
1894+ }
1895+ } ) ;
1896+ // Extract non-nested alias bound candidates, will be preferred over where bounds if
1897+ // we're proving an auto-trait, sizedness trait or default trait.
18881898 if matches ! ( candidate_preference_mode, CandidatePreferenceMode :: Marker ) {
1889- match alias_bound {
1890- Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
1899+ match alias_bounds
1900+ . clone ( )
1901+ . filter_map ( |( idx, kind) | ( kind == AliasBoundKind :: SelfBounds ) . then_some ( idx) )
1902+ . try_reduce ( |c1, c2| if has_non_region_infer { None } else { Some ( c1. min ( c2) ) } )
1903+ {
1904+ Some ( Some ( idx) ) => {
1905+ return Some ( ProjectionCandidate { idx, kind : AliasBoundKind :: SelfBounds } ) ;
1906+ }
18911907 Some ( None ) => { }
18921908 None => return None ,
18931909 }
@@ -1926,8 +1942,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
19261942 // fairly arbitrary but once again necessary for backwards compatibility.
19271943 // If there are multiple applicable candidates which don't affect type inference,
19281944 // choose the one with the lowest index.
1929- match alias_bound {
1930- Some ( Some ( index) ) => return Some ( ProjectionCandidate ( index) ) ,
1945+ match alias_bounds. try_reduce ( |( c1, k1) , ( c2, k2) | {
1946+ if has_non_region_infer {
1947+ None
1948+ } else if c1 < c2 {
1949+ Some ( ( c1, k1) )
1950+ } else {
1951+ Some ( ( c2, k2) )
1952+ }
1953+ } ) {
1954+ Some ( Some ( ( idx, kind) ) ) => return Some ( ProjectionCandidate { idx, kind } ) ,
19311955 Some ( None ) => { }
19321956 None => return None ,
19331957 }
@@ -2016,7 +2040,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
20162040 // Non-global param candidates have already been handled, global
20172041 // where-bounds get ignored.
20182042 ParamCandidate ( _) | ImplCandidate ( _) => true ,
2019- ProjectionCandidate ( _ ) | ObjectCandidate ( _) => unreachable ! ( ) ,
2043+ ProjectionCandidate { .. } | ObjectCandidate ( _) => unreachable ! ( ) ,
20202044 } ) {
20212045 return Some ( ImplCandidate ( def_id) ) ;
20222046 } else {
0 commit comments