aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-15 14:08:26 +0000
committerGitHub <[email protected]>2021-03-15 14:08:26 +0000
commitf2c39d0cdf708d6178740385f58d6b2b657e411a (patch)
tree83ed009ee98b3c1cfe1cbcc203c1c419c914569e /crates/hir
parent3962b0d53c8da6e3f95f54395d266cb99562bd47 (diff)
parent79561b9d2e901e2624f94ffa7bc6017f0249f23d (diff)
Merge #8020
8020: Power up goto_implementation r=matklad a=Veykril by allowing it to be invoked on references of names, now showing all (trait) implementations of the given type in all crates instead of just the defining crate as well as including support for builtin types ![image](https://user-images.githubusercontent.com/3757771/111144403-52bb0700-8587-11eb-9205-7a2a5b8b75a3.png) Example screenshot of `impl`s of Box in `log`, `alloc`, `std` and the current crate. Before you had to invoke it on the definition where it would only show the `impls` in `alloc`. Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/lib.rs58
1 files changed, 44 insertions, 14 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 25e5bfb01..c5161dadd 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -51,7 +51,8 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
51use hir_ty::{ 51use hir_ty::{
52 autoderef, 52 autoderef,
53 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, 53 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
54 method_resolution, to_assoc_type_id, 54 method_resolution::{self, TyFingerprint},
55 to_assoc_type_id,
55 traits::{FnTrait, Solution, SolutionVariables}, 56 traits::{FnTrait, Solution, SolutionVariables},
56 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 57 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
57 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, 58 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty,
@@ -695,8 +696,8 @@ impl Adt {
695 } 696 }
696 } 697 }
697 698
698 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 699 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
699 Some(self.module(db).krate()) 700 self.module(db).krate()
700 } 701 }
701 702
702 pub fn name(self, db: &dyn HirDatabase) -> Name { 703 pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -1018,8 +1019,8 @@ impl TypeAlias {
1018 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1019 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1019 } 1020 }
1020 1021
1021 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 1022 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1022 Some(self.module(db).krate()) 1023 self.module(db).krate()
1023 } 1024 }
1024 1025
1025 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1026 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1482,9 +1483,44 @@ impl Impl {
1482 1483
1483 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1484 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1484 } 1485 }
1485 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { 1486
1486 let impls = db.trait_impls_in_crate(krate.id); 1487 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
1487 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::new(),
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.into_iter().for_each(|id| {
1501 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1502 });
1503 let fp = TyFingerprint::for_impl(&ty.value);
1504 for id in db.crate_graph().iter() {
1505 match fp {
1506 Some(fp) => all.extend(
1507 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
1508 ),
1509 None => all
1510 .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)),
1511 }
1512 }
1513 all
1514 }
1515
1516 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
1517 let krate = trait_.module(db).krate();
1518 let mut all = Vec::new();
1519 for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) {
1520 let impls = db.trait_impls_in_crate(id);
1521 all.extend(impls.for_trait(trait_.id).map(Self::from))
1522 }
1523 all
1488 } 1524 }
1489 1525
1490 // FIXME: the return type is wrong. This should be a hir version of 1526 // FIXME: the return type is wrong. This should be a hir version of
@@ -1932,12 +1968,6 @@ impl Type {
1932 self.ty.value.associated_type_parent_trait(db).map(Into::into) 1968 self.ty.value.associated_type_parent_trait(db).map(Into::into)
1933 } 1969 }
1934 1970
1935 // FIXME: provide required accessors such that it becomes implementable from outside.
1936 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1937 let rref = other.remove_ref();
1938 self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value))
1939 }
1940
1941 fn derived(&self, ty: Ty) -> Type { 1971 fn derived(&self, ty: Ty) -> Type {
1942 Type { 1972 Type {
1943 krate: self.krate, 1973 krate: self.krate,