From 93aa166748eef9560df2435391dc3f3b53f8262d Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 24 Jan 2020 19:35:09 +0100 Subject: wip lower impl trait to type args --- crates/ra_hir_ty/src/utils.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/utils.rs') diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 0b1806a84..314a3241f 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -127,7 +127,8 @@ impl Generics { self.find_param(param).0 } pub(crate) fn param_name(&self, param: TypeParamId) -> Name { - self.find_param(param).1.name.clone() + // FIXME make this return Option + self.find_param(param).1.name.clone().unwrap_or_else(Name::missing) } fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { if param.parent == self.def { -- cgit v1.2.3 From 16c69374471a0072541c21a5551b4fd97f7e12ba Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 25 Jan 2020 23:38:33 +0100 Subject: Lower impl trait to variables, move away from using placeholders where they don't belong --- crates/ra_hir_ty/src/utils.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/utils.rs') diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 314a3241f..f116b95e7 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use hir_def::{ adt::VariantData, db::DefDatabase, - generics::{GenericParams, TypeParamData}, + generics::{GenericParams, TypeParamData, TypeParamProvenance}, path::Path, resolver::{HasResolver, TypeNs}, type_ref::TypeRef, @@ -117,19 +117,31 @@ impl Generics { pub(crate) fn len(&self) -> usize { self.len_split().0 } + /// (total, parents, child) pub(crate) fn len_split(&self) -> (usize, usize, usize) { let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); let child = self.params.types.len(); (parent + child, parent, child) } + + /// (self, type param list, impl trait) + pub(crate) fn provenance_split(&self) -> (usize, usize, usize) { + let self_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::TraitSelf).count(); + let list_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::TypeParamList).count(); + let impl_trait_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::ArgumentImplTrait).count(); + (self_params, list_params, impl_trait_params) + } + pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 { self.find_param(param).0 } + pub(crate) fn param_name(&self, param: TypeParamId) -> Name { // FIXME make this return Option self.find_param(param).1.name.clone().unwrap_or_else(Name::missing) } + fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { if param.parent == self.def { let (idx, (_local_id, data)) = self -- cgit v1.2.3 From dbc14f9d570e5bc1ddae05e9ccd8f163082b3cac Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 15:17:48 +0100 Subject: First stab at desugaring bounds for APIT --- crates/ra_hir_ty/src/utils.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/utils.rs') diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index f116b95e7..77b7de729 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -12,6 +12,7 @@ use hir_def::{ AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, }; use hir_expand::name::{name, Name}; +use hir_def::generics::WherePredicateTarget; fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { let resolver = trait_.resolver(db); @@ -19,11 +20,14 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { // lifetime problems, but since there usually shouldn't be more than a // few direct traits this should be fine (we could even use some kind of // SmallVec if performance is a concern) - db.generic_params(trait_.into()) + let generic_params = db.generic_params(trait_.into()); + let trait_self = generic_params.find_trait_self_param(); + generic_params .where_predicates .iter() - .filter_map(|pred| match &pred.type_ref { - TypeRef::Path(p) if p == &Path::from(name![Self]) => pred.bound.as_path(), + .filter_map(|pred| match &pred.target { + WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => pred.bound.as_path(), + WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => pred.bound.as_path(), _ => None, }) .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { -- cgit v1.2.3 From ed25cf70d5e0df9c7a33deb503ea14c2d97bd7a7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 16:52:43 +0100 Subject: Change Ty::Param to contain param ID --- crates/ra_hir_ty/src/utils.rs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir_ty/src/utils.rs') diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 77b7de729..8fa1838bd 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -99,23 +99,19 @@ pub(crate) struct Generics { } impl Generics { - pub(crate) fn iter<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn iter<'a>(&'a self) -> impl Iterator + 'a { self.parent_generics .as_ref() .into_iter() - .flat_map(|it| it.params.types.iter()) - .chain(self.params.types.iter()) - .enumerate() - .map(|(i, (_local_id, p))| (i as u32, p)) + .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) + .chain(self.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: self.def, local_id }, p))) } - pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator + 'a { self.parent_generics .as_ref() .into_iter() - .flat_map(|it| it.params.types.iter()) - .enumerate() - .map(|(i, (_local_id, p))| (i as u32, p)) + .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) } pub(crate) fn len(&self) -> usize { @@ -137,16 +133,11 @@ impl Generics { (self_params, list_params, impl_trait_params) } - pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 { - self.find_param(param).0 + pub(crate) fn param_idx(&self, param: TypeParamId) -> Option { + Some(self.find_param(param)?.0) } - pub(crate) fn param_name(&self, param: TypeParamId) -> Name { - // FIXME make this return Option - self.find_param(param).1.name.clone().unwrap_or_else(Name::missing) - } - - fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { + fn find_param(&self, param: TypeParamId) -> Option<(u32, &TypeParamData)> { if param.parent == self.def { let (idx, (_local_id, data)) = self .params @@ -156,9 +147,10 @@ impl Generics { .find(|(_, (idx, _))| *idx == param.local_id) .unwrap(); let (_total, parent_len, _child) = self.len_split(); - return ((parent_len + idx) as u32, data); + Some(((parent_len + idx) as u32, data)) + } else { + self.parent_generics.as_ref().and_then(|g| g.find_param(param)) } - self.parent_generics.as_ref().unwrap().find_param(param) } } -- cgit v1.2.3 From dded90a748737c3661aad043524f2248e324c867 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 7 Feb 2020 15:13:15 +0100 Subject: Formatting --- crates/ra_hir_ty/src/utils.rs | 63 +++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir_ty/src/utils.rs') diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 8fa1838bd..e307d958d 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -2,6 +2,7 @@ //! query, but can't be computed directly from `*Data` (ie, which need a `db`). use std::sync::Arc; +use hir_def::generics::WherePredicateTarget; use hir_def::{ adt::VariantData, db::DefDatabase, @@ -12,7 +13,6 @@ use hir_def::{ AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, }; use hir_expand::name::{name, Name}; -use hir_def::generics::WherePredicateTarget; fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { let resolver = trait_.resolver(db); @@ -26,8 +26,12 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec { .where_predicates .iter() .filter_map(|pred| match &pred.target { - WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => pred.bound.as_path(), - WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => pred.bound.as_path(), + WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => { + pred.bound.as_path() + } + WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { + pred.bound.as_path() + } _ => None, }) .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { @@ -99,19 +103,35 @@ pub(crate) struct Generics { } impl Generics { - pub(crate) fn iter<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn iter<'a>( + &'a self, + ) -> impl Iterator + 'a { self.parent_generics .as_ref() .into_iter() - .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) - .chain(self.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: self.def, local_id }, p))) + .flat_map(|it| { + it.params + .types + .iter() + .map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p)) + }) + .chain( + self.params + .types + .iter() + .map(move |(local_id, p)| (TypeParamId { parent: self.def, local_id }, p)), + ) } - pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator + 'a { - self.parent_generics - .as_ref() - .into_iter() - .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) + pub(crate) fn iter_parent<'a>( + &'a self, + ) -> impl Iterator + 'a { + self.parent_generics.as_ref().into_iter().flat_map(|it| { + it.params + .types + .iter() + .map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p)) + }) } pub(crate) fn len(&self) -> usize { @@ -127,9 +147,24 @@ impl Generics { /// (self, type param list, impl trait) pub(crate) fn provenance_split(&self) -> (usize, usize, usize) { - let self_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::TraitSelf).count(); - let list_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::TypeParamList).count(); - let impl_trait_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::ArgumentImplTrait).count(); + let self_params = self + .params + .types + .iter() + .filter(|(_, p)| p.provenance == TypeParamProvenance::TraitSelf) + .count(); + let list_params = self + .params + .types + .iter() + .filter(|(_, p)| p.provenance == TypeParamProvenance::TypeParamList) + .count(); + let impl_trait_params = self + .params + .types + .iter() + .filter(|(_, p)| p.provenance == TypeParamProvenance::ArgumentImplTrait) + .count(); (self_params, list_params, impl_trait_params) } -- cgit v1.2.3 From 6c70619b0126bc0e40bd9df39dcd6e711cac69c5 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 7 Feb 2020 16:24:09 +0100 Subject: Deal better with implicit type parameters and argument lists --- crates/ra_hir_ty/src/utils.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/utils.rs') diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index e307d958d..508ae9046 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -145,8 +145,9 @@ impl Generics { (parent + child, parent, child) } - /// (self, type param list, impl trait) - pub(crate) fn provenance_split(&self) -> (usize, usize, usize) { + /// (parent total, self param, type param list, impl trait) + pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize) { + let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); let self_params = self .params .types @@ -165,7 +166,7 @@ impl Generics { .iter() .filter(|(_, p)| p.provenance == TypeParamProvenance::ArgumentImplTrait) .count(); - (self_params, list_params, impl_trait_params) + (parent, self_params, list_params, impl_trait_params) } pub(crate) fn param_idx(&self, param: TypeParamId) -> Option { -- cgit v1.2.3