-
Notifications
You must be signed in to change notification settings - Fork 69
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
Fully rustfmt use
declarations
#750
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed. Concerns or objections to the proposal should be discussed on Zulip and formally registered here by adding a comment with the following syntax:
Concerns can be lifted with:
See documentation at https://forge.rust-lang.org cc @rust-lang/compiler @rust-lang/compiler-contributors |
use
declarations
rust-lang/rust#125443 has a draft implementation with the recommended options, for those who want to see what it looks like on the whole repository. |
Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750.
…iler-errors Run rustfmt on files that need it. Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750.
…er-errors Run rustfmt on files that need it. Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750.
…iler-errors Run rustfmt on files that need it. Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750.
Rollup merge of rust-lang#125477 - nnethercote:missed-rustfmt, r=compiler-errors Run rustfmt on files that need it. Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750.
Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750.
Add a fast-path to `Debug` ASCII `&str` Instead of going through the `EscapeDebug` machinery, we can just skip over ASCII chars that don’t need any escaping. Introduce printable-ASCII fast-path for `impl Debug for str` Instead of having a single loop that works on utf-8 `char`s, this splits the implementation into a loop that quickly skips over printable ASCII, falling back to per-char iteration for other chunks. Switch to primarily using `&str` Surprisingly, benchmarks have shown that using `&str` instead of `&[u8]` with some `unsafe` code is actually faster. Process a single not-ASCII-printable `char` per iteration This avoids having to collect a non-ASCII-printable run before processing it. std: simplify key-based thread locals std: clean up the TLS implementation Make clamp inline Run rustfmt on files that need it. Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on rust-lang/compiler-team#750. Fix the dead link in the bootstrap README Notify kobzol after changes to `opt-dist` Revert "Rollup merge of rust-lang#123979 - oli-obk:define_opaque_types7, r=compiler-errors" This reverts commit f939d1f, reversing changes made to 183c706. Add regression tests Only suppress binop error in favor of semicolon suggestion if we're in an assignment statement compiler: const_eval/transform/validate.rs -> mir_transform/validate.rs compiler: unnest rustc_const_eval::check_consts clippy: unnest check_consts miri: receive the blessings of validate.rs Migrate `run-make/rustdoc-with-output-dir-option` to `rmake.rs` Fix some SIMD intrinsics documentation Actually just remove the special case altogether rustdoc-json: Add test for keywords with `--document-private-items` tag more stuff with `WG-trait-system-refactor` Warn/error on self ctor from outer item in inner item (Mostly) revert "Account for type param from other item in `note_and_explain`" This mostly reverts commit 7449478. It also removes an `opt_param_at` that really is unnecessary given our ICE policy for malformed intrinsics. Update cargo use posix_memalign on most Unix targets fix typo Co-authored-by: Jubilee <[email protected]> Fail relating constants of different types Use regular type equating instead of a custom query Bump bootstrap compiler to the latest beta compiler Remove now outdated comment since we bumped stage0 Stop using the avx512er and avx512pf x86 target features They are no longer supported by LLVM 19. Fixes rust-lang#125492 remove proof tree formatter, make em shallow Don't eagerly monomorphize drop for types that are impossible to instantiate Better ICE message for unresolved upvars Structurally resolve before builtin_index in EUV Add manual Sync impl for ReentrantLockGuard Fixes: rust-lang#125526
@rustbot second |
I think there have been enough discussions on Zulip that should be considered before just accepting this proposal as-is.
|
Ah, I see the MCP has been updated based on the discussion. A shame that we don't get diffs for that. |
you can click the |
As decided in rust-lang/compiler-team#750. Use declarations are currently wildly inconsistent because rustfmt is quite unopinionated about how they should be formatted. The `rustfmt.toml` additions makes rustfmt more opinionated, which avoids the need for any decision when adding new use declarations to a file.
As decided in rust-lang/compiler-team#750. Use declarations are currently wildly inconsistent because rustfmt is quite unopinionated about how they should be formatted. The `rustfmt.toml` additions makes rustfmt more opinionated, which avoids the need for any decision when adding new use declarations to a file. This commit only updates `rustfmt.toml`. The next commit will do the reformatting.
@rustbot label -final-comment-period +major-change-accepted |
Update: just before I originally planned to merge this change in rust-lang/rust#125443, I found a minor issue with comments on // A lovely import.
use crate::ast;
use rustc_parser::parser;
use std::fmt; rustfmt will rearrange this to this with the configuration we've chosen: use std::fmt;
use rustc_parser::parser;
// A lovely import.
use crate::ast; The comment that applied to the Now what about this? // Three lovely imports.
use crate::ast;
use rustc_parser::parser;
use std::fmt; This is almost identical to the previous case, but the comment clearly is intended to apply to multiple There are many tens of thousands of Based on all the above, I intend to update and merge rust-lang/rust#125443 soon, hopefully at a time when the merge queue is quiet. |
That's this rustfmt issue: rust-lang/rustfmt#6241. I think it is very unfortunate that we should lose the ability to comment a group of imports. Seems like something around 1 in a 100 files is affected by this. (Counting individual
I don't recall ever losing noticeable time to format this by hand, and there were no arguments that I am aware of until you started them by deciding that we should set group_imports -- an unstable rustfmt flag that's considered experimental for a reason. As far as I am concerned, there was no problem with our So there's a very clear alternative that also basically entirely avoids having to argue about You are repeating the usual arguments for doing any formatting at all, but I don't think they apply here. This is about a small subset of the code that's rarely read carefully; our current inconsistent |
Ralf: on the question of motivation, I described that in the MCP description above. Inconsistent More generally, I have followed (and gone beyond) the required procedures for making a change of this kind.
Your opposition to this has been strong from the start, at first about the original I contend that all procedures have been completed and this is appropriate to merge. I expect you will say that the comment-on-multiple-declarations issue is a showstopper that invalidates much or all of what went before. I disagree; although we have lost one way to write a comment describing a group of imports, rust-lang/rust#126776 demonstrates there are multiple good alternatives, and comments like that are rare. The two of us have been doing most of the talking. I would like to hear thoughts from other people. |
I'm not surprised that a formatting change has provoked so much arguing, but I'm still disappointed at how much energy has been spent on this topic. There are decisions made in the Rust organization that I do not fully agree with, but I try to defer to the wisdom of my peers and the group's overall preferences, because that's just part of being on a team.
Every time I touch a
I do not agree that this is a major downside. I looked at the comments that @nnethercote deleted, and I didn't see anything of significant value being lost. |
(I want to let others talk, but I will say one brief thing to pre-empt possible confusion: I did delete two comments in rust-lang/rust#126776 that I thought were low-value, but deleting them was not the only option. There are ways they could have been preserved. See the "post-merge update" in this comment for details on the comment-on-multiple-declarations issue.) |
Fully agreed. The same goes for you.
I also touch a lot of files and never spent any noticeable time thinking about this. I find it hard to say which of these positions is more representative.
Yes, and I notice that both of the PRs you are referencing for concrete evidence that there is a problem in practice here are by you. I understand that you are bothered by this inconsistency. All else being equal, I would also prefer consistent ordering over the current situation! But as rust-lang/rust#126717 and rust-lang/rust#126717 show, all else is not equal. Increasingly it becomes clear why this is still an experimental option in rustfmt.
Yes you did, I never claimed anything else. I appreciate that this is a lot of work, and I thank you for constructively engaging in discussion throughout this. I was okay with the decision that was eventually made -- I may have still preferred another outcome, but the downsides I was aware of at the time were not significant enough to justify spending more time on this. But most of the discussion happened without us being aware that we'd lose the ability to comment blocks of imports, and for me that tipped the scale back from "harmless" to "rather not". I am not the only one who considers that issue relevant -- @cuviper also spoke up in rust-lang/rust#126776 with similar concerns. @workingjubilee was disappointed by another aspect of rustfmt formatting, one that would also be a non-issue if we could just have a comment above the
No, I was not going to say that. I was going to say that this is new evidence and we should make sure that there is still consensus in the compiler team to do this. If that is the case, I will concede that I am in a minority position here and accept that the team has different priorities/preferences.
I do not think that you have presented a good alternative. The one alternative I recall you suggesting is to duplicate the comment on each The only good alternative I could come up with so far is to add a Yes, comments like that are rare, but we're talking about formatting code that almost everyone scrolls over most of the time anyway. The benefit of formatting that is, in my view, very small, so it doesn't take a big downside to tip the scale.
When, after making a decision, new evidence relevant for this decision surfaces, then we should make sure that that does not change the group's opinion. This is part of our normal decision-making process -- the lang team may accept an RFC, but then during implementation new information surfaces, and that may well change the team's position. So I don't think it is fair to characterize my opposition here as trying to overthrow established team consensus; I am saying there is new evidence and so we shouldn't blindly go ahead with a decision made before this evidence was known. |
tbh I feel like most of this discussion is a symptom of the thought of PRing rustfmt being kinda anxiety inducing, because it has simultaneously very low review capacity and very strict stability promises. probably even stricter than the actual language's, honestly. |
May I ask y'all to move to the zulip thread that rustbot explicitly asks y'all to move to? |
As decided in rust-lang/compiler-team#750. Use declarations are currently wildly inconsistent because rustfmt is quite unopinionated about how they should be formatted. The `rustfmt.toml` additions makes rustfmt more opinionated, which avoids the need for any decision when adding new use declarations to a file. This commit only updates `rustfmt.toml` and `compiler/rustc_codegen_cranelift/rustfmt.toml`. The next commit will do the reformatting.
rustfmt `use` declarations This PR implements rust-lang/compiler-team#750, which changes how `use` declarations are formatted by adding these options to `rustfmt.toml`: ``` group_imports = "StdExternalCrate" imports_granularity = "Module" ``` r? `@ghost`
…r,cuviper,GuillaumeGomez rustfmt `use` declarations This PR implements rust-lang/compiler-team#750, which changes how `use` declarations are formatted by adding these options to `rustfmt.toml`: ``` group_imports = "StdExternalCrate" imports_granularity = "Module" ``` r? `@ghost`
This feature has worsened merge conflicts caused by |
|
As decided in rust-lang/compiler-team#750. Use declarations are currently wildly inconsistent because rustfmt is quite unopinionated about how they should be formatted. The `rustfmt.toml` additions makes rustfmt more opinionated, which avoids the need for any decision when adding new use declarations to a file. This commit only updates `rustfmt.toml` and `compiler/rustc_codegen_cranelift/rustfmt.toml`. The next commit will do the reformatting.
…,GuillaumeGomez rustfmt `use` declarations This PR implements rust-lang/compiler-team#750, which changes how `use` declarations are formatted by adding these options to `rustfmt.toml`: ``` group_imports = "StdExternalCrate" imports_granularity = "Module" ``` r? `@ghost`
Proposal
[Edit: the MCP has been updated after polling people on Zulip about the options, which uncovered some fairly clear preferences.]
TL;DR This MCP proposes adding these lines to
rustfmt.toml
and reformattinguse
declarations for the entire repository:Problem: inadequate auto-formatting of
use
declsrustc doesn't have a style guide because rustfmt and tidy theoretically obviate the need for one. In practice there are some style choices left under-specified. One of them is
use
declarations. By default rustfmt touchesuse
declarations only lightly.use
declarations within a section, where a section is a series ofuse
declarations without any intervening blank lines. The sorting isself
,super
,crate
, then alphabetical.use
declaration with braces.However, it doesn't express any opinion on two matters.
use
declarations should be divided into sections.This leaves a lot of flexibility and the repository uses a wide variety of styles. Many
use
item additions can occur in more than one place and require a choice from the author.For example, if I need to use
fruit::Orange
and a file already has these lines:should I insert in the first line, the second, or merge them?
Alternatively has use
use
sections forcrate
,rustc_*
, andstd
imports, where should I add something likeuse tracing::debug;
?These questions get particularly annoying in some large changes like rust-lang/rust#125434.
And attempts to improve even "obviously" badly arranged use declarations can be controversial.
These are all problems that auto-formatting is supposed to solve!
Solution: enable more opinionated rustfmt options
Fortunately rustfmt has some options that can fix the problems. We just need to make some decisions about how to set them, resulting a particular style.
There are various characteristics to consider for this style.
use.*foo
and get reliable hits?Scope
rustfmt.toml
applies to the entire repository. Although you can tell rustfmt to ignore certain files or directories, there is no practical way for part of the repository to opt into a subset of rustfmt options. Therefore, this change would apply to everything that rustfmt doesn't ignore, i.e.:compiler/
library/
src/
bootstrap
,librustdoc
,compiletest
,tidy
, plus a few other small toolscargo
,clippy
,miri
,rust-analyzer
,rustfmt
tests/
rmake.rs
files within this directoryAn MCP is appropriate for the compiler changes. I don't know what the equivalent mechanism would be for the other components, or if there even is one. Hopefully this MCP will suffice.
The choices
I have deliberately limited the discussion to options that are implemented.
There are four relevant rustfmt options. They are all unstable, but the relevant tracking issues are all three to five years old so there is some level of maturity.
The proposal is to add
group_imports = "One"
+imports_granularity = "Module"
, and leaveimports_layout
andimports_indent
with their default values. Discussion below.group_imports
This controls how sections are used.
Currently there are two common sectioning strategies in the codebase.
crate
,rustc_*
, andstd
, and when sectioning is used they are typically separate, though the order varies. Third-party items (e.g.use tracing::debug;
) are less common, and when present they are arranged inconsistently: sometimes in a separate section, sometimes withrustc_*
, and sometimes withstd
. Sometimespub use
items are in their own section. Sometimesuse
declarations with attributes are in their own section.There are two choices beyond the unsatisfactory "Preserve" default.
self
/super
/crate
are sorted to the top, everything else is alphabetical. This is ultra-simple and has good normalcy, matching a lot of existing code.std
in the first section,self
/super
/crate
in the last section, and everything else in the second section. This has reasonably good normalcy (though acrate
/external/std
ordering is probably more common in the codebase). The second section ends up with a mixture of local modules, local crates, and external crates because rustfmt doesn't have (and never will have) have enough information to distinguish these cases. #125645The choice of option doesn't affect conflict avoidance, greppability, or char-count, and barely affects line-count. So it's mostly a matter of normalcy and personal preference.
The proposal is to change to "StdExternalCrate", which received 9 votes. "One" received 4 votes, "no preference" received 3 votes, and "Preserve" (the existing default) used 1 vote. (This was the closest of the four votes.)
It's also worth noting that if there is one or more
use
sections, followed by one or more other kind of item, followed by one or more additionaluse
section, rustfmt won't rearrange theuse
declarations around that other kind of item. This happens in numerous places withmod
items. It's unclear if such cases should be fixed by moving all theuse
declarations together, and if so, whether they should come before or aftermod
items. I recommend leaving such cases as a follow-up.imports_granularity
This option dictates how much "factoring" of common prefixes is done, and how many things are imported by each individual
use
item.This choice is very important, affecting every characteristic. There are four choices beyond the unsatisfactory "Preserve" default.
use
declaration, as long as they have the same visibility and attributes. This ranks terribly for normalcy and greppability, though it is the best for char-count.The proposal is to change to "Module", which received 13 votes. "Crate", "Item", and "Preserve" (the default) each received 1 vote.
imports_layout
This only affects how lengthy
use
declarations are split across multiple lines.use
doesn't fit on one line then every entry gets its own line. More like the "Block" styling used everywhere else by rustfmt. Slightly worse for line-count, slightly better for conflict avoidance.imports_granularity = "Item"
, except better for char-count and even worse for line-count -- requires four lines to import two items from the same module!The proposal is to keep using "Mixed", which received 12 votes. The only other vote was for an option that rustfmt currently doesn't implement: "Horizontal" + splitting long items into multiple items.
imports_indent
This only affects how multi-line
use
declarations are indented. There are two options.indent_style
and is very Rust-y.The proposal is to keep using "Block", which was the unanimous choice with 13 votes.
Examples
Here are a few examples of the more plausible combinations. I have used a moderately complex collection of real
use
declarations from rustc, taken from a mixture of files, that demonstrate all the interesting cases.group_imports = "StdExternalCrate"
+imports_granularity = "Module"
This shows how the "external" section contains local crates (
rustc_*
), modules (borrow_set
) and enums (Nonterminal::*
), alongside external crates (smallvec
andtracing
).group_imports = "One"
+imports_granularity = "Module"
Note the
self
/super
/crate
at the top.group_imports = "One"
+imports_granularity = "Crate"
This is more indent-heavy and has a higher line-count than the previous example.
group_imports = "One"
+imports_granularity = "Item"
This one is really verbose.
group_imports = "One"
+imports_granularity = "Module"
+imports_layout = "HorizontalVertical"
Similar to
group_imports = "One"
+imports_granularity = "Module"
, but this:is changed to this:
Mentors or Reviewers
No mentors needed. The resulting PR will be enormous but fully automated, so anyone could review it.
Process
The main points of the Major Change Process are as follows:
@rustbot second
.-C flag
, then full team check-off is required.@rfcbot fcp merge
on either the MCP or the PR.You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered: