Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Omit final self from use statements. #4641

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -1710,7 +1710,7 @@ pub enum Foo {}
Merge together related imports based on their paths.

- **Default value**: `Preserve`
- **Possible values**: `Preserve`, `Crate`, `Module`
- **Possible values**: `Preserve`, `Crate`, `Module`, `Item`
- **Stable**: No

#### `Preserve` (default):
Expand Down Expand Up @@ -1749,6 +1749,21 @@ use foo::{a, b, c};
use qux::{h, i};
```

#### `Item`:

Flatten imports so that each has its own `use` statement.

```rust
use foo::a;
use foo::b;
use foo::b::f;
use foo::b::g;
use foo::c;
use foo::d::e;
use qux::h;
use qux::i;
```

## `merge_imports`

This option is deprecated. Use `imports_granularity = "Crate"` instead.
Expand Down
2 changes: 2 additions & 0 deletions src/config/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ pub enum ImportGranularity {
Crate,
/// Use one `use` statement per module.
Module,
/// Use one `use` statement per imported item.
Item,
}

#[config_type]
Expand Down
29 changes: 23 additions & 6 deletions src/formatting/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,24 +542,25 @@ impl UseTree {
SharedPrefix::Module => {
self.path[..self.path.len() - 1] == other.path[..other.path.len() - 1]
}
SharedPrefix::NoPrefix => false,
}
}
}

fn flatten(self) -> Vec<UseTree> {
match self.path.last() {
Some(UseSegment::List(list)) => {
if list.len() == 1 && list[0].path.len() == 1 {
if let UseSegment::Slf(..) = list[0].path[0] {
return vec![self];
};
}
let prefix = &self.path[..self.path.len() - 1];
let mut result = vec![];
for nested_use_tree in list {
for flattened in &mut nested_use_tree.clone().flatten() {
let mut new_path = prefix.to_vec();
new_path.append(&mut flattened.path);
if flattened.path.len() == 1 {
if let UseSegment::Slf(..) = flattened.path[0] {
new_path.pop();
}
}
result.push(UseTree {
path: new_path,
span: self.span,
Expand Down Expand Up @@ -854,6 +855,7 @@ impl Rewrite for UseTree {
pub(crate) enum SharedPrefix {
Crate,
Module,
NoPrefix,
}

#[cfg(test)]
Expand Down Expand Up @@ -1049,7 +1051,7 @@ mod test {
test_merge!(
Crate,
["a::{self}", "b::{self as foo}"],
["a::{self}", "b::{self as foo}"]
["a::self", "b::self as foo"]
);
}

Expand All @@ -1068,6 +1070,21 @@ mod test {
);
}

#[test]
fn test_use_tree_merge_no_prefix() {
test_merge!(
NoPrefix,
["foo::{a::{b, c}, d::e}"],
["foo::a::b", "foo::a::c", "foo::d::e"]
);

test_merge!(
NoPrefix,
["foo::{self, a, b::{c, d}, e::*}"],
["foo::self", "foo::a", "foo::b::c", "foo::b::d", "foo::e::*"]
)
}

#[test]
fn test_use_tree_flatten() {
assert_eq!(
Expand Down
27 changes: 21 additions & 6 deletions src/formatting/reorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,29 @@ fn rewrite_reorderable_or_regroupable_items(
for (item, list_item) in normalized_items.iter_mut().zip(list_items) {
item.list_item = Some(list_item.clone());
}
match context.config.imports_granularity() {
ImportGranularity::Crate => {
normalized_items = merge_use_trees(normalized_items, SharedPrefix::Crate)
}
normalized_items = match context.config.imports_granularity() {
ImportGranularity::Crate => merge_use_trees(normalized_items, SharedPrefix::Crate),
ImportGranularity::Module => {
normalized_items = merge_use_trees(normalized_items, SharedPrefix::Module)
merge_use_trees(normalized_items, SharedPrefix::Module)
}
ImportGranularity::Item => {
merge_use_trees(normalized_items, SharedPrefix::NoPrefix)
}
ImportGranularity::Preserve => normalized_items,
};
for item in normalized_items.iter_mut() {
if let Some(UseSegment::Slf(..)) = item.path.last() {
let self_seg = item.path.pop().unwrap();
match self_seg {
UseSegment::Slf(Some(self_rename)) => match item.path.last_mut() {
Some(UseSegment::Ident(_, rename @ None))
| Some(UseSegment::Crate(rename @ None))
| Some(UseSegment::Super(rename @ None)) => *rename = Some(self_rename),
_ => {}
},
_ => {}
}
}
ImportGranularity::Preserve => {}
}

let mut regrouped_items = match context.config.group_imports() {
Expand Down
6 changes: 6 additions & 0 deletions tests/source/imports_granularity_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// rustfmt-imports_granularity: Item

use a::{b, c, d};
use a::{f::g, h::{i, j}};
use a::{l::{self, m, n::o, p::*}};
use a::q::{self};
8 changes: 4 additions & 4 deletions tests/target/imports_granularity_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ pub use foo::{bar, foobar};
use a::b::c::{d, xxx, yyy, zzz, *};

// https://github.com/rust-lang/rustfmt/issues/3808
use d::{self};
use e::{self as foo};
use d;
use e as foo;
use f::{self, b};
use g::{self, a, b};
use h::a;
use i::a::{self};
use j::a::{self};
use i::a;
use j::a;

use k::{a, b, c, d};
use l::{a, b, c, d};
13 changes: 13 additions & 0 deletions tests/target/imports_granularity_item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// rustfmt-imports_granularity: Item

use a::b;
use a::c;
use a::d;
use a::f::g;
use a::h::i;
use a::h::j;
use a::l;
use a::l::m;
use a::l::n::o;
use a::l::p::*;
use a::q;
2 changes: 1 addition & 1 deletion tests/target/issue-3645.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
mod x {
use super::self as x;
use super as x;
}