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

Option to create groups for std, external crates, and other imports #4445

Merged
merged 12 commits into from
Nov 16, 2020

Conversation

MattX
Copy link
Contributor

@MattX MattX commented Sep 30, 2020

This adds a configuration flag, reorder_imports_opinionated, that causes existing import groups to be discarded and replaced by three groups for standard imports, other imports, and self/super/crate imports.

The option name isn't great, we can change it if there are better ideas.

I know @calebcartwright raised a possible issue in #4107 (comment), but I'm not sure if it is still a blocker.

Resolves #4107.

@calebcartwright
Copy link
Member

Thanks for the PR @MattX! Excited to see this one. I don't think I'll have a chance to give this a review tonight, but a few initial thoughts for you:

  • I think we'll want to use a more rich type for the config option instead of a simple boolean, for example an enum where each variant can represent a set of the groupings/order (even if there's only two variants in the beginning). I could see different camps wanting this feature albeit with different ordering and only having a boolean option would make that tricky
  • We probably need to bikeshed on the name a bit. To me it's more of a imports_groupings or group_imports or import_grouping_strategy or something else, but I don't think we want to have the word opinionated in there
  • Let's add some additional tests that incorporate this new option in conjunction with the various other import-related options to make sure there's no unexpected/undesired behavior when using multiple options together

@calebcartwright
Copy link
Member

I know @calebcartwright raised a possible issue in #4107 (comment), but I'm not sure if it is still a blocker.

The bug with comment association will be a blocker for being able to stabilize this option, but not a blocker for being able to make it available on nightly as an unstable option

@MattX MattX changed the title Option to create groups for std, local create, and other imports Option to create groups for std, local crate, and other imports Oct 1, 2020
@MattX
Copy link
Contributor Author

MattX commented Oct 1, 2020

Thanks for the feedback!

  • I've renamed the option to group_imports for now. I'm happy to change it to anything else.
  • I've made the parameter into an enum. Not sure how to describe the current regrouping behavior, so I've called it StdExternalCrate for now. Also happy to change that.
  • I've added two tests to check the interaction with merge_imports and reorder_imports.

