remove braces when fixing a nested use tree into a single use
This commit is contained in:
parent
13f76235b3
commit
2d3a9a5847
@ -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 };
|
||||
}
|
||||
@ -300,6 +300,7 @@ fn calc_unused_spans(
|
||||
let mut unused_spans = Vec::new();
|
||||
let mut to_remove = Vec::new();
|
||||
let mut used_childs = 0;
|
||||
let mut contains_self = false;
|
||||
let mut previous_unused = false;
|
||||
for (pos, (use_tree, use_tree_id)) in nested.iter().enumerate() {
|
||||
let remove = match calc_unused_spans(unused_import, use_tree, *use_tree_id) {
|
||||
@ -339,6 +340,8 @@ fn calc_unused_spans(
|
||||
to_remove.push(remove_span);
|
||||
}
|
||||
}
|
||||
contains_self |= use_tree.prefix == kw::SelfLower
|
||||
&& matches!(use_tree.kind, ast::UseTreeKind::Simple(None));
|
||||
previous_unused = remove.is_some();
|
||||
}
|
||||
if unused_spans.is_empty() {
|
||||
@ -346,6 +349,28 @@ 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.
|
||||
//
|
||||
// Note that we cannot remove the braces if the only item inside the use tree is
|
||||
// `self`: `use foo::{self};` is valid Rust syntax, while `use foo::self;` errors
|
||||
// out. We also cannot turn `use foo::{self}` into `use foo`, as the former doesn't
|
||||
// import types with the same name as the module.
|
||||
if used_childs == 1 && !contains_self {
|
||||
// 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 }
|
||||
}
|
||||
}
|
||||
|
35
tests/ui/suggestions/unused-imports.fixed
Normal file
35
tests/ui/suggestions/unused-imports.fixed
Normal file
@ -0,0 +1,35 @@
|
||||
//@ 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;
|
||||
}
|
||||
pub mod another {
|
||||
pub struct H;
|
||||
pub struct I;
|
||||
}
|
||||
}
|
||||
|
||||
use nested::B;
|
||||
//~^ WARN unused import
|
||||
|
||||
use nested::even_more::F;
|
||||
//~^^^^^^^ WARN unused import
|
||||
|
||||
// Note that the following fix should result in `::{self}`, not `::self`. The latter is invalid
|
||||
// Rust syntax, so the braces should not be removed.
|
||||
use nested::another::{self};
|
||||
//~^ WARN unused import
|
||||
|
||||
fn main() {
|
||||
let _ = (B, F, another::I);
|
||||
}
|
42
tests/ui/suggestions/unused-imports.rs
Normal file
42
tests/ui/suggestions/unused-imports.rs
Normal file
@ -0,0 +1,42 @@
|
||||
//@ 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;
|
||||
}
|
||||
pub mod another {
|
||||
pub struct H;
|
||||
pub struct I;
|
||||
}
|
||||
}
|
||||
|
||||
use nested::{A, B, C};
|
||||
//~^ WARN unused import
|
||||
|
||||
use nested::{
|
||||
D,
|
||||
even_more::{
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
},
|
||||
};
|
||||
//~^^^^^^^ WARN unused import
|
||||
|
||||
// Note that the following fix should result in `::{self}`, not `::self`. The latter is invalid
|
||||
// Rust syntax, so the braces should not be removed.
|
||||
use nested::another::{self, I};
|
||||
//~^ WARN unused import
|
||||
|
||||
fn main() {
|
||||
let _ = (B, F, another::I);
|
||||
}
|
32
tests/ui/suggestions/unused-imports.stderr
Normal file
32
tests/ui/suggestions/unused-imports.stderr
Normal file
@ -0,0 +1,32 @@
|
||||
warning: unused imports: `A`, `C`
|
||||
--> $DIR/unused-imports.rs:22: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:26:5
|
||||
|
|
||||
LL | D,
|
||||
| ^
|
||||
LL | even_more::{
|
||||
LL | E,
|
||||
| ^
|
||||
LL | F,
|
||||
LL | G,
|
||||
| ^
|
||||
|
||||
warning: unused import: `I`
|
||||
--> $DIR/unused-imports.rs:37:29
|
||||
|
|
||||
LL | use nested::another::{self, I};
|
||||
| ^
|
||||
|
||||
warning: 3 warnings emitted
|
||||
|
Loading…
Reference in New Issue
Block a user