From dd16cbcb4e633841e32694a822b498f7ea76fb87 Mon Sep 17 00:00:00 2001 From: Harry Sarson Date: Thu, 25 Apr 2024 15:16:52 +0100 Subject: [PATCH] braces around {self} in UseTree are not unnecessary Before this commit `UseTree::remove_unnecessary_braces` removed the braces around `{self}` in `use x::y::{self};` but `use x::y::self;` is not valid rust. --- .../src/handlers/remove_unused_imports.rs | 34 +++++++++++++++++++ .../crates/syntax/src/ast/node_ext.rs | 21 ++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs index 0f0f13bbc80b1..b653f3b6650e3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs @@ -776,6 +776,40 @@ mod z { ); } + #[test] + fn remove_unused_fixes_nested_self() { + check_assist( + remove_unused_imports, + r#" +mod inner { + pub struct X(); + pub struct Y(); +} + +mod z { + use super::inner::{self, X}$0; + + fn f() { + let y = inner::Y(); + } +} +"#, + r#"mod inner { + pub struct X(); + pub struct Y(); +} + +mod z { + use super::inner::{self}; + + fn f() { + let y = inner::Y(); + } +} +"#, + ); + } + #[test] fn dont_remove_used_glob() { check_assist_not_applicable( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index c3d6f50e6b080..b0fbe7101c113 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -378,9 +378,26 @@ impl ast::UseTreeList { /// Remove the unnecessary braces in current `UseTreeList` pub fn remove_unnecessary_braces(mut self) { + // Returns true iff there is a single subtree and it is not the self keyword. The braces in + // `use x::{self};` are necessary and so we should not remove them. + let has_single_subtree_that_is_not_self = |u: &ast::UseTreeList| { + if let Some((single_subtree,)) = u.use_trees().collect_tuple() { + // We have a single subtree, check whether it is self. + + let is_self = single_subtree.path().as_ref().map_or(false, |path| { + path.segment().and_then(|seg| seg.self_token()).is_some() + && path.qualifier().is_none() + }); + + !is_self + } else { + // Not a single subtree + false + } + }; + let remove_brace_in_use_tree_list = |u: &ast::UseTreeList| { - let use_tree_count = u.use_trees().count(); - if use_tree_count == 1 { + if has_single_subtree_that_is_not_self(u) { if let Some(a) = u.l_curly_token() { ted::remove(a) }