Skip to content

Consider Imports Reorder config when merging Use Trees #5621

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

davidBar-On
Copy link
Contributor

@davidBar-On davidBar-On commented Nov 30, 2022

While evaluating enhancements to PR #5612, I found that merging use-trees does not take into account the imports_reorder setting and it is considered to set as true. Assuming this is an issue, this PR is an attempt to fix it. This is done by adding the imports_reorder config value as a parameter to the use-trees merge related functions.

Note that because of the added parameter, many internal test cases in imports.rs were changed. For the existing tests I added true as the imports_reorder value, and I added a version of the tests with false value.

One case that is not handled by this PR, and that was raised in a PR #5612 comment is the formatting of the following code, when imports_granularity=Preserve and reorder_imports=true:

use a::b::c::{
d::e
};

In this case, because of the Preserve, it is expected that the output will be use a::b::c::{d::e}, but it is use a::b::c::d::e.

For the record, following is a possible fix for this issue (if it is an issue). I didn't add this fix because it affects some existing test cases. The possible fix is to UseTree::normalize():

  1. Add imports_granularity argument to the function (usually the passed value is context.config.imports_granularity()).
  2. Change:

    rustfmt/src/imports.rs

    Lines 590 to 595 in ee2bed9

    // Normalise foo::{bar} -> foo::bar
    if let UseSegmentKind::List(ref list) = last.kind {
    if list.len() == 1 && list[0].to_string() != "self" {
    normalize_sole_list = true;
    }
    }

    To:
        // Normalise foo::{bar} -> foo::bar
        if let UseSegmentKind::List(ref list) = last.kind {
            if list.len() == 1 && list[0].to_string() != "self" && imports_granularity != ImportGranularity::Preserve {
                normalize_sole_list = true;
            }
        }

@ytmimi
Copy link
Contributor

ytmimi commented Nov 30, 2022

Thanks for the PR, and taking the time to look into this. I took a really quick look, and I don't think this is an issue. I think users expect that when we merge imports we also sort them within the new import list, but maybe someone out there would like some more explicit control with the reorder_imports option so maybe we should keep this open. Personally, my vote would be to close this. @calebcartwright what are your thoughts?

One case that is not handled by this PR, and that was raised in a PR #5162 comment is the formatting of the following code, when imports_granularity=Preserve and reorder_imports=true:

use a::b::c::{
d::e
};

In this case, because of the Preserve, it is expected that the output will be use a::b::c::{d::e}, but it is use a::b::c::d::e.

I believe the above 👆🏼 issue that's not handled by this PR is the only one that needs fixing as it's inconsistent with the definition of Preserve, which is.

Do not change the granularity of any imports and preserve the original structure written by the developer.

However, any fix would need to be version gated because reorder_imports is a stable config option and reorder_imports=true is the default.

I believe fixing the discrepancy in the case mentioned above should be simple enough, and it might make more sense to add an issue for it to the backlog and label it as good-first-issue for a new contributor to work on.

@davidBar-On
Copy link
Contributor Author

I think users expect that when we merge imports we also sort them within the new import list ... Personally, my vote would be to close this.

My view on this (as much as it worth) is that this is the right approach, but it should be extended so imports_granularity=Crate and reorder_imports=false will be mutual exclusive. I.e. rustfmt should not allow setting these two values, and when imports_granularity=Crate is set, rustfmt should implicitly set reorder_imports to true. Otherwise non-merged parts will not be sorted and merged parts will be sorted, which seem to be a conflict.

There are probably other similar cases. E.g. imports_granularity=Preserve and reorder_imports=true may be mutual exclusive, and imports_granularity=Preserve should implicitly implyreorder_imports=false.

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.

2 participants