Fix super_traits_of to consider where bounds
This commit is contained in:
parent
4a97c52630
commit
5b6f206d23
2 changed files with 47 additions and 4 deletions
|
@ -1133,10 +1133,12 @@ pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator<It
|
|||
_ => 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<It
|
|||
stack.push(trait_did);
|
||||
}
|
||||
}
|
||||
|
||||
let icx = ItemCtxt::new(tcx, trait_did);
|
||||
// Convert any explicit superbounds in the where-clause,
|
||||
// e.g., `trait Foo where Self: Bar`.
|
||||
// In the case of trait aliases, however, we include all bounds in the where-clause,
|
||||
// so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
|
||||
// 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 {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// check-pass
|
||||
|
||||
trait Foo {
|
||||
type Item;
|
||||
}
|
||||
|
||||
trait Bar
|
||||
where
|
||||
Self: Foo,
|
||||
{
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn foo<M>(_m: M)
|
||||
where
|
||||
M: Bar,
|
||||
M::Item: Send,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue