Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #13897 - bvanjoi:nearest-block-search, r=Veykril
fix(ty): should query impls in nearest block fix https://github.com/rust-lang/rust-analyzer/issues/13895
bors 2023-01-11
parent 6dabdef · parent 9a15cc8 · commit 75877d7
-rw-r--r--crates/hir-ty/src/method_resolution.rs9
-rw-r--r--crates/ide/src/goto_definition.rs64
2 files changed, 71 insertions, 2 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 2328dceb83..ae25704f20 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -1094,13 +1094,13 @@ fn iterate_inherent_methods(
None => return ControlFlow::Continue(()),
};
- let (module, block) = match visible_from_module {
+ let (module, mut block) = match visible_from_module {
VisibleFromModule::Filter(module) => (Some(module), module.containing_block()),
VisibleFromModule::IncludeBlock(block) => (None, Some(block)),
VisibleFromModule::None => (None, None),
};
- if let Some(block_id) = block {
+ while let Some(block_id) = block {
if let Some(impls) = db.inherent_impls_in_block(block_id) {
impls_for_self_ty(
&impls,
@@ -1113,6 +1113,11 @@ fn iterate_inherent_methods(
callback,
)?;
}
+
+ block = db
+ .block_def_map(block_id)
+ .and_then(|map| map.parent())
+ .and_then(|module| module.containing_block());
}
for krate in def_crates {
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 73fd518a9e..93019527f4 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1916,4 +1916,68 @@ fn main() {
"#,
)
}
+
+ #[test]
+ fn query_impls_in_nearest_block() {
+ check(
+ r#"
+struct S1;
+impl S1 {
+ fn e() -> () {}
+}
+fn f1() {
+ struct S1;
+ impl S1 {
+ fn e() -> () {}
+ //^
+ }
+ fn f2() {
+ fn f3() {
+ S1::e$0();
+ }
+ }
+}
+"#,
+ );
+
+ check(
+ r#"
+struct S1;
+impl S1 {
+ fn e() -> () {}
+}
+fn f1() {
+ struct S1;
+ impl S1 {
+ fn e() -> () {}
+ //^
+ }
+ fn f2() {
+ struct S2;
+ S1::e$0();
+ }
+}
+fn f12() {
+ struct S1;
+ impl S1 {
+ fn e() -> () {}
+ }
+}
+"#,
+ );
+
+ check(
+ r#"
+struct S1;
+impl S1 {
+ fn e() -> () {}
+ //^
+}
+fn f2() {
+ struct S2;
+ S1::e$0();
+}
+"#,
+ );
+ }
}