@@ -2052,23 +2052,27 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20522052 match path. res {
20532053 Res :: Def ( DefKind :: TyParam , _) | Res :: SelfTyParam { trait_ : _ } => {
20542054 let mut bounds =
2055- self . for_each_in_scope_predicate ( path. res ) . filter_map ( |trait_ | {
2055+ self . for_each_trait_bound_on_res ( path. res ) . filter_map ( |trait_def_id | {
20562056 BoundVarContext :: supertrait_hrtb_vars (
20572057 self . tcx ,
2058- trait_ . trait_ref . trait_def_id ( ) ? ,
2058+ trait_def_id,
20592059 item_segment. ident ,
20602060 ty:: AssocKind :: Fn ,
20612061 )
20622062 } ) ;
20632063
20642064 let one_bound = bounds. next ( ) ;
2065- let second_bound = bounds. next ( ) ;
20662065
2067- if second_bound. is_some ( ) {
2068- self . tcx
2069- . dcx ( )
2070- . span_delayed_bug ( path. span , "ambiguous resolution for RTN path" ) ;
2071- return ;
2066+ // Don't bail if we have identical bounds, which may be collected from
2067+ // something like `T: Bound + Bound`, or via elaborating supertraits.
2068+ for second_bound in bounds {
2069+ if Some ( & second_bound) != one_bound. as_ref ( ) {
2070+ self . tcx . dcx ( ) . span_delayed_bug (
2071+ path. span ,
2072+ "ambiguous resolution for RTN path" ,
2073+ ) ;
2074+ return ;
2075+ }
20722076 }
20732077
20742078 let Some ( ( bound_vars, assoc_item) ) = one_bound else {
@@ -2077,6 +2081,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20772081 . span_delayed_bug ( path. span , "no resolution for RTN path" ) ;
20782082 return ;
20792083 } ;
2084+
20802085 ( bound_vars, assoc_item. def_id , item_segment)
20812086 }
20822087 // If we have a self type alias (in an impl), try to resolve an
@@ -2143,12 +2148,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21432148 self . record_late_bound_vars ( item_segment. hir_id , existing_bound_vars_saved) ;
21442149 }
21452150
2146- /// Walk the generics of the item for a trait-ref whose self type
2147- /// corresponds to the expected res.
2148- fn for_each_in_scope_predicate (
2151+ /// Walk the generics of the item for a trait bound whose self type
2152+ /// corresponds to the expected res, and return the trait def id .
2153+ fn for_each_trait_bound_on_res (
21492154 & self ,
21502155 expected_res : Res ,
2151- ) -> impl Iterator < Item = & ' tcx hir :: PolyTraitRef < ' tcx > > + use < ' tcx , ' _ > {
2156+ ) -> impl Iterator < Item = DefId > + use < ' tcx , ' _ > {
21522157 std:: iter:: from_coroutine (
21532158 #[ coroutine]
21542159 move || {
@@ -2164,7 +2169,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21642169 | Scope :: ObjectLifetimeDefault { s, .. }
21652170 | Scope :: Supertrait { s, .. }
21662171 | Scope :: TraitRefBoundary { s }
2167- | Scope :: LateBoundary { s, .. } => {
2172+ | Scope :: LateBoundary { s, .. }
2173+ | Scope :: Opaque { s, .. } => {
21682174 next_scope = Some ( s) ;
21692175 continue ;
21702176 }
@@ -2177,7 +2183,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21772183 }
21782184 } ;
21792185 let node = self . tcx . hir_node ( hir_id) ;
2180- if let Some ( generics) = node. generics ( ) {
2186+ // If this is a `Self` bound in a trait, yield the trait itself.
2187+ // Specifically, we don't need to look at any supertraits since
2188+ // we already do that in `BoundVarContext::supertrait_hrtb_vars`.
2189+ if let Res :: SelfTyParam { trait_ : _ } = expected_res
2190+ && let hir:: Node :: Item ( item) = node
2191+ && let hir:: ItemKind :: Trait ( ..) = item. kind
2192+ {
2193+ // Yield the trait's def id. Supertraits will be
2194+ // elaborated from that.
2195+ yield item. owner_id . def_id . to_def_id ( ) ;
2196+ } else if let Some ( generics) = node. generics ( ) {
21812197 for pred in generics. predicates {
21822198 let hir:: WherePredicate :: BoundPredicate ( pred) = pred else {
21832199 continue ;
@@ -2191,24 +2207,24 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21912207 if bounded_path. res != expected_res {
21922208 continue ;
21932209 }
2194- yield pred. bounds ;
2210+ for pred in pred. bounds {
2211+ match pred {
2212+ hir:: GenericBound :: Trait ( poly_trait_ref) => {
2213+ if let Some ( def_id) =
2214+ poly_trait_ref. trait_ref . trait_def_id ( )
2215+ {
2216+ yield def_id;
2217+ }
2218+ }
2219+ hir:: GenericBound :: Outlives ( _)
2220+ | hir:: GenericBound :: Use ( _, _) => { }
2221+ }
2222+ }
21952223 }
21962224 }
2197- // Also consider supertraits for `Self` res...
2198- if let Res :: SelfTyParam { trait_ : _ } = expected_res
2199- && let hir:: Node :: Item ( item) = node
2200- && let hir:: ItemKind :: Trait ( _, _, _, supertraits, _) = item. kind
2201- {
2202- yield supertraits;
2203- }
22042225 }
22052226 } ,
22062227 )
2207- . flatten ( )
2208- . filter_map ( |pred| match pred {
2209- hir:: GenericBound :: Trait ( poly_trait_ref) => Some ( poly_trait_ref) ,
2210- hir:: GenericBound :: Outlives ( _) | hir:: GenericBound :: Use ( _, _) => None ,
2211- } )
22122228 . fuse ( )
22132229 }
22142230}
0 commit comments