From 6c782a53148dc2f34be2eafbdf872ab6497632fd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 15 Mar 2021 10:11:48 +0100 Subject: Power up goto_implementation by allowing it to be invoked on references of names, showing all (trait) implementations of the given type in all crates including builtin types --- crates/hir/src/lib.rs | 53 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'crates/hir/src/lib.rs') diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index eb1cd66fb..a9d3c9156 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -696,8 +696,8 @@ impl Adt { } } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + self.module(db).krate() } pub fn name(self, db: &dyn HirDatabase) -> Name { @@ -1019,8 +1019,8 @@ impl TypeAlias { Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + self.module(db).krate() } pub fn type_ref(self, db: &dyn HirDatabase) -> Option { @@ -1483,9 +1483,42 @@ impl Impl { inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() } - pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec { - let impls = db.trait_impls_in_crate(krate.id); - impls.for_trait(trait_.id).map(Self::from).collect() + + pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec { + let def_crates = match ty.value.def_crates(db, krate) { + Some(def_crates) => def_crates, + None => return vec![], + }; + + let filter = |impl_def: &Impl| { + let target_ty = impl_def.target_ty(db); + let rref = target_ty.remove_ref(); + ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) + }; + + let mut all = Vec::new(); + def_crates.iter().for_each(|&id| { + all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) + }); + for id in def_crates + .iter() + .flat_map(|&id| Crate { id }.reverse_dependencies(db)) + .map(|Crate { id }| id) + .chain(def_crates.iter().copied()) + { + all.extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)); + } + all + } + + pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec { + let krate = trait_.module(db).krate(); + let mut all = Vec::new(); + for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) { + let impls = db.trait_impls_in_crate(id); + all.extend(impls.for_trait(trait_.id).map(Self::from)) + } + all } // FIXME: the return type is wrong. This should be a hir version of @@ -1913,12 +1946,6 @@ impl Type { self.ty.value.associated_type_parent_trait(db).map(Into::into) } - // FIXME: provide required accessors such that it becomes implementable from outside. - pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { - let rref = other.remove_ref(); - self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value)) - } - fn derived(&self, ty: Ty) -> Type { Type { krate: self.krate, -- cgit v1.2.3