Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0482ac8

Browse files
authored
Merge pull request rust-lang#3548 from bash/normalize-multiline-doc-attributes
Fix normalisation of multiline doc attributes
2 parents 421ed94 + 1ba35fc commit 0482ac8

File tree

4 files changed

+97
-5
lines changed

4 files changed

+97
-5
lines changed

src/attr.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use syntax::ast;
44
use syntax::source_map::{BytePos, Span, DUMMY_SP};
55

6+
use self::doc_comment::DocCommentFormatter;
67
use crate::comment::{contains_comment, rewrite_doc_comment, CommentStyle};
78
use crate::config::lists::*;
89
use crate::config::IndentStyle;
@@ -14,6 +15,8 @@ use crate::shape::Shape;
1415
use crate::types::{rewrite_path, PathContext};
1516
use crate::utils::{count_newlines, mk_sp};
1617

18+
mod doc_comment;
19+
1720
/// Returns attributes on the given statement.
1821
pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
1922
match stmt.node {
@@ -330,11 +333,9 @@ impl Rewrite for ast::Attribute {
330333
ast::AttrStyle::Outer => CommentStyle::TripleSlash,
331334
};
332335

333-
// Remove possible whitespace from the `CommentStyle::opener()` so that
334-
// the literal itself has control over the comment's leading spaces.
335-
let opener = comment_style.opener().trim_end();
336-
337-
let doc_comment = format!("{}{}", opener, literal);
336+
let doc_comment_formatter =
337+
DocCommentFormatter::new(literal.as_str().get(), comment_style);
338+
let doc_comment = format!("{}", doc_comment_formatter);
338339
return rewrite_doc_comment(
339340
&doc_comment,
340341
shape.comment(context.config),

src/attr/doc_comment.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::comment::CommentStyle;
2+
use std::fmt::{self, Display};
3+
4+
/// Formats a string as a doc comment using the given [`CommentStyle`].
5+
#[derive(new)]
6+
pub(super) struct DocCommentFormatter<'a> {
7+
literal: &'a str,
8+
style: CommentStyle<'a>,
9+
}
10+
11+
impl Display for DocCommentFormatter<'_> {
12+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
13+
let opener = self.style.opener().trim_end();
14+
let mut lines = self.literal.lines().peekable();
15+
while let Some(line) = lines.next() {
16+
let is_last_line = lines.peek().is_none();
17+
if is_last_line {
18+
write!(formatter, "{}{}", opener, line)?;
19+
} else {
20+
writeln!(formatter, "{}{}", opener, line)?;
21+
}
22+
}
23+
Ok(())
24+
}
25+
}
26+
27+
#[cfg(test)]
28+
mod tests {
29+
use super::*;
30+
31+
#[test]
32+
fn literal_controls_leading_spaces() {
33+
test_doc_comment_is_formatted_correctly(
34+
" Lorem ipsum",
35+
"/// Lorem ipsum",
36+
CommentStyle::TripleSlash,
37+
);
38+
}
39+
40+
#[test]
41+
fn single_line_doc_comment_is_formatted_correctly() {
42+
test_doc_comment_is_formatted_correctly(
43+
"Lorem ipsum",
44+
"///Lorem ipsum",
45+
CommentStyle::TripleSlash,
46+
);
47+
}
48+
49+
#[test]
50+
fn multi_line_doc_comment_is_formatted_correctly() {
51+
test_doc_comment_is_formatted_correctly(
52+
"Lorem ipsum\nDolor sit amet",
53+
"///Lorem ipsum\n///Dolor sit amet",
54+
CommentStyle::TripleSlash,
55+
);
56+
}
57+
58+
#[test]
59+
fn whitespace_within_lines_is_preserved() {
60+
test_doc_comment_is_formatted_correctly(
61+
" Lorem ipsum \n Dolor sit amet ",
62+
"/// Lorem ipsum \n/// Dolor sit amet ",
63+
CommentStyle::TripleSlash,
64+
);
65+
}
66+
67+
fn test_doc_comment_is_formatted_correctly(
68+
literal: &str,
69+
expected_comment: &str,
70+
style: CommentStyle<'_>,
71+
) {
72+
assert_eq!(
73+
expected_comment,
74+
format!("{}", DocCommentFormatter::new(&literal, style))
75+
);
76+
}
77+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rustfmt-unstable: true
2+
// rustfmt-normalize_doc_attributes: true
3+
4+
#[doc = "This comment
5+
is split
6+
on multiple lines"]
7+
fn foo() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rustfmt-unstable: true
2+
// rustfmt-normalize_doc_attributes: true
3+
4+
///This comment
5+
///is split
6+
///on multiple lines
7+
fn foo() {}

0 commit comments

Comments
 (0)