diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 950a0f9ff652d..be4de99bdef9e 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -292,7 +292,7 @@ fn calc_unused_spans( UnusedSpanResult::Used } } - ast::UseTreeKind::Nested { items: ref nested, .. } => { + ast::UseTreeKind::Nested { items: ref nested, span: tree_span } => { if nested.is_empty() { return UnusedSpanResult::Unused { spans: vec![use_tree.span], remove: full_span }; } @@ -346,6 +346,23 @@ fn calc_unused_spans( } else if used_childs == 0 { UnusedSpanResult::Unused { spans: unused_spans, remove: full_span } } else { + // If there is only one remaining child that is used, the braces around the use + // tree are not needed anymore. In that case, we determine the span of the left + // brace and the right brace, and tell rustfix to remove them as well. + // + // This means that `use a::{B, C};` will be turned into `use a::B;` rather than + // `use a::{B};`, removing a rustfmt roundtrip. + if used_childs == 1 { + // Left brace, from the start of the nested group to the first item. + to_remove.push( + tree_span.shrink_to_lo().to(nested.first().unwrap().0.span.shrink_to_lo()), + ); + // Right brace, from the end of the last item to the end of the nested group. + to_remove.push( + nested.last().unwrap().0.span.shrink_to_hi().to(tree_span.shrink_to_hi()), + ); + } + UnusedSpanResult::PartialUnused { spans: unused_spans, remove: to_remove } } } diff --git a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed index d554bbfcc98c9..40a44ab8f2fb8 100644 --- a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed +++ b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed @@ -6,7 +6,7 @@ use std::ops::{ Coroutine, - CoroutineState::{self}, + CoroutineState::self, //~^ ERROR unused import: `*` }; use std::pin::Pin; diff --git a/tests/ui/suggestions/unused-imports.fixed b/tests/ui/suggestions/unused-imports.fixed new file mode 100644 index 0000000000000..e5421932744ce --- /dev/null +++ b/tests/ui/suggestions/unused-imports.fixed @@ -0,0 +1,26 @@ +//@ run-rustfix +//@ check-pass + +#![warn(unused_imports)] + +pub mod nested { + pub struct A; + pub struct B; + pub struct C; + pub struct D; + pub mod even_more { + pub struct E; + pub struct F; + pub struct G; + } +} + +use nested::B; +//~^ WARN unused import + +use nested::even_more::F; +//~^^^^^^^ WARN unused import + +fn main() { + let _ = (B, F); +} diff --git a/tests/ui/suggestions/unused-imports.rs b/tests/ui/suggestions/unused-imports.rs new file mode 100644 index 0000000000000..a6f535d48b742 --- /dev/null +++ b/tests/ui/suggestions/unused-imports.rs @@ -0,0 +1,33 @@ +//@ run-rustfix +//@ check-pass + +#![warn(unused_imports)] + +pub mod nested { + pub struct A; + pub struct B; + pub struct C; + pub struct D; + pub mod even_more { + pub struct E; + pub struct F; + pub struct G; + } +} + +use nested::{A, B, C}; +//~^ WARN unused import + +use nested::{ + D, + even_more::{ + E, + F, + G, + }, + }; +//~^^^^^^^ WARN unused import + +fn main() { + let _ = (B, F); +} diff --git a/tests/ui/suggestions/unused-imports.stderr b/tests/ui/suggestions/unused-imports.stderr new file mode 100644 index 0000000000000..dcc82788e767f --- /dev/null +++ b/tests/ui/suggestions/unused-imports.stderr @@ -0,0 +1,26 @@ +warning: unused imports: `A`, `C` + --> $DIR/unused-imports.rs:18:14 + | +LL | use nested::{A, B, C}; + | ^ ^ + | +note: the lint level is defined here + --> $DIR/unused-imports.rs:4:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: unused imports: `D`, `E`, `G` + --> $DIR/unused-imports.rs:22:5 + | +LL | D, + | ^ +LL | even_more::{ +LL | E, + | ^ +LL | F, +LL | G, + | ^ + +warning: 2 warnings emitted +