Skip to content

Exclude block-style comments in wrap_str/filter_normal_code check #4668

Open
@calebcartwright

Description

@calebcartwright

There's a utility function, wrap_str, used in various locations throughout the rustfmt codebase which does some checks against a string of formatted code, including whether each line in the string will fit within the width constraints.

The width check is supposed to exclude comments, and does so successfully for line-style comments (e.g. // foo bar). However, there is an issue where it does not exclude block-style comments (e.g. /* foo bar */).

The code that handles sorting out comments can be found in the comments.rs file:

pub(crate) fn filter_normal_code(code: &str) -> String {
let mut buffer = String::with_capacity(code.len());
LineClasses::new(code).for_each(|(kind, line)| match kind {
FullCodeCharKind::Normal
| FullCodeCharKind::StartString
| FullCodeCharKind::InString
| FullCodeCharKind::EndString => {
buffer.push_str(&line);
buffer.push('\n');
}
_ => {}
});
if !code.ends_with('\n') && buffer.ends_with('\n') {
buffer.pop();
}
buffer
}

and this would need to be extended to exclude block-style comments as well. Remember that multi-line block style comments are a possibility, so that needs to be accounted for as well, though happy to accept improvements that cover single-line block style comments.

The changes should include tests, for example additional unit tests like the existing ones for filter_normal_code:

fn test_filter_normal_code() {
let s = r#"
fn main() {
println!("hello, world");
}
"#;
assert_eq!(s, filter_normal_code(s));
let s_with_comment = r#"
fn main() {
// hello, world
println!("hello, world");
}
"#;
assert_eq!(s, filter_normal_code(s_with_comment));
}
}

Additionally, it would be beneficial to include the standard system/idempotence tests with an input file (tests/source/...) that contains snippets that result in the above code paths getting hit, such as a chain that contains a block-style comment that exceeds max_width, along with a target/output file (tests/target/...) that shows the resultant formatting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    1x-backport:pendingFixed/resolved in source but not yet backported to a 1x branch and releasea-commentsgood first issueIssues up for grabs, also good candidates for new rustfmt contributorshelp wantedp-medium

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions