From c8c58d81eca78b322675afa053463e06c422cfbc Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 17 Dec 2020 13:40:11 +0100 Subject: Remove obsolete FIXME --- crates/hir/src/code_model.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 84e8c8047..afe229c32 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -1266,7 +1266,6 @@ impl LifetimeParam { } } -// FIXME: rename from `ImplDef` to `Impl` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Impl { pub(crate) id: ImplId, -- cgit v1.2.3 From fa65d6ba855fb2da68840b987bfdec258239a59b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 17 Dec 2020 22:01:42 +0100 Subject: Higher-ranked trait bounds for where clauses --- crates/hir_def/src/generics.rs | 37 +++++++++++++++++++++++++++++++------ crates/hir_ty/src/lower.rs | 18 +++++++++--------- crates/hir_ty/src/utils.rs | 9 ++++++--- crates/ide/src/goto_definition.rs | 28 ++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 18 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 41134d23b..bb8fca009 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs @@ -62,6 +62,7 @@ pub struct GenericParams { pub enum WherePredicate { TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, Lifetime { target: LifetimeRef, bound: LifetimeRef }, + ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound }, } #[derive(Clone, PartialEq, Eq, Debug)] @@ -69,7 +70,6 @@ pub enum WherePredicateTypeTarget { TypeRef(TypeRef), /// For desugared where predicates that can directly refer to a type param. TypeParam(LocalTypeParamId), - // FIXME: ForLifetime(Vec, TypeRef) } #[derive(Default)] @@ -234,7 +234,7 @@ impl GenericParams { for bound in node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) { - self.add_where_predicate_from_bound(lower_ctx, bound, target.clone()); + self.add_where_predicate_from_bound(lower_ctx, bound, None, target.clone()); } } @@ -279,8 +279,25 @@ impl GenericParams { } else { continue; }; + + let lifetimes: Option> = pred.generic_param_list().map(|param_list| { + // Higher-Ranked Trait Bounds + param_list + .lifetime_params() + .map(|lifetime_param| { + lifetime_param + .lifetime() + .map_or_else(Name::missing, |lt| Name::new_lifetime(<)) + }) + .collect() + }); for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { - self.add_where_predicate_from_bound(lower_ctx, bound, target.clone()); + self.add_where_predicate_from_bound( + lower_ctx, + bound, + lifetimes.as_ref(), + target.clone(), + ); } } } @@ -289,6 +306,7 @@ impl GenericParams { &mut self, lower_ctx: &LowerCtx, bound: ast::TypeBound, + hrtb_lifetimes: Option<&Box<[Name]>>, target: Either, ) { if bound.question_mark_token().is_some() { @@ -297,9 +315,16 @@ impl GenericParams { } let bound = TypeBound::from_ast(lower_ctx, bound); let predicate = match (target, bound) { - (Either::Left(type_ref), bound) => WherePredicate::TypeBound { - target: WherePredicateTypeTarget::TypeRef(type_ref), - bound, + (Either::Left(type_ref), bound) => match hrtb_lifetimes { + Some(hrtb_lifetimes) => WherePredicate::ForLifetime { + lifetimes: hrtb_lifetimes.clone(), + target: WherePredicateTypeTarget::TypeRef(type_ref), + bound, + }, + None => WherePredicate::TypeBound { + target: WherePredicateTypeTarget::TypeRef(type_ref), + bound, + }, }, (Either::Right(lifetime), TypeBound::Lifetime(bound)) => { WherePredicate::Lifetime { target: lifetime, bound } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 8392cb770..8da56cd11 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -675,7 +675,8 @@ impl GenericPredicate { where_predicate: &'a WherePredicate, ) -> impl Iterator + '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| { diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index af880c065..65b79df0d 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -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 { .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 { } _ => 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), diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 173509b08..d75ae447b 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -1077,4 +1077,32 @@ fn foo<'foobar>(_: &'foobar ()) { }"#, ) } + + #[test] + #[ignore] // requires the HIR to somehow track these hrtb lifetimes + fn goto_lifetime_hrtb() { + check( + r#"trait Foo {} +fn foo() where for<'a> T: Foo<&'a<|> (u8, u16)>, {} + //^^ +"#, + ); + check( + r#"trait Foo {} +fn foo() where for<'a<|>> T: Foo<&'a (u8, u16)>, {} + //^^ +"#, + ); + } + + #[test] + #[ignore] // requires ForTypes to be implemented + fn goto_lifetime_hrtb_for_type() { + check( + r#"trait Foo {} +fn foo() where T: for<'a> Foo<&'a<|> (u8, u16)>, {} + //^^ +"#, + ); + } } -- cgit v1.2.3