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

Commit 503cdde

Browse files
authored
Merge pull request rust-lang#3225 from scampi/issue-3224
rewrite_comment: fix block fallback when failing to rewrite an itemized block
2 parents a1bbf58 + 3b18238 commit 503cdde

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

src/comment.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ impl CodeBlockAttribute {
421421
/// An item starts with either a star `*` or a dash `-`. Different level of indentation are
422422
/// handled by shrinking the shape accordingly.
423423
struct ItemizedBlock {
424+
/// the lines that are identified as part of an itemized block
425+
lines: Vec<String>,
424426
/// the number of whitespaces up to the item sigil
425427
indent: usize,
426428
/// the string that marks the start of an item
@@ -442,6 +444,7 @@ impl ItemizedBlock {
442444
let space_to_sigil = line.chars().take_while(|c| c.is_whitespace()).count();
443445
let indent = space_to_sigil + 2;
444446
ItemizedBlock {
447+
lines: vec![line[indent..].to_string()],
445448
indent,
446449
opener: line[..indent].to_string(),
447450
line_start: " ".repeat(indent),
@@ -461,10 +464,29 @@ impl ItemizedBlock {
461464
}
462465
}
463466

464-
/// Returns true if the line is part of the current itemized block
465-
fn in_block(&self, line: &str) -> bool {
466-
!ItemizedBlock::is_itemized_line(line)
467+
/// Returns true if the line is part of the current itemized block.
468+
/// If it is, then it is added to the internal lines vec.
469+
fn add_line(&mut self, line: &str) -> bool {
470+
if !ItemizedBlock::is_itemized_line(line)
467471
&& self.indent <= line.chars().take_while(|c| c.is_whitespace()).count()
472+
{
473+
self.lines.push(line.to_string());
474+
return true;
475+
}
476+
false
477+
}
478+
479+
/// Returns the block as a string, with each line trimmed at the start.
480+
fn trimmed_block_as_string(&self) -> String {
481+
self.lines
482+
.iter()
483+
.map(|line| format!("{} ", line.trim_start()))
484+
.collect::<String>()
485+
}
486+
487+
/// Returns the block as a string under its original form
488+
fn original_block_as_string(&self) -> String {
489+
self.lines.join("\n")
468490
}
469491
}
470492

@@ -473,7 +495,6 @@ struct CommentRewrite<'a> {
473495
code_block_buffer: String,
474496
is_prev_line_multi_line: bool,
475497
code_block_attr: Option<CodeBlockAttribute>,
476-
item_block_buffer: String,
477498
item_block: Option<ItemizedBlock>,
478499
comment_line_separator: String,
479500
indent_str: String,
@@ -511,7 +532,6 @@ impl<'a> CommentRewrite<'a> {
511532
code_block_buffer: String::with_capacity(128),
512533
is_prev_line_multi_line: false,
513534
code_block_attr: None,
514-
item_block_buffer: String::with_capacity(128),
515535
item_block: None,
516536
comment_line_separator: format!("{}{}", indent_str, line_start),
517537
max_chars,
@@ -561,17 +581,14 @@ impl<'a> CommentRewrite<'a> {
561581
));
562582
}
563583

564-
if !self.item_block_buffer.is_empty() {
584+
if let Some(ref ib) = self.item_block {
565585
// the last few lines are part of an itemized block
566586
self.fmt.shape = Shape::legacy(self.max_chars, self.fmt_indent);
567-
let mut ib = None;
568-
::std::mem::swap(&mut ib, &mut self.item_block);
569-
let ib = ib.unwrap();
570587
let item_fmt = ib.create_string_format(&self.fmt);
571588
self.result.push_str(&self.comment_line_separator);
572589
self.result.push_str(&ib.opener);
573590
match rewrite_string(
574-
&self.item_block_buffer.replace("\n", " "),
591+
&ib.trimmed_block_as_string(),
575592
&item_fmt,
576593
self.max_chars.saturating_sub(ib.indent),
577594
) {
@@ -580,7 +597,7 @@ impl<'a> CommentRewrite<'a> {
580597
&format!("{}{}", &self.comment_line_separator, ib.line_start),
581598
)),
582599
None => self.result.push_str(&Self::join_block(
583-
&self.item_block_buffer,
600+
&ib.original_block_as_string(),
584601
&self.comment_line_separator,
585602
)),
586603
};
@@ -604,10 +621,8 @@ impl<'a> CommentRewrite<'a> {
604621
) -> bool {
605622
let is_last = i == count_newlines(orig);
606623

607-
if let Some(ref ib) = self.item_block {
608-
if ib.in_block(&line) {
609-
self.item_block_buffer.push_str(line.trim_start());
610-
self.item_block_buffer.push('\n');
624+
if let Some(ref mut ib) = self.item_block {
625+
if ib.add_line(&line) {
611626
return false;
612627
}
613628
self.is_prev_line_multi_line = false;
@@ -616,7 +631,7 @@ impl<'a> CommentRewrite<'a> {
616631
self.result.push_str(&self.comment_line_separator);
617632
self.result.push_str(&ib.opener);
618633
match rewrite_string(
619-
&self.item_block_buffer.replace("\n", " "),
634+
&ib.trimmed_block_as_string(),
620635
&item_fmt,
621636
self.max_chars.saturating_sub(ib.indent),
622637
) {
@@ -625,11 +640,10 @@ impl<'a> CommentRewrite<'a> {
625640
&format!("{}{}", &self.comment_line_separator, ib.line_start),
626641
)),
627642
None => self.result.push_str(&Self::join_block(
628-
&self.item_block_buffer,
643+
&ib.original_block_as_string(),
629644
&self.comment_line_separator,
630645
)),
631646
};
632-
self.item_block_buffer.clear();
633647
} else if self.code_block_attr.is_some() {
634648
if line.starts_with("```") {
635649
let code_block = match self.code_block_attr.as_ref().unwrap() {
@@ -669,8 +683,6 @@ impl<'a> CommentRewrite<'a> {
669683
self.code_block_attr = Some(CodeBlockAttribute::new(&line[3..]))
670684
} else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) {
671685
let ib = ItemizedBlock::new(&line);
672-
self.item_block_buffer.push_str(&line[ib.indent..]);
673-
self.item_block_buffer.push('\n');
674686
self.item_block = Some(ib);
675687
return false;
676688
}

tests/target/issue-3224.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// rustfmt-wrap_comments: true
2+
3+
//! Test:
4+
//! * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
5+
//! * [`examples/simple`] – Demonstrates use of the [`init`] API with plain
6+
//! structs.
7+
//! * [`examples/simple_flatbuffer`] – Demonstrates use of the [`init`] API with
8+
//! FlatBuffers.
9+
//! * [`examples/gravity`] – Demonstrates use of the [`RLBot::set_game_state`]
10+
//! API
11+
fn foo() {}

0 commit comments

Comments
 (0)