diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 8b457c7ceec..6a33bc88685 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1133,10 +1133,12 @@ pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator bug!("super_trait_of {} is not an item", trait_hir_id), }; - let supertraits = match item.kind { - hir::ItemKind::Trait(.., ref supertraits, _) => supertraits, - hir::ItemKind::TraitAlias(_, ref supertraits) => supertraits, - _ => span_bug!(item.span, "super_trait_of invoked on non-trait"), + let (generics, supertraits) = match item.kind { + hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => { + (generics, supertraits) + } + hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits), + _ => span_bug!(item.span, "super_predicates invoked on non-trait"), }; for supertrait in supertraits.iter() { @@ -1145,6 +1147,26 @@ pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator` would include `u32: PartialEq` + // as one of its "superpredicates". + let is_trait_alias = tcx.is_trait_alias(trait_did); + let self_param_ty = tcx.types.self_param; + for (predicate, _) in icx.type_parameter_bounds_in_generics( + generics, + item.hir_id, + self_param_ty, + OnlySelfBounds(!is_trait_alias), + None, + ) { + if let ty::PredicateAtom::Trait(data, _) = predicate.skip_binders() { + stack.push(data.def_id()); + } + } } else { let generic_predicates = tcx.super_predicates_of(trait_did); for (predicate, _) in generic_predicates.predicates { diff --git a/src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs b/src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs new file mode 100644 index 00000000000..3eb50ab5547 --- /dev/null +++ b/src/test/ui/associated-type-bounds/associated-item-through-where-clause.rs @@ -0,0 +1,21 @@ +// check-pass + +trait Foo { + type Item; +} + +trait Bar +where + Self: Foo, +{ +} + +#[allow(dead_code)] +fn foo(_m: M) +where + M: Bar, + M::Item: Send, +{ +} + +fn main() {}