@@ -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> {
16281629pub ( 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