From c50157f33025b6ff01809b975a3d12c0e43a0072 Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 10 Jun 2020 21:24:36 +0300 Subject: Add `Go to Type Definition` hover action. --- crates/ra_hir_ty/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 2b9372b4b..9d4d6aaa4 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -1052,10 +1052,10 @@ pub enum OpaqueTyId { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct ReturnTypeImplTraits { - pub(crate) impl_traits: Vec, + pub impl_traits: Vec, } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub(crate) struct ReturnTypeImplTrait { - pub(crate) bounds: Binders>, +pub struct ReturnTypeImplTrait { + pub bounds: Binders>, } -- cgit v1.2.3 From 4b07c1e77515ae9198aae6275700aacd43181b50 Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 11 Jun 2020 20:17:32 +0300 Subject: Add Type::walk method --- crates/ra_hir_ty/src/lib.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 9d4d6aaa4..25ab9d872 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -877,6 +877,58 @@ impl Ty { _ => None, } } + + pub fn impl_trait_ref(&self, db: &dyn HirDatabase) -> Option { + match self { + Ty::Opaque(opaque_ty) => { + let predicates = match opaque_ty.opaque_ty_id { + OpaqueTyId::ReturnTypeImplTrait(func, idx) => { + db.return_type_impl_traits(func).map(|it| { + let data = (*it) + .as_ref() + .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); + data.clone().subst(&opaque_ty.parameters) + }) + } + }; + + predicates.and_then(|it| { + it.value.iter().find_map(|pred| match pred { + GenericPredicate::Implemented(tr) => Some(tr.clone()), + _ => None, + }) + }) + } + Ty::Placeholder(id) => { + let generic_params = db.generic_params(id.parent); + let param_data = &generic_params.types[id.local_id]; + match param_data.provenance { + hir_def::generics::TypeParamProvenance::ArgumentImplTrait => db + .generic_predicates_for_param(*id) + .into_iter() + .map(|pred| pred.value.clone()) + .find_map(|pred| match pred { + GenericPredicate::Implemented(tr) => Some(tr.clone()), + _ => None, + }), + _ => None, + } + } + _ => None, + } + } + + pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option { + match self { + Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { + match type_alias_id.lookup(db.upcast()).container { + AssocContainerId::TraitId(trait_id) => Some(trait_id), + _ => None, + } + } + _ => None, + } + } } /// This allows walking structures that contain types to do something with those -- cgit v1.2.3 From 022fbefffad0d7c402ac5607457f2828decb2188 Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 11 Jun 2020 23:06:58 +0300 Subject: Apply suggestions from code review --- crates/ra_hir_ty/src/lib.rs | 53 +++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 25ab9d872..f22232324 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -73,6 +73,7 @@ pub use lower::{ pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; pub use chalk_ir::{BoundVar, DebruijnIndex}; +use itertools::Itertools; /// A type constructor or type name: this might be something like the primitive /// type `bool`, a struct like `Vec`, or things like function pointers or @@ -815,6 +816,11 @@ impl Ty { } } + /// If this is a `dyn Trait`, returns that trait. + pub fn dyn_trait(&self) -> Option { + self.dyn_trait_ref().map(|it| it.trait_) + } + fn builtin_deref(&self) -> Option { match self { Ty::Apply(a_ty) => match a_ty.ctor { @@ -867,18 +873,7 @@ impl Ty { } } - /// If this is a `dyn Trait`, returns that trait. - pub fn dyn_trait(&self) -> Option { - match self { - Ty::Dyn(predicates) => predicates.iter().find_map(|pred| match pred { - GenericPredicate::Implemented(tr) => Some(tr.trait_), - _ => None, - }), - _ => None, - } - } - - pub fn impl_trait_ref(&self, db: &dyn HirDatabase) -> Option { + pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option> { match self { Ty::Opaque(opaque_ty) => { let predicates = match opaque_ty.opaque_ty_id { @@ -892,25 +887,21 @@ impl Ty { } }; - predicates.and_then(|it| { - it.value.iter().find_map(|pred| match pred { - GenericPredicate::Implemented(tr) => Some(tr.clone()), - _ => None, - }) - }) + predicates.map(|it| it.value) } Ty::Placeholder(id) => { let generic_params = db.generic_params(id.parent); let param_data = &generic_params.types[id.local_id]; match param_data.provenance { - hir_def::generics::TypeParamProvenance::ArgumentImplTrait => db - .generic_predicates_for_param(*id) - .into_iter() - .map(|pred| pred.value.clone()) - .find_map(|pred| match pred { - GenericPredicate::Implemented(tr) => Some(tr.clone()), - _ => None, - }), + hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { + let predicates = db + .generic_predicates_for_param(*id) + .into_iter() + .map(|pred| pred.value.clone()) + .collect_vec(); + + Some(predicates) + } _ => None, } } @@ -926,6 +917,12 @@ impl Ty { _ => None, } } + Ty::Projection(projection_ty) => { + match projection_ty.associated_ty.lookup(db.upcast()).container { + AssocContainerId::TraitId(trait_id) => Some(trait_id), + _ => None, + } + } _ => None, } } @@ -1104,10 +1101,10 @@ pub enum OpaqueTyId { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct ReturnTypeImplTraits { - pub impl_traits: Vec, + pub(crate) impl_traits: Vec, } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct ReturnTypeImplTrait { +pub(crate) struct ReturnTypeImplTrait { pub bounds: Binders>, } -- cgit v1.2.3