-
Notifications
You must be signed in to change notification settings - Fork 898
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
Import sorting does not handle uppercase/lowercase consistently #5269
Comments
Thanks for the report! Confirming that I'm able to reproduce this on |
@ytmimi Thank you! |
I did some digging and I think the formatting you're seeing is caused by the implementation of Lines 761 to 780 in 1bb85bd
|
It also looks like we're not doing an explicit "CamelCase" check, and that might explain why |
Acknowledge seeing this and share the initial reaction of puzzlement. Obviously any changes here, bug fix or otherwise, can have a wide blast radius of formatting changes, so we'll need to be extremely thorough and thoughtful. The corresponding code hasn't been touched in a long time, so I'd also suggest going back through the original style guide issue to see if perhaps there were any discussion of relevant behavior that perhaps never made its way into the final codified result. Though somewhat tangential, #5075 and rust-lang/style-team#143 may also be of interest if the door is being reopened |
It looks like #1785 was the PR that introduced this change. |
@calebcartwright I do understand that rustfmt has to be cautious about introducing changes that will cause churn. If rustfmt were sorting in a plausible order that just disagreed with the style guide, I would absolutely suggest we keep that until an edition boundary or similar, to avoid churn. However, in this case, it seems like this is producing an unpredictable order that people can't easily replicate, and I think this may be close enough to a bugfix to be worth considering. (That's separate from any future changes to do version-sorting or similar, which I'd love to see but which does seem like 2.0 material.) This won't arise in every import list, and in the ones where it does arise, I think the inconsistency and inability for a human to produce the same order as rustfmt before running rustfmt provide a sufficiently compelling motivation for this change. That said, I also acknowledge that any such change will incur a cost, even if we think that cost is worthwhile. And whether or not this can be fixed in rustfmt 1, I'd still like to see it fixed in the next generation. |
@joshtriplett - to be clear, I have not said nor am I implying that we do nothing. It deserves consideration and careful inspection, both to determine/confirm there's divergence from prescribed behavior and if so then when/how a fix/change would be rolled out. I am stressing the need for caution and thoroughness, however, as there's been more than a few occasions where something seemed like an obvious bug at first blush but which later turned out to not be the case. I realize that if there were anyone that would know/remember the specifics it would be folks like yourself and Nick, but on our end we do still need to go back through relevant discussions to confirm, especially given the age and thoroughness of those threads. |
I'm marking this as a p-high, as I'd really like to get @yaahc - this could potentially be a pretty gnarly one, but also potentially a decent one if you wanted to hack on the rustfmt codebase a little. Subsequent to some of my prior comments, @ytmimi has developed some really sweet automation that we can use to evaluate changes for idempotency across multiple codebases (kinda like our own mini formatting crater run) that helps reduce the review burden of having to mentally conjure potential formatting impacts |
Is this issue as simple as redoing the section @ytmimi linked to not check for cases and instead do ascii sorting? Or are there further decisions to make here, with impact being the biggest issue? If impact is an issue, could sorting just become style edition dependent? I am assuming that would be fairly easy too if edition is stored in an atomic somewhere. Btw @joshtriplett your style guide link in the original post is dead |
@tgross35 Lines 104 to 108 in 16db2a4
That should make it easier to change the |
TLDR: The ALL_CAPS vs CamelCase vs snake_case sorting came about in order to separate constants from types in list imports (e.g.
Updated style guide link: https://github.com/rust-lang/rust/blob/master/src/doc/style-guide/src/items.md#ordering-of-imports Timeline of rust-lang/style-team#24 as it pertains: Dec 16, 2016:
Mar 28, 2017:
Mar 29, 2017:
May 9, 2017:
July 12, 2017:
July 13, 2017:
Apr 14, 2018:
|
Using casing conventions as a stand-in for types seems like the main flaw here. To achieve consistency you need one of the following
Point 3 then makes a demand for an extra rule (whether that rule is exposed or not), which determines the sorting order of the groups themselves. So I believe the correct approach requires three definitions, which may or may not be exposed as configurable, but must be defined nonetheless:
|
@kniteli Unfortunately there's no way to know what the type of a value is when it's being imported. The type of each identifier isn't represented in the AST that rustfmt uses to format your program. rustfmt has no idea whether you're importing a struct, enum, trait, function, constant, macro, etc. |
I assumed that might be the case. I'd imagine rustfmt is probably designed to work on single files with no cross-project context necessary? Yes, I wasn't necessarily trying to prescribe a course of action, I was more trying to block out the boundaries that any solution has to adhere to, which leads us to: fundamentally I don't think there's any way to for this issue to be closed without performing the intended grouping of language constructs with the proper tools rather than using a casing convention. There's just... not enough info for it to solve correctly, and there never will be based on characters and casing. It's either drop the the groups, somehow get access to the language types and group that way, or live with the current reality of "usually acceptable but still incorrect" sorting. I think long term the only solutions are dropping the groups or getting access to the language constructs. First class unicode support will invariably come to rust sooner or later, and that's just incompatible with this current approach. I suppose another approach would be to just make the groups entirely configurable by some user defined patterns, the default of which is the current setup, but that sounds complicated and error prone, both for the end user and rustfmt development. It does deflect the unicode issue though. |
There is another possibility, just to be exhaustive. I mentioned this approach earlier:
I assume you have the construct types on the source file side (unlike during an import), so this approach should be achievable. It would solve the immediate problem, but doesn't solve for unicode (if that's important to you), and it makes a coherent sort dependent on another rule being active. |
@kniteli sorry, I'm not sure I understand what you mean. Any solution that involves name resolution isn't going to work. At the time rustfmt is ready to rewrite / sort an import it can only reliably rely on the information present in the ast::UseTree node. Trying to infer the type of an identifier based on source code might seem doable, but it isn't a very robust solution. Among other issues, it could only be applied for locally defined types and then we'd end up with inconsistencies around sorting imports from external dependencies. |
Right, makes sense. So we come back around to the main problem outlined: you can't robustly group using convention, especially because the imports might be from a library that uses a different convention, so even the idea I mentioned about user configurable strategies doesn't work.
That's the only solution (beside dropping the groups, or ignoring the issue), that's what I'm trying to highlight. You're not going to find the necessary extra information to do this "group and sort" robustly without it. So if you're saying that it's impossible, then the only two choices left are 1. stop grouping or 2. ignore the issue. Make that decision and then #4991 has a path to stabilization. I suspect I'm simply retreading ground that's already been discussed out-of-band, but no decision has been made because it's an unsatisfying answer. |
I'm going to close because from the rustfmt team perspective this is now resolved with #6284 completed The original topic here was a report about compatibility with the sorting algorithm prescribed in the Style Guide (specifically, Editions 2015-2021 of the Style Guide). That can't be modified within the context of those older Style editions due to rustfmt's stability guarantee, so there's nothing to be done there. The Style Team provided new sorting prescriptions in the 2024 Style edition (which I'll note is intended to also cover unicode), and that will be the rustfmt behavior for 2024 onwards. As such, everything related to the original report is resolved and there's no more action to be taken. Some of the subsequent discussion broached into how sorting could effect other options, but I am still going to close this issue as those discussions should happen on their respective issues. |
This may be related to #4648 , but I don't know if it's the same issue.
rustfmt sorts imports, and braced groups within imports, in the following order:
This isn't alphabetical, ASCIIbetical, or any other sort order that I can identify.
The style guide says to sort ascii-betically here, in both cases (top-level and within braced lists).
The text was updated successfully, but these errors were encountered: