Skip to content

Commit dc2f142

Browse files
authored
Merge pull request #2521 from topecongiro/issue-2520
Fix bugs when rewriting doc comments with code block
2 parents 58fb47a + 4844698 commit dc2f142

File tree

6 files changed

+60
-23
lines changed

6 files changed

+60
-23
lines changed

src/attr.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ use rewrite::{Rewrite, RewriteContext};
2121
use shape::Shape;
2222
use utils::{count_newlines, mk_sp};
2323

24-
use std::cmp;
25-
2624
/// Returns attributes on the given statement.
2725
pub fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
2826
match stmt.node {
@@ -98,27 +96,26 @@ fn take_while_with_pred<'a, P>(
9896
where
9997
P: Fn(&ast::Attribute) -> bool,
10098
{
101-
let mut last_index = 0;
102-
let mut iter = attrs.iter().enumerate().peekable();
103-
while let Some((i, attr)) = iter.next() {
104-
if !pred(attr) {
99+
let mut len = 0;
100+
let mut iter = attrs.iter().peekable();
101+
102+
while let Some(attr) = iter.next() {
103+
if pred(attr) {
104+
len += 1;
105+
} else {
105106
break;
106107
}
107-
if let Some(&(_, next_attr)) = iter.peek() {
108+
if let Some(next_attr) = iter.peek() {
108109
// Extract comments between two attributes.
109110
let span_between_attr = mk_sp(attr.span.hi(), next_attr.span.lo());
110111
let snippet = context.snippet(span_between_attr);
111112
if count_newlines(snippet) >= 2 || snippet.contains('/') {
112113
break;
113114
}
114115
}
115-
last_index = i;
116-
}
117-
if last_index == 0 {
118-
&[]
119-
} else {
120-
&attrs[..last_index + 1]
121116
}
117+
118+
&attrs[..len]
122119
}
123120

124121
/// Rewrite the same kind of attributes at the same time. This includes doc
@@ -141,7 +138,7 @@ fn rewrite_first_group_attrs(
141138
.join("\n");
142139
return Some((
143140
sugared_docs.len(),
144-
rewrite_doc_comment(&snippet, shape, context.config)?,
141+
rewrite_doc_comment(&snippet, shape.comment(context.config), context.config)?,
145142
));
146143
}
147144
// Rewrite `#[derive(..)]`s.
@@ -250,13 +247,7 @@ impl Rewrite for ast::Attribute {
250247
};
251248
let snippet = context.snippet(self.span);
252249
if self.is_sugared_doc {
253-
let doc_shape = Shape {
254-
width: cmp::min(shape.width, context.config.comment_width())
255-
.checked_sub(shape.indent.width())
256-
.unwrap_or(0),
257-
..shape
258-
};
259-
rewrite_doc_comment(snippet, doc_shape, context.config)
250+
rewrite_doc_comment(snippet, shape.comment(context.config), context.config)
260251
} else {
261252
if contains_comment(snippet) {
262253
return Some(snippet.to_owned());

src/comment.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,15 @@ fn rewrite_comment_inner(
391391
} else {
392392
code_block_buffer.push_str(line);
393393
code_block_buffer.push('\n');
394+
395+
if is_last {
396+
// There is an code block that is not properly enclosed by backticks.
397+
// We will leave them untouched.
398+
result.push_str(&comment_line_separator);
399+
result.push_str(&join_code_block_with_comment_line_separator(
400+
&code_block_buffer,
401+
));
402+
}
394403
}
395404

396405
continue;

src/shape.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use std::borrow::Cow;
12+
use std::cmp::min;
1213
use std::ops::{Add, Sub};
1314

1415
use Config;
@@ -276,6 +277,17 @@ impl Shape {
276277
.checked_sub(self.used_width() + self.width)
277278
.unwrap_or(0)
278279
}
280+
281+
pub fn comment(&self, config: &Config) -> Shape {
282+
let width = min(
283+
self.width,
284+
config
285+
.comment_width()
286+
.checked_sub(self.indent.width())
287+
.unwrap_or(0),
288+
);
289+
Shape { width, ..*self }
290+
}
279291
}
280292

281293
#[cfg(test)]

tests/source/issue-2520.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-normalize_comments: true
2+
3+
//! ```rust
4+
//! println!( "hello, world" );
5+
//! ```
6+
7+
#![deny( missing_docs )]
8+
9+
//! ```rust
10+
//! println!("hello, world");
11+
12+
#![deny( missing_docs )]

tests/target/enum.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,9 @@ pub enum Bencoding<'i> {
145145
Str(&'i [u8]),
146146
Int(i64),
147147
List(Vec<Bencoding<'i>>),
148-
/// A bencoded dict value. The first element the slice of bytes in the source that the dict is
149-
/// composed of. The second is the dict, decoded into an ordered map.
148+
/// A bencoded dict value. The first element the slice of bytes in the
149+
/// source that the dict is composed of. The second is the dict,
150+
/// decoded into an ordered map.
150151
// TODO make Dict "structlike" AKA name the two values.
151152
Dict(&'i [u8], BTreeMap<&'i [u8], Bencoding<'i>>),
152153
}

tests/target/issue-2520.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-normalize_comments: true
2+
3+
//! ```rust
4+
//! println!("hello, world");
5+
//! ```
6+
7+
#![deny(missing_docs)]
8+
9+
//! ```rust
10+
//! println!("hello, world");
11+
12+
#![deny(missing_docs)]

0 commit comments

Comments
 (0)