The way I've implemented it, this new option has no effect when reorder_imports is false. This is more because it's more straightforward to implement than because it makes sense. After all, it seems possible to group imports without sorting them within each group (but I don't know if this is really something people want).

In any case, it might make sense to add a warning or error when reorder_imports = false and group_imports != None. I didn't see existing machinery to validate the config this way, so I haven't added this for now.

@calebcartwright
Copy link
Member

calebcartwright commented Oct 4, 2020

Thanks for the updates, I like the new name better.

The way I've implemented it, this new option has no effect when reorder_imports is false. This is more because it's more straightforward to implement than because it makes sense. After all, it seems possible to group imports without sorting them within each group (but I don't know if this is really something people want).

I was wondering about this one. I don't think we'll be able to couple the two options together and have this one only be operational one another has a certain value. Logically it makes sense that the majority of folks that would want an enforced grouping (and a sorting of those groups) would want to have the elements sorted within that group, but it's almost inevitable that there will be some folks that want to use their own/different sorting within the groups.

I imagine it'll add a bit of complexity but it's something we'll need to do

(Sorry for the PR close/reopen, accidentally hit the wrong button)

Comment on lines 2011 to 2026
## `group_imports`

Discard existing import groups, and create three groups for:
1. `std`, `core` and `alloc`,
2. external crates,
3. `self`, `super` and `crate` imports.

Within each group, imports are sorted as with `reorder_imports`.

This has no effect is `reorder_imports` is `false`.

- **Default value**: `None`
- **Possible values**: `None`, `StdExternalCrate`
- **Stable**: No

#### `None` (default):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the description of the option generic about what the option does/what it controls as opposed to describing the behavior of a particular supported variant (e.g. Controls the strategy for how imports are grouped together...)

And given the denotations of None within Rust, I'd suggest we use Preserve instead, which will also be consistent with a few other rustfmt config option variants

@MattX
Copy link
Contributor Author

MattX commented Oct 4, 2020

Thanks for the feedback! I was actually able to decouple ordering and grouping without much difficulty. I've also renamed None to Preserve.

src/config.rs Outdated
@@ -78,6 +78,8 @@ create_config! {
imports_indent: IndentStyle, IndentStyle::Block, false, "Indent of imports";
imports_layout: ListTactic, ListTactic::Mixed, false, "Item layout inside a import block";
merge_imports: bool, false, false, "Merge imports";
group_imports: GroupImportsTactic, GroupImportsTactic::Preserve, false,
"Reorganize import groups";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit but could we update this with something similar to what was changed in the Configurations.md file, like Controls the strategy for how imports are grouped together?

@@ -227,19 +229,34 @@ fn rewrite_reorderable_items(
if context.config.merge_imports() {
normalized_items = merge_use_trees(normalized_items);
}
normalized_items.sort();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll confess this gave me pause at first glance, but see why we had to wrap the sorting behind the reorder_imports check here now since we can get here even if reorder_imports false with non-Preservation group import strategies.

Copy link
Member

@calebcartwright calebcartwright left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work @MattX, thank you! One super minor item left inline, but otherwise this is good to go from my perspective

@MattX MattX force-pushed the master branch 2 times, most recently from 0da8517 to ee1acb5 Compare October 6, 2020 02:23
@MattX MattX changed the title Option to create groups for std, local crate, and other imports Option to create groups for std, external crates, and other imports Oct 6, 2020
Copy link
Member

@calebcartwright calebcartwright left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@calebcartwright
Copy link
Member

Everything LGTM to me @MattX. Going to hold off a bit on merging though so @topecongiro can weigh in since this is a new config option

@MattX
Copy link
Contributor Author

MattX commented Oct 6, 2020

Sounds good!

@MattX
Copy link
Contributor Author

MattX commented Oct 6, 2020

Once it's reviewed, any chance this can be tagged as hacktoberfest-accepted? I want my t-shirt :p

Copy link
Contributor

@topecongiro topecongiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR! I think that the current implementation is good enough for the first round of implementing this feature, except for the inline comment. Would you mind fixing it and adding a test?


wrap_reorderable_items(context, &item_vec, nested_shape)
Some(item_vec.join("\n\n"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to respect the current indentation here to indent inside inner modules correctly. E.g.,

mod test {
    use crate::foo::bar;
    use std::path;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I've added code to handle this case but I don't know if it's the best way to do things. Let me know if it's not.

@MattX
Copy link
Contributor Author

MattX commented Oct 27, 2020

Looks like the rustc_ap_rustc_data_structures crate is failing to compile in integ tests. The tests work for me locally (I'm probably using a different minor version?). I'll retry the checks when this is fixed.

@calebcartwright
Copy link
Member

There's a broken toolstate issue on nightly at the moment that requires us to bump the rustc-ap crates here. Those crates (snapshots of rustc internals) are published once a week, and I'm waiting to grab the next one which should be done in ~16 hours or so.

@calebcartwright
Copy link
Member

crates bumped, you should be able to rebase now

@MattX
Copy link
Contributor Author

MattX commented Nov 16, 2020

Hey, just pinging on this to make sure it gets merged before it's too outdated. Let me know if there's anything that still needs to be done on my end.

@calebcartwright
Copy link
Member

@topecongiro going to go ahead and merge as the change you requested appears to have been resolved

@calebcartwright calebcartwright merged commit 17d90ca into rust-lang:master Nov 16, 2020
@calebcartwright
Copy link
Member

@MattX - note that while this has been merged, and thus immediately available for anyone building rustfmt 2.0 from source, it's not available in the version of rustfmt distributed via rustup as that's on a different branch.

If you'd like to see this new feature supported in a released version of rustfmt, that will need to be backported to a target 1.x branch (1.4.27 at the moment). If you're interested in such a PR please let us know, otherwise I'll try to take a look at cherry-picking/backporting at some point down the road

@MattX
Copy link
Contributor Author

MattX commented Nov 17, 2020

Ok! I'm opening a new PR for 1.4.27.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Opinionated sorting of use statement blocks
4 participants