diff options
author | Lukas Wirth <[email protected]> | 2021-03-15 09:11:48 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-03-15 11:10:18 +0000 |
commit | 6c782a53148dc2f34be2eafbdf872ab6497632fd (patch) | |
tree | 634e4bc975861908b0c79028eedfcc4e87a2ecfa /crates/hir | |
parent | de360275416ca095102f2b17d6ca1de3bd091fdb (diff) |
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
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/lib.rs | 53 |
1 files changed, 40 insertions, 13 deletions
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 { | |||
696 | } | 696 | } |
697 | } | 697 | } |
698 | 698 | ||
699 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | 699 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
700 | Some(self.module(db).krate()) | 700 | self.module(db).krate() |
701 | } | 701 | } |
702 | 702 | ||
703 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 703 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
@@ -1019,8 +1019,8 @@ impl TypeAlias { | |||
1019 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } | 1019 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | 1022 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
1023 | Some(self.module(db).krate()) | 1023 | self.module(db).krate() |
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1026 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
@@ -1483,9 +1483,42 @@ impl Impl { | |||
1483 | 1483 | ||
1484 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() | 1484 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() |
1485 | } | 1485 | } |
1486 | pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { | 1486 | |
1487 | let impls = db.trait_impls_in_crate(krate.id); | 1487 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { |
1488 | impls.for_trait(trait_.id).map(Self::from).collect() | 1488 | let def_crates = match ty.value.def_crates(db, krate) { |
1489 | Some(def_crates) => def_crates, | ||
1490 | None => return vec![], | ||
1491 | }; | ||
1492 | |||
1493 | let filter = |impl_def: &Impl| { | ||
1494 | let target_ty = impl_def.target_ty(db); | ||
1495 | let rref = target_ty.remove_ref(); | ||
1496 | ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) | ||
1497 | }; | ||
1498 | |||
1499 | let mut all = Vec::new(); | ||
1500 | def_crates.iter().for_each(|&id| { | ||
1501 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | ||
1502 | }); | ||
1503 | for id in def_crates | ||
1504 | .iter() | ||
1505 | .flat_map(|&id| Crate { id }.reverse_dependencies(db)) | ||
1506 | .map(|Crate { id }| id) | ||
1507 | .chain(def_crates.iter().copied()) | ||
1508 | { | ||
1509 | all.extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)); | ||
1510 | } | ||
1511 | all | ||
1512 | } | ||
1513 | |||
1514 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { | ||
1515 | let krate = trait_.module(db).krate(); | ||
1516 | let mut all = Vec::new(); | ||
1517 | for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) { | ||
1518 | let impls = db.trait_impls_in_crate(id); | ||
1519 | all.extend(impls.for_trait(trait_.id).map(Self::from)) | ||
1520 | } | ||
1521 | all | ||
1489 | } | 1522 | } |
1490 | 1523 | ||
1491 | // FIXME: the return type is wrong. This should be a hir version of | 1524 | // FIXME: the return type is wrong. This should be a hir version of |
@@ -1913,12 +1946,6 @@ impl Type { | |||
1913 | self.ty.value.associated_type_parent_trait(db).map(Into::into) | 1946 | self.ty.value.associated_type_parent_trait(db).map(Into::into) |
1914 | } | 1947 | } |
1915 | 1948 | ||
1916 | // FIXME: provide required accessors such that it becomes implementable from outside. | ||
1917 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | ||
1918 | let rref = other.remove_ref(); | ||
1919 | self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value)) | ||
1920 | } | ||
1921 | |||
1922 | fn derived(&self, ty: Ty) -> Type { | 1949 | fn derived(&self, ty: Ty) -> Type { |
1923 | Type { | 1950 | Type { |
1924 | krate: self.krate, | 1951 | krate: self.krate, |