Skip to content

Commit 2acf6ee

Browse files
committed
Auto merge of #80295 - GuillaumeGomez:beautify-rework, r=petrochenkov
Rework beautify_doc_string so that it returns a Symbol instead of a String This commit comes from #80261, the goal here is to inspect the impact on performance of this change on its own. The idea of rewriting `beautify_doc_string` is to not go through `String` if we don't need to update the doc comment to be able to keep the original `Symbol` and also to have better performance. r? `@jyn514`
2 parents c34c015 + 64afded commit 2acf6ee

File tree

4 files changed

+39
-37
lines changed

4 files changed

+39
-37
lines changed

Diff for: compiler/rustc_ast/src/util/comments.rs

+30-28
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ pub struct Comment {
2525

2626
/// Makes a doc string more presentable to users.
2727
/// Used by rustdoc and perhaps other tools, but not by rustc.
28-
pub fn beautify_doc_string(data: Symbol) -> String {
29-
/// remove whitespace-only lines from the start/end of lines
30-
fn vertical_trim(lines: Vec<String>) -> Vec<String> {
28+
pub fn beautify_doc_string(data: Symbol) -> Symbol {
29+
fn get_vertical_trim(lines: &[&str]) -> Option<(usize, usize)> {
3130
let mut i = 0;
3231
let mut j = lines.len();
3332
// first line of all-stars should be omitted
@@ -47,55 +46,58 @@ pub fn beautify_doc_string(data: Symbol) -> String {
4746
j -= 1;
4847
}
4948

50-
lines[i..j].to_vec()
49+
if i != 0 || j != lines.len() { Some((i, j)) } else { None }
5150
}
5251

53-
/// remove a "[ \t]*\*" block from each line, if possible
54-
fn horizontal_trim(lines: Vec<String>) -> Vec<String> {
52+
fn get_horizontal_trim(lines: &[&str]) -> Option<usize> {
5553
let mut i = usize::MAX;
56-
let mut can_trim = true;
5754
let mut first = true;
5855

59-
for line in &lines {
56+
for line in lines {
6057
for (j, c) in line.chars().enumerate() {
6158
if j > i || !"* \t".contains(c) {
62-
can_trim = false;
63-
break;
59+
return None;
6460
}
6561
if c == '*' {
6662
if first {
6763
i = j;
6864
first = false;
6965
} else if i != j {
70-
can_trim = false;
66+
return None;
7167
}
7268
break;
7369
}
7470
}
7571
if i >= line.len() {
76-
can_trim = false;
77-
}
78-
if !can_trim {
79-
break;
72+
return None;
8073
}
8174
}
75+
Some(i)
76+
}
8277

83-
if can_trim {
84-
lines.iter().map(|line| (&line[i + 1..line.len()]).to_string()).collect()
78+
let data_s = data.as_str();
79+
if data_s.contains('\n') {
80+
let mut lines = data_s.lines().collect::<Vec<&str>>();
81+
let mut changes = false;
82+
let lines = if let Some((i, j)) = get_vertical_trim(&lines) {
83+
changes = true;
84+
// remove whitespace-only lines from the start/end of lines
85+
&mut lines[i..j]
8586
} else {
86-
lines
87+
&mut lines
88+
};
89+
if let Some(horizontal) = get_horizontal_trim(&lines) {
90+
changes = true;
91+
// remove a "[ \t]*\*" block from each line, if possible
92+
for line in lines.iter_mut() {
93+
*line = &line[horizontal + 1..];
94+
}
95+
}
96+
if changes {
97+
return Symbol::intern(&lines.join("\n"));
8798
}
8899
}
89-
90-
let data = data.as_str();
91-
if data.contains('\n') {
92-
let lines = data.lines().map(|s| s.to_string()).collect::<Vec<String>>();
93-
let lines = vertical_trim(lines);
94-
let lines = horizontal_trim(lines);
95-
lines.join("\n")
96-
} else {
97-
data.to_string()
98-
}
100+
data
99101
}
100102

101103
/// Returns `None` if the first `col` chars of `s` contain a non-whitespace char.

Diff for: compiler/rustc_ast/src/util/comments/tests.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ fn test_block_doc_comment_1() {
66
with_default_session_globals(|| {
77
let comment = "\n * Test \n ** Test\n * Test\n";
88
let stripped = beautify_doc_string(Symbol::intern(comment));
9-
assert_eq!(stripped, " Test \n* Test\n Test");
9+
assert_eq!(stripped.as_str(), " Test \n* Test\n Test");
1010
})
1111
}
1212

@@ -15,7 +15,7 @@ fn test_block_doc_comment_2() {
1515
with_default_session_globals(|| {
1616
let comment = "\n * Test\n * Test\n";
1717
let stripped = beautify_doc_string(Symbol::intern(comment));
18-
assert_eq!(stripped, " Test\n Test");
18+
assert_eq!(stripped.as_str(), " Test\n Test");
1919
})
2020
}
2121

@@ -24,20 +24,20 @@ fn test_block_doc_comment_3() {
2424
with_default_session_globals(|| {
2525
let comment = "\n let a: *i32;\n *a = 5;\n";
2626
let stripped = beautify_doc_string(Symbol::intern(comment));
27-
assert_eq!(stripped, " let a: *i32;\n *a = 5;");
27+
assert_eq!(stripped.as_str(), " let a: *i32;\n *a = 5;");
2828
})
2929
}
3030

3131
#[test]
3232
fn test_line_doc_comment() {
3333
with_default_session_globals(|| {
3434
let stripped = beautify_doc_string(Symbol::intern(" test"));
35-
assert_eq!(stripped, " test");
35+
assert_eq!(stripped.as_str(), " test");
3636
let stripped = beautify_doc_string(Symbol::intern("! test"));
37-
assert_eq!(stripped, "! test");
37+
assert_eq!(stripped.as_str(), "! test");
3838
let stripped = beautify_doc_string(Symbol::intern("test"));
39-
assert_eq!(stripped, "test");
39+
assert_eq!(stripped.as_str(), "test");
4040
let stripped = beautify_doc_string(Symbol::intern("!test"));
41-
assert_eq!(stripped, "!test");
41+
assert_eq!(stripped.as_str(), "!test");
4242
})
4343
}

Diff for: compiler/rustc_save_analysis/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ impl<'tcx> SaveContext<'tcx> {
825825
for attr in attrs {
826826
if let Some(val) = attr.doc_str() {
827827
// FIXME: Should save-analysis beautify doc strings itself or leave it to users?
828-
result.push_str(&beautify_doc_string(val));
828+
result.push_str(&beautify_doc_string(val).as_str());
829829
result.push('\n');
830830
} else if self.tcx.sess.check_name(attr, sym::doc) {
831831
if let Some(meta_list) = attr.meta_item_list() {

Diff for: src/librustdoc/clean/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ impl Attributes {
621621
let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
622622
if let Some(value) = attr.doc_str() {
623623
trace!("got doc_str={:?}", value);
624-
let value = beautify_doc_string(value);
624+
let value = beautify_doc_string(value).to_string();
625625
let kind = if attr.is_doc_comment() {
626626
DocFragmentKind::SugaredDoc
627627
} else {

0 commit comments

Comments
 (0)