@@ -2061,23 +2061,27 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2061
2061
match path. res {
2062
2062
Res :: Def ( DefKind :: TyParam , _) | Res :: SelfTyParam { trait_ : _ } => {
2063
2063
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 | {
2065
2065
BoundVarContext :: supertrait_hrtb_vars (
2066
2066
self . tcx ,
2067
- trait_ . trait_ref . trait_def_id ( ) ? ,
2067
+ trait_def_id,
2068
2068
item_segment. ident ,
2069
2069
ty:: AssocKind :: Fn ,
2070
2070
)
2071
2071
} ) ;
2072
2072
2073
2073
let one_bound = bounds. next ( ) ;
2074
- let second_bound = bounds. next ( ) ;
2075
2074
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
+ }
2081
2085
}
2082
2086
2083
2087
let Some ( ( bound_vars, assoc_item) ) = one_bound else {
@@ -2086,6 +2090,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2086
2090
. span_delayed_bug ( path. span , "no resolution for RTN path" ) ;
2087
2091
return ;
2088
2092
} ;
2093
+
2089
2094
( bound_vars, assoc_item. def_id , item_segment)
2090
2095
}
2091
2096
// If we have a self type alias (in an impl), try to resolve an
@@ -2152,12 +2157,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2152
2157
self . record_late_bound_vars ( item_segment. hir_id , existing_bound_vars_saved) ;
2153
2158
}
2154
2159
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 (
2158
2163
& self ,
2159
2164
expected_res : Res ,
2160
- ) -> impl Iterator < Item = & ' tcx hir :: PolyTraitRef < ' tcx > > + use < ' tcx , ' _ > {
2165
+ ) -> impl Iterator < Item = DefId > + use < ' tcx , ' _ > {
2161
2166
std:: iter:: from_coroutine (
2162
2167
#[ coroutine]
2163
2168
move || {
@@ -2173,7 +2178,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2173
2178
| Scope :: ObjectLifetimeDefault { s, .. }
2174
2179
| Scope :: Supertrait { s, .. }
2175
2180
| Scope :: TraitRefBoundary { s }
2176
- | Scope :: LateBoundary { s, .. } => {
2181
+ | Scope :: LateBoundary { s, .. }
2182
+ | Scope :: Opaque { s, .. } => {
2177
2183
next_scope = Some ( s) ;
2178
2184
continue ;
2179
2185
}
@@ -2186,7 +2192,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2186
2192
}
2187
2193
} ;
2188
2194
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 ( ) {
2190
2206
for pred in generics. predicates {
2191
2207
let hir:: WherePredicateKind :: BoundPredicate ( pred) = pred. kind else {
2192
2208
continue ;
@@ -2200,24 +2216,24 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
2200
2216
if bounded_path. res != expected_res {
2201
2217
continue ;
2202
2218
}
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
+ }
2204
2232
}
2205
2233
}
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
- }
2213
2234
}
2214
2235
} ,
2215
2236
)
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
- } )
2221
2237
. fuse ( )
2222
2238
}
2223
2239
}
0 commit comments