@@ -2052,23 +2052,27 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2052
2052
match path. res {
2053
2053
Res :: Def ( DefKind :: TyParam , _) | Res :: SelfTyParam { trait_ : _ } => {
2054
2054
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 | {
2056
2056
BoundVarContext :: supertrait_hrtb_vars (
2057
2057
self . tcx ,
2058
- trait_ . trait_ref . trait_def_id ( ) ? ,
2058
+ trait_def_id,
2059
2059
item_segment. ident ,
2060
2060
ty:: AssocKind :: Fn ,
2061
2061
)
2062
2062
} ) ;
2063
2063
2064
2064
let one_bound = bounds. next ( ) ;
2065
- let second_bound = bounds. next ( ) ;
2066
2065
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
+ }
2072
2076
}
2073
2077
2074
2078
let Some ( ( bound_vars, assoc_item) ) = one_bound else {
@@ -2077,6 +2081,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2077
2081
. span_delayed_bug ( path. span , "no resolution for RTN path" ) ;
2078
2082
return ;
2079
2083
} ;
2084
+
2080
2085
( bound_vars, assoc_item. def_id , item_segment)
2081
2086
}
2082
2087
// If we have a self type alias (in an impl), try to resolve an
@@ -2145,10 +2150,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2145
2150
2146
2151
/// Walk the generics of the item for a trait-ref whose self type
2147
2152
/// corresponds to the expected res.
2148
- fn for_each_in_scope_predicate (
2153
+ fn for_each_trait_bound_on_res (
2149
2154
& self ,
2150
2155
expected_res : Res ,
2151
- ) -> impl Iterator < Item = & ' tcx hir :: PolyTraitRef < ' tcx > > + use < ' tcx , ' _ > {
2156
+ ) -> impl Iterator < Item = DefId > + use < ' tcx , ' _ > {
2152
2157
std:: iter:: from_coroutine (
2153
2158
#[ coroutine]
2154
2159
move || {
@@ -2164,7 +2169,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2164
2169
| Scope :: ObjectLifetimeDefault { s, .. }
2165
2170
| Scope :: Supertrait { s, .. }
2166
2171
| Scope :: TraitRefBoundary { s }
2167
- | Scope :: LateBoundary { s, .. } => {
2172
+ | Scope :: LateBoundary { s, .. }
2173
+ | Scope :: Opaque { s, .. } => {
2168
2174
next_scope = Some ( s) ;
2169
2175
continue ;
2170
2176
}
@@ -2177,7 +2183,15 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2177
2183
}
2178
2184
} ;
2179
2185
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 self.
2187
+ if let Res :: SelfTyParam { trait_ : _ } = expected_res
2188
+ && let hir:: Node :: Item ( item) = node
2189
+ && let hir:: ItemKind :: Trait ( ..) = item. kind
2190
+ {
2191
+ // Yield the trait's def id. Supertraits will be
2192
+ // elaborated from that.
2193
+ yield item. owner_id . def_id . to_def_id ( ) ;
2194
+ } else if let Some ( generics) = node. generics ( ) {
2181
2195
for pred in generics. predicates {
2182
2196
let hir:: WherePredicate :: BoundPredicate ( pred) = pred else {
2183
2197
continue ;
@@ -2191,24 +2205,24 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2191
2205
if bounded_path. res != expected_res {
2192
2206
continue ;
2193
2207
}
2194
- yield pred. bounds ;
2208
+ for pred in pred. bounds {
2209
+ match pred {
2210
+ hir:: GenericBound :: Trait ( poly_trait_ref) => {
2211
+ if let Some ( def_id) =
2212
+ poly_trait_ref. trait_ref . trait_def_id ( )
2213
+ {
2214
+ yield def_id;
2215
+ }
2216
+ }
2217
+ hir:: GenericBound :: Outlives ( _)
2218
+ | hir:: GenericBound :: Use ( _, _) => { }
2219
+ }
2220
+ }
2195
2221
}
2196
2222
}
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
- }
2204
2223
}
2205
2224
} ,
2206
2225
)
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
- } )
2212
2226
. fuse ( )
2213
2227
}
2214
2228
}
0 commit comments