Higher-ranked trait bounds for where clauses

This commit is contained in:
Lukas Wirth 2020-12-17 22:01:42 +01:00
parent c8c58d81ec
commit fa65d6ba85
4 changed files with 74 additions and 18 deletions

View file

@ -675,7 +675,8 @@ impl GenericPredicate {
where_predicate: &'a WherePredicate,
) -> impl Iterator<Item = GenericPredicate> + 'a {
match where_predicate {
WherePredicate::TypeBound { target, bound } => {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => {
let self_ty = match target {
WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
WherePredicateTypeTarget::TypeParam(param_id) => {
@ -888,14 +889,13 @@ pub(crate) fn generic_predicates_for_param_query(
.where_predicates_in_scope()
// we have to filter out all other predicates *first*, before attempting to lower them
.filter(|pred| match pred {
WherePredicate::TypeBound {
target: WherePredicateTypeTarget::TypeRef(type_ref),
..
} => Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id),
WherePredicate::TypeBound {
target: WherePredicateTypeTarget::TypeParam(local_id),
..
} => *local_id == param_id.local_id,
WherePredicate::ForLifetime { target, .. }
| WherePredicate::TypeBound { target, .. } => match target {
WherePredicateTypeTarget::TypeRef(type_ref) => {
Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
}
WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id,
},
WherePredicate::Lifetime { .. } => false,
})
.flat_map(|pred| {

View file

@ -5,7 +5,9 @@ use std::sync::Arc;
use hir_def::{
adt::VariantData,
db::DefDatabase,
generics::{GenericParams, TypeParamData, TypeParamProvenance, WherePredicateTypeTarget},
generics::{
GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
},
path::Path,
resolver::{HasResolver, TypeNs},
type_ref::TypeRef,
@ -27,7 +29,8 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
.where_predicates
.iter()
.filter_map(|pred| match pred {
hir_def::generics::WherePredicate::TypeBound { target, bound } => match target {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => match target {
WherePredicateTypeTarget::TypeRef(TypeRef::Path(p))
if p == &Path::from(name![Self]) =>
{
@ -38,7 +41,7 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
}
_ => None,
},
hir_def::generics::WherePredicate::Lifetime { .. } => None,
WherePredicate::Lifetime { .. } => None,
})
.filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) {
Some(TypeNs::TraitId(t)) => Some(t),