@@ -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