@@ -2059,23 +2059,27 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20592059 match path. res {
20602060 Res :: Def ( DefKind :: TyParam , _) | Res :: SelfTyParam { trait_ : _ } => {
20612061 let mut bounds =
2062- self . for_each_in_scope_predicate ( path. res ) . filter_map ( |trait_ | {
2062+ self . for_each_trait_bound_on_res ( path. res ) . filter_map ( |trait_def_id | {
20632063 BoundVarContext :: supertrait_hrtb_vars (
20642064 self . tcx ,
2065- trait_ . trait_ref . trait_def_id ( ) ? ,
2065+ trait_def_id,
20662066 item_segment. ident ,
20672067 ty:: AssocKind :: Fn ,
20682068 )
20692069 } ) ;
20702070
20712071 let one_bound = bounds. next ( ) ;
2072- let second_bound = bounds. next ( ) ;
20732072
2074- if second_bound. is_some ( ) {
2075- self . tcx
2076- . dcx ( )
2077- . span_delayed_bug ( path. span , "ambiguous resolution for RTN path" ) ;
2078- return ;
2073+ // Don't bail if we have identical bounds, which may be collected from
2074+ // something like `T: Bound + Bound`, or via elaborating supertraits.
2075+ for second_bound in bounds {
2076+ if Some ( & second_bound) != one_bound. as_ref ( ) {
2077+ self . tcx . dcx ( ) . span_delayed_bug (
2078+ path. span ,
2079+ "ambiguous resolution for RTN path" ,
2080+ ) ;
2081+ return ;
2082+ }
20792083 }
20802084
20812085 let Some ( ( bound_vars, assoc_item) ) = one_bound else {
@@ -2084,6 +2088,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20842088 . span_delayed_bug ( path. span , "no resolution for RTN path" ) ;
20852089 return ;
20862090 } ;
2091+
20872092 ( bound_vars, assoc_item. def_id , item_segment)
20882093 }
20892094 // If we have a self type alias (in an impl), try to resolve an
@@ -2150,12 +2155,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21502155 self . record_late_bound_vars ( item_segment. hir_id , existing_bound_vars_saved) ;
21512156 }
21522157
2153- /// Walk the generics of the item for a trait-ref whose self type
2154- /// corresponds to the expected res.
2155- fn for_each_in_scope_predicate (
2158+ /// Walk the generics of the item for a trait bound whose self type
2159+ /// corresponds to the expected res, and return the trait def id .
2160+ fn for_each_trait_bound_on_res (
21562161 & self ,
21572162 expected_res : Res ,
2158- ) -> impl Iterator < Item = & ' tcx hir :: PolyTraitRef < ' tcx > > + use < ' tcx , ' _ > {
2163+ ) -> impl Iterator < Item = DefId > + use < ' tcx , ' _ > {
21592164 std:: iter:: from_coroutine (
21602165 #[ coroutine]
21612166 move || {
@@ -2171,7 +2176,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21712176 | Scope :: ObjectLifetimeDefault { s, .. }
21722177 | Scope :: Supertrait { s, .. }
21732178 | Scope :: TraitRefBoundary { s }
2174- | Scope :: LateBoundary { s, .. } => {
2179+ | Scope :: LateBoundary { s, .. }
2180+ | Scope :: Opaque { s, .. } => {
21752181 next_scope = Some ( s) ;
21762182 continue ;
21772183 }
@@ -2184,7 +2190,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21842190 }
21852191 } ;
21862192 let node = self . tcx . hir_node ( hir_id) ;
2187- if let Some ( generics) = node. generics ( ) {
2193+ // If this is a `Self` bound in a trait, yield the trait itself.
2194+ // Specifically, we don't need to look at any supertraits since
2195+ // we already do that in `BoundVarContext::supertrait_hrtb_vars`.
2196+ if let Res :: SelfTyParam { trait_ : _ } = expected_res
2197+ && let hir:: Node :: Item ( item) = node
2198+ && let hir:: ItemKind :: Trait ( ..) = item. kind
2199+ {
2200+ // Yield the trait's def id. Supertraits will be
2201+ // elaborated from that.
2202+ yield item. owner_id . def_id . to_def_id ( ) ;
2203+ } else if let Some ( generics) = node. generics ( ) {
21882204 for pred in generics. predicates {
21892205 let hir:: WherePredicate :: BoundPredicate ( pred) = pred else {
21902206 continue ;
@@ -2198,24 +2214,24 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21982214 if bounded_path. res != expected_res {
21992215 continue ;
22002216 }
2201- yield pred. bounds ;
2217+ for pred in pred. bounds {
2218+ match pred {
2219+ hir:: GenericBound :: Trait ( poly_trait_ref) => {
2220+ if let Some ( def_id) =
2221+ poly_trait_ref. trait_ref . trait_def_id ( )
2222+ {
2223+ yield def_id;
2224+ }
2225+ }
2226+ hir:: GenericBound :: Outlives ( _)
2227+ | hir:: GenericBound :: Use ( _, _) => { }
2228+ }
2229+ }
22022230 }
22032231 }
2204- // Also consider supertraits for `Self` res...
2205- if let Res :: SelfTyParam { trait_ : _ } = expected_res
2206- && let hir:: Node :: Item ( item) = node
2207- && let hir:: ItemKind :: Trait ( _, _, _, supertraits, _) = item. kind
2208- {
2209- yield supertraits;
2210- }
22112232 }
22122233 } ,
22132234 )
2214- . flatten ( )
2215- . filter_map ( |pred| match pred {
2216- hir:: GenericBound :: Trait ( poly_trait_ref) => Some ( poly_trait_ref) ,
2217- hir:: GenericBound :: Outlives ( _) | hir:: GenericBound :: Use ( _, _) => None ,
2218- } )
22192235 . fuse ( )
22202236 }
22212237}
0 commit comments