@@ -2061,23 +2061,27 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20612061                match  path. res  { 
20622062                    Res :: Def ( DefKind :: TyParam ,  _)  | Res :: SelfTyParam  {  trait_ :  _ }  => { 
20632063                        let  mut  bounds =
2064-                             self . for_each_in_scope_predicate ( path. res ) . filter_map ( |trait_ | { 
2064+                             self . for_each_trait_bound_on_res ( path. res ) . filter_map ( |trait_def_id | { 
20652065                                BoundVarContext :: supertrait_hrtb_vars ( 
20662066                                    self . tcx , 
2067-                                     trait_ . trait_ref . trait_def_id ( ) ? , 
2067+                                     trait_def_id, 
20682068                                    item_segment. ident , 
20692069                                    ty:: AssocKind :: Fn , 
20702070                                ) 
20712071                            } ) ; 
20722072
20732073                        let  one_bound = bounds. next ( ) ; 
2074-                         let  second_bound = bounds. next ( ) ; 
20752074
2076-                         if  second_bound. is_some ( )  { 
2077-                             self . tcx 
2078-                                 . dcx ( ) 
2079-                                 . span_delayed_bug ( path. span ,  "ambiguous resolution for RTN path" ) ; 
2080-                             return ; 
2075+                         // Don't bail if we have identical bounds, which may be collected from 
2076+                         // something like `T: Bound + Bound`, or via elaborating supertraits. 
2077+                         for  second_bound in  bounds { 
2078+                             if  Some ( & second_bound)  != one_bound. as_ref ( )  { 
2079+                                 self . tcx . dcx ( ) . span_delayed_bug ( 
2080+                                     path. span , 
2081+                                     "ambiguous resolution for RTN path" , 
2082+                                 ) ; 
2083+                                 return ; 
2084+                             } 
20812085                        } 
20822086
20832087                        let  Some ( ( bound_vars,  assoc_item) )  = one_bound else  { 
@@ -2086,6 +2090,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20862090                                . span_delayed_bug ( path. span ,  "no resolution for RTN path" ) ; 
20872091                            return ; 
20882092                        } ; 
2093+ 
20892094                        ( bound_vars,  assoc_item. def_id ,  item_segment) 
20902095                    } 
20912096                    // If we have a self type alias (in an impl), try to resolve an 
@@ -2152,12 +2157,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21522157        self . record_late_bound_vars ( item_segment. hir_id ,  existing_bound_vars_saved) ; 
21532158    } 
21542159
2155-     /// Walk the generics of the item for a trait-ref  whose self type 
2156-      /// corresponds to the expected res. 
2157-      fn  for_each_in_scope_predicate ( 
2160+     /// Walk the generics of the item for a trait bound  whose self type 
2161+      /// corresponds to the expected res, and return the trait def id . 
2162+      fn  for_each_trait_bound_on_res ( 
21582163        & self , 
21592164        expected_res :  Res , 
2160-     )  -> impl  Iterator < Item  = & ' tcx  hir :: PolyTraitRef < ' tcx > >  + use < ' tcx ,  ' _ >  { 
2165+     )  -> impl  Iterator < Item  = DefId >  + use < ' tcx ,  ' _ >  { 
21612166        std:: iter:: from_coroutine ( 
21622167            #[ coroutine]  
21632168            move  || { 
@@ -2173,7 +2178,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21732178                        | Scope :: ObjectLifetimeDefault  {  s,  .. } 
21742179                        | Scope :: Supertrait  {  s,  .. } 
21752180                        | Scope :: TraitRefBoundary  {  s } 
2176-                         | Scope :: LateBoundary  {  s,  .. }  => { 
2181+                         | Scope :: LateBoundary  {  s,  .. } 
2182+                         | Scope :: Opaque  {  s,  .. }  => { 
21772183                            next_scope = Some ( s) ; 
21782184                            continue ; 
21792185                        } 
@@ -2186,7 +2192,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21862192                        } 
21872193                    } ; 
21882194                    let  node = self . tcx . hir_node ( hir_id) ; 
2189-                     if  let  Some ( generics)  = node. generics ( )  { 
2195+                     // If this is a `Self` bound in a trait, yield the trait itself. 
2196+                     // Specifically, we don't need to look at any supertraits since 
2197+                     // we already do that in `BoundVarContext::supertrait_hrtb_vars`. 
2198+                     if  let  Res :: SelfTyParam  {  trait_ :  _ }  = expected_res
2199+                         && let  hir:: Node :: Item ( item)  = node
2200+                         && let  hir:: ItemKind :: Trait ( ..)  = item. kind 
2201+                     { 
2202+                         // Yield the trait's def id. Supertraits will be 
2203+                         // elaborated from that. 
2204+                         yield  item. owner_id . def_id . to_def_id ( ) ; 
2205+                     }  else  if  let  Some ( generics)  = node. generics ( )  { 
21902206                        for  pred in  generics. predicates  { 
21912207                            let  hir:: WherePredicateKind :: BoundPredicate ( pred)  = pred. kind  else  { 
21922208                                continue ; 
@@ -2200,24 +2216,24 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
22002216                            if  bounded_path. res  != expected_res { 
22012217                                continue ; 
22022218                            } 
2203-                             yield  pred. bounds ; 
2219+                             for  pred in  pred. bounds  { 
2220+                                 match  pred { 
2221+                                     hir:: GenericBound :: Trait ( poly_trait_ref)  => { 
2222+                                         if  let  Some ( def_id)  =
2223+                                             poly_trait_ref. trait_ref . trait_def_id ( ) 
2224+                                         { 
2225+                                             yield  def_id; 
2226+                                         } 
2227+                                     } 
2228+                                     hir:: GenericBound :: Outlives ( _) 
2229+                                     | hir:: GenericBound :: Use ( _,  _)  => { } 
2230+                                 } 
2231+                             } 
22042232                        } 
22052233                    } 
2206-                     // Also consider supertraits for `Self` res... 
2207-                     if  let  Res :: SelfTyParam  {  trait_ :  _ }  = expected_res
2208-                         && let  hir:: Node :: Item ( item)  = node
2209-                         && let  hir:: ItemKind :: Trait ( _,  _,  _,  supertraits,  _)  = item. kind 
2210-                     { 
2211-                         yield  supertraits; 
2212-                     } 
22132234                } 
22142235            } , 
22152236        ) 
2216-         . flatten ( ) 
2217-         . filter_map ( |pred| match  pred { 
2218-             hir:: GenericBound :: Trait ( poly_trait_ref)  => Some ( poly_trait_ref) , 
2219-             hir:: GenericBound :: Outlives ( _)  | hir:: GenericBound :: Use ( _,  _)  => None , 
2220-         } ) 
22212237        . fuse ( ) 
22222238    } 
22232239} 
0 commit comments