From 134b6f2228b7c9e2f3b9ab2bddcbd8bd615ccf3a Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 4 Feb 2025 18:30:50 +0200 Subject: [PATCH 1/2] Fix IDE resolution of `use` inside a body We stopped the expression search too early because `use` is an item. --- crates/hir/src/source_analyzer.rs | 6 +++++- crates/ide/src/goto_definition.rs | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index ca239826d4..23e7518883 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -1252,7 +1252,11 @@ fn scope_for( node: InFile<&SyntaxNode>, ) -> Option { node.ancestors_with_macros(db.upcast()) - .take_while(|it| !ast::Item::can_cast(it.kind()) || ast::MacroCall::can_cast(it.kind())) + .take_while(|it| { + !ast::Item::can_cast(it.kind()) + || ast::MacroCall::can_cast(it.kind()) + || ast::Use::can_cast(it.kind()) + }) .filter_map(|it| it.map(ast::Expr::cast).transpose()) .filter_map(|it| source_map.node_expr(it.as_ref())?.as_expr()) .find_map(|it| scopes.scope_for(it)) diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 45f694d2fb..bdafb701ff 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -3272,4 +3272,22 @@ fn f() { "#, ); } + + #[test] + fn use_inside_body() { + check( + r#" +fn main() { + mod nice_module { + pub(super) struct NiceStruct; + // ^^^^^^^^^^ + } + + use nice_module::NiceStruct$0; + + let _ = NiceStruct; +} + "#, + ); + } } From bffc169925db98b40469e90d688d39e8a9b585cb Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 4 Feb 2025 19:10:04 +0200 Subject: [PATCH 2/2] Fix a failing test The reason this test passed previously is not because it was working as intended, but because prior to the previous commit we did not resolve the `use` at all! Now, `use self as _` is invalid code anyway (it prints E0429), and because we fallback to the value namespace if we can't resolve in the type namespace (which is a reasonable behavior), this test now actually fails. I don't think we want to change the fallback, so I removed `use self as _` and instead added a new test, where the value can be resolved in the type namespace. --- crates/ide/src/rename.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 3d7ff5f76a..3e8295e3f0 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -2001,19 +2001,37 @@ impl Foo { "foo", r#" fn f($0self) -> i32 { - use self as _; self.i } "#, r#" fn f(foo: _) -> i32 { - use self as _; foo.i } "#, ); } + #[test] + fn no_type_value_ns_confuse() { + // Test that we don't rename items from different namespaces. + check( + "bar", + r#" +struct foo {} +fn f(foo$0: i32) -> i32 { + use foo as _; +} +"#, + r#" +struct foo {} +fn f(bar: i32) -> i32 { + use foo as _; +} +"#, + ); + } + #[test] fn test_self_in_path_to_parameter() { check(