Description
Rustfmt fails to format the following file.
fn main() {
let x = 0; // X
//.Y
}
- The failure is sensitive to the contents of the second comment. For example
// Y
or//Y
does not hit this bug.//.Y
or//~Y
or//^Y
do. - The failure does not appear to be sensitive to the contents of the first comment, just that there is a comment.
- The failure is not sensitive to the second comment being the last thing in a block; it occurs even if there are more statements inside the block after the second comment. I left that out above because it is unnecessary for a minimal repro.
Repro against current master (3de1a09):
$ echo -e 'fn main() {\n let x = 0; // X\n //.Y\n}' | cargo run --bin rustfmt -- --edition=2021
fn main() {
let x = 0; // X
//.Y
}
error[internal]: left behind trailing whitespace
--> <stdin>:3:3:1
|
3 |
| ^^^^
|
warning: rustfmt has failed to format. See previous 1 errors.
I looked through all the open issues matching a "left behind trailing whitespace" search in this repo (of which there are many) and all the closed ones that mention "comment" in the title, and I did not find one that matches this situation. They mostly seemed to involve comments placed in weird places inside an expression or statement, like let x =⏎// comment⏎value;
or map(|_|⏎//comment⏎value)
. In contrast, this issue involves comments in a location where a conscientious person might reasonably put a comment (particularly if there is more stuff in the block after the second comment, as mentioned above). In fact the compiletest_rs crate requires such comments (//~^ ERROR
) which is how Miri's test suite ran into this bug.
Activity
ytmimi commentedon Jun 20, 2022
Thanks for the report!
I quickly took a look at this. At least in the case that you've described above it looks like we need
version=Two
to be set. Settingversion=One
produces different formatting. Usingrustfmt 1.5.0-nightly (3de1a095 2022-06-17)
withversion=One
this is what I'm getting for your input snippet:At least in the case where the comment is the last item in a block we hit the following code path:
rustfmt/src/visitor.rs
Lines 311 to 325 in 3de1a09
I think the issue here is that we push an indented newline on Line 315 with the intention that the next thing we push will be the comment, but
rewrite_comment
is returningSome("\n //.Y")
(there are 4 spaces that aren't being rendered so well), so that explains the extra whitespace error we're seeing here. Here's the code path we hit inrewrite_comment
:rustfmt/src/comment.rs
Lines 385 to 408 in 3de1a09
Still need to do some digging into the case where the comment isn't the last statement in the block, but I'd assume that something similar is happening. Also a little confused that the content of the 2nd comment would influence this, but I'll see if I can figure that out as well.
ytmimi commentedon Jun 20, 2022
Okay after some more digging its seems like the
//.Y
and the//~Y
cases are being treated asCommentStyle::Custom
since that's whatcomments::comment_style
is returning.rustfmt/src/comment.rs
Lines 41 to 50 in 3de1a09
Placing a space between the leading
//
and the~
or.
helps rustfmt correctly classify these comments asCommentStyle::DoubleSlash
. @dtolnay would adding the leading space be an acceptable workaround for now?@calebcartwright I'm wondering if you recall what
CommentStyle::Custom
is used for. I'm guessing that it might be used to implement itemized blocks but I'm not totally sure where it gets used. For what it's worth, I did some testing and hard coded the comment_style toCommentStyle::DoubleSlash
and that seems to have resolved the issue we're seeing here.I think I have a fix for this, but I wanted to get some more context on
CommentStyle::Custom
to make sure what I'm thinking makes sense.dtolnay commentedon Jun 20, 2022
No.
compiletest_rs
requires no space. See https://rustc-dev-guide.rust-lang.org/tests/ui.html#error-annotations.ytmimi commentedon Jun 20, 2022
Got it, just wanted to see. It looks like the
CommentStyle::Custom
variant was added in #1607 to handle cases with multiple forward slashesAuto merge of #2242 - dtolnay-contrib:rustfmtskip, r=RalfJung
comment::rewrite_comment
#5392error[internal]: left behind trailing whitespace
#5868