Unnamed repository; edit this file 'description' to name the repository.
fix: Goto implementation to impls inside blocks
Shoyu Vanilla 2024-03-19
parent b91697d · commit 967a864
-rw-r--r--crates/hir/src/lib.rs27
-rw-r--r--crates/ide/src/goto_implementation.rs71
2 files changed, 97 insertions, 1 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4f9697f7fe..9d7be9a421 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -3628,16 +3628,41 @@ impl Impl {
.filter(filter),
);
}
+
+ if let Some(block) =
+ ty.adt_id(Interner).and_then(|def| def.0.module(db.upcast()).containing_block())
+ {
+ if let Some(inherent_impls) = db.inherent_impls_in_block(block) {
+ all.extend(
+ inherent_impls.for_self_ty(&ty).iter().cloned().map(Self::from).filter(filter),
+ );
+ }
+ if let Some(trait_impls) = db.trait_impls_in_block(block) {
+ all.extend(
+ trait_impls
+ .for_self_ty_without_blanket_impls(fp)
+ .map(Self::from)
+ .filter(filter),
+ );
+ }
+ }
+
all
}
pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
- let krate = trait_.module(db).krate();
+ let module = trait_.module(db);
+ let krate = module.krate();
let mut all = Vec::new();
for Crate { id } in krate.transitive_reverse_dependencies(db) {
let impls = db.trait_impls_in_crate(id);
all.extend(impls.for_trait(trait_.id).map(Self::from))
}
+ if let Some(block) = module.id.containing_block() {
+ if let Some(trait_impls) = db.trait_impls_in_block(block) {
+ all.extend(trait_impls.for_trait(trait_.id).map(Self::from));
+ }
+ }
all
}
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 8a12cbaccc..76e5e9dd92 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -340,4 +340,75 @@ impl Tr for S {
"#,
);
}
+
+ #[test]
+ fn goto_adt_implementation_inside_block() {
+ check(
+ r#"
+//- minicore: copy, derive
+trait Bar {}
+
+fn test() {
+ #[derive(Copy)]
+ //^^^^^^^^^^^^^^^
+ struct Foo$0;
+
+ impl Foo {}
+ //^^^
+
+ trait Baz {}
+
+ impl Bar for Foo {}
+ //^^^
+
+ impl Baz for Foo {}
+ //^^^
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_trait_implementation_inside_block() {
+ check(
+ r#"
+struct Bar;
+
+fn test() {
+ trait Foo$0 {}
+
+ struct Baz;
+
+ impl Foo for Bar {}
+ //^^^
+
+ impl Foo for Baz {}
+ //^^^
+}
+"#,
+ );
+ check(
+ r#"
+struct Bar;
+
+fn test() {
+ trait Foo {
+ fn foo$0() {}
+ }
+
+ struct Baz;
+
+ impl Foo for Bar {
+ fn foo() {}
+ //^^^
+ }
+
+ impl Foo for Baz {
+ fn foo() {}
+ //^^^
+ }
+}
+"#,
+ );
+ }
}