Skip to content

Commit 5b6f206

Browse files
committed
Fix super_traits_of to consider where bounds
1 parent 4a97c52 commit 5b6f206

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

compiler/rustc_typeck/src/collect.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,10 +1133,12 @@ pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator<It
11331133
_ => bug!("super_trait_of {} is not an item", trait_hir_id),
11341134
};
11351135

1136-
let supertraits = match item.kind {
1137-
hir::ItemKind::Trait(.., ref supertraits, _) => supertraits,
1138-
hir::ItemKind::TraitAlias(_, ref supertraits) => supertraits,
1139-
_ => span_bug!(item.span, "super_trait_of invoked on non-trait"),
1136+
let (generics, supertraits) = match item.kind {
1137+
hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => {
1138+
(generics, supertraits)
1139+
}
1140+
hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
1141+
_ => span_bug!(item.span, "super_predicates invoked on non-trait"),
11401142
};
11411143

11421144
for supertrait in supertraits.iter() {
@@ -1145,6 +1147,26 @@ pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator<It
11451147
stack.push(trait_did);
11461148
}
11471149
}
1150+
1151+
let icx = ItemCtxt::new(tcx, trait_did);
1152+
// Convert any explicit superbounds in the where-clause,
1153+
// e.g., `trait Foo where Self: Bar`.
1154+
// In the case of trait aliases, however, we include all bounds in the where-clause,
1155+
// so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
1156+
// as one of its "superpredicates".
1157+
let is_trait_alias = tcx.is_trait_alias(trait_did);
1158+
let self_param_ty = tcx.types.self_param;
1159+
for (predicate, _) in icx.type_parameter_bounds_in_generics(
1160+
generics,
1161+
item.hir_id,
1162+
self_param_ty,
1163+
OnlySelfBounds(!is_trait_alias),
1164+
None,
1165+
) {
1166+
if let ty::PredicateAtom::Trait(data, _) = predicate.skip_binders() {
1167+
stack.push(data.def_id());
1168+
}
1169+
}
11481170
} else {
11491171
let generic_predicates = tcx.super_predicates_of(trait_did);
11501172
for (predicate, _) in generic_predicates.predicates {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
3+
trait Foo {
4+
type Item;
5+
}
6+
7+
trait Bar
8+
where
9+
Self: Foo,
10+
{
11+
}
12+
13+
#[allow(dead_code)]
14+
fn foo<M>(_m: M)
15+
where
16+
M: Bar,
17+
M::Item: Send,
18+
{
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)