diff --git a/crates/ide-assists/src/handlers/remove_unused_imports.rs b/crates/ide-assists/src/handlers/remove_unused_imports.rs index 0f0f13bbc8..b653f3b665 100644 --- a/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/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/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index c3d6f50e6b..b0fbe7101c 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/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) }