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

Trailing whitespaces are stripped in raw string literals in doc tests #5978

Open
Pistonight opened this issue Dec 9, 2023 · 2 comments
Open

Comments

@Pistonight
Copy link

Example:

/// Doc Test
/// ```rust
/// let expected = "\nfoo \n";
/// assert_eq!(expected, r#"
/// foo 
/// "#);
/// ```
pub fn main() {}

Note that the expected string has a space before the last newline.
cargo fmt strips the space in the raw string literal, causing passing doc tests to fail afterwards

@Pistonight
Copy link
Author

This issue only exists in doc comments. Trailing spaces in raw string literals are kept correctly in regular code

@ytmimi
Copy link
Contributor

ytmimi commented Dec 13, 2023

@Pistonight thanks for the report. Generally, rustfmt does it's best to remove trailing whitespace, but I understand in this case it's changing the semantics of the code in the doc test. If possible, I'd encourage you to write your doc test in a way that avoids trailing whitespace.

I did a little investigating into what's going on. Hopefully this will be useful for anyone if they decide to work on this:

In this particular case code execution is going to light_rewrite_comment, which is causing the trailing space to be removed. That code path doesn't have any real awareness of "am I in a rust code block within a doc comment".

light_rewrite_comment(first_group, shape.indent, config, is_doc_comment)

Code execution continues on to trim_end_unless_two_whitespaces and that's where we seem to be removing the trailing whitespace.

trim_end_unless_two_whitespaces(left_trimmed, is_doc_comment)

I thought that configuring rustfmt with format_code_in_doc_comments=true might help, but in that case code execution will hit rewtie_comment_inner

rustfmt/src/comment.rs

Lines 376 to 383 in 2174e60

rewrite_comment_inner(
first_group,
block_style,
style,
shape,
config,
is_doc_comment || style.is_doc_comment(),
)?

and again we end up calling trim_end_unless_two_whitespaces before we do any of the very basic logic to determine if we're formatting a code block within a doc comment.

rustfmt/src/comment.rs

Lines 922 to 933 in 2174e60

let lines = orig
.lines()
.enumerate()
.map(|(i, mut line)| {
line = trim_end_unless_two_whitespaces(line.trim_start(), is_doc_comment);
// Drop old closer.
if i == line_breaks && line.ends_with("*/") && !line.starts_with("//") {
line = line[..(line.len() - 2)].trim_end();
}
line
})

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

No branches or pull requests

2 participants