Skip to content

Commit 69cf483

Browse files
authored
fix handling of nested comments in patterns and ControlFlows (#3869)
2 parents 233497a + fd6e960 commit 69cf483

File tree

5 files changed

+199
-16
lines changed

5 files changed

+199
-16
lines changed

src/comment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<'a> CommentStyle<'a> {
112112
}
113113
}
114114

115-
fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle<'_> {
115+
pub(crate) fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle<'_> {
116116
if !normalize_comments {
117117
if orig.starts_with("/**") && !orig.starts_with("/**/") {
118118
CommentStyle::DoubleBullet

src/expr.rs

+35-6
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use syntax::{ast, ptr};
99
use crate::chains::rewrite_chain;
1010
use crate::closures;
1111
use crate::comment::{
12-
combine_strs_with_missing_comments, contains_comment, recover_comment_removed, rewrite_comment,
13-
rewrite_missing_comment, CharClasses, FindUncommented,
12+
combine_strs_with_missing_comments, comment_style, contains_comment, recover_comment_removed,
13+
rewrite_comment, rewrite_missing_comment, CharClasses, FindUncommented,
1414
};
1515
use crate::config::lists::*;
1616
use crate::config::{Config, ControlBraceStyle, IndentStyle, Version};
@@ -808,7 +808,7 @@ impl<'a> ControlFlow<'a> {
808808
debug!("rewrite_pat_expr {:?} {:?} {:?}", shape, self.pat, expr);
809809

810810
let cond_shape = shape.offset_left(offset)?;
811-
if !self.pat.is_none() {
811+
if let Some(pat) = self.pat {
812812
let matcher = if self.matcher.is_empty() {
813813
self.matcher.to_owned()
814814
} else {
@@ -817,12 +817,41 @@ impl<'a> ControlFlow<'a> {
817817
let pat_shape = cond_shape
818818
.offset_left(matcher.len())?
819819
.sub_width(self.connector.len())?;
820-
let pat_string = if let Some(pat) = self.pat {
821-
pat.rewrite(context, pat_shape)?
820+
let pat_string = pat.rewrite(context, pat_shape)?;
821+
let comments_lo = context
822+
.snippet_provider
823+
.span_after(self.span, self.connector.trim());
824+
let missing_comments = if let Some(comment) =
825+
rewrite_missing_comment(mk_sp(comments_lo, expr.span.lo()), cond_shape, context)
826+
{
827+
if !self.connector.is_empty() && !comment.is_empty() {
828+
if comment_style(&comment, false).is_line_comment() || comment.contains("\n") {
829+
let newline = &pat_shape
830+
.indent
831+
.block_indent(context.config)
832+
.to_string_with_newline(context.config);
833+
// An extra space is added when the lhs and rhs are joined
834+
// so we need to remove one space from the end to ensure
835+
// the comment and rhs are aligned.
836+
let mut suffix = newline.as_ref().to_string();
837+
if !suffix.is_empty() {
838+
suffix.truncate(suffix.len() - 1);
839+
}
840+
format!("{}{}{}", newline, comment, suffix)
841+
} else {
842+
format!(" {}", comment)
843+
}
844+
} else {
845+
comment
846+
}
822847
} else {
823848
"".to_owned()
824849
};
825-
let result = format!("{}{}{}", matcher, pat_string, self.connector);
850+
851+
let result = format!(
852+
"{}{}{}{}",
853+
matcher, pat_string, self.connector, missing_comments
854+
);
826855
return rewrite_assign_rhs(context, result, expr, cond_shape);
827856
}
828857

src/patterns.rs

+64-9
Original file line numberDiff line numberDiff line change
@@ -89,26 +89,81 @@ impl Rewrite for Pat {
8989
PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape),
9090
PatKind::Ident(binding_mode, ident, ref sub_pat) => {
9191
let (prefix, mutability) = match binding_mode {
92-
BindingMode::ByRef(mutability) => ("ref ", mutability),
92+
BindingMode::ByRef(mutability) => ("ref", mutability),
9393
BindingMode::ByValue(mutability) => ("", mutability),
9494
};
95-
let mut_infix = format_mutability(mutability);
95+
let mut_infix = format_mutability(mutability).trim();
9696
let id_str = rewrite_ident(context, ident);
9797
let sub_pat = match *sub_pat {
9898
Some(ref p) => {
99-
// 3 - ` @ `.
99+
// 2 - `@ `.
100100
let width = shape
101101
.width
102-
.checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 3)?;
103-
format!(
104-
" @ {}",
105-
p.rewrite(context, Shape::legacy(width, shape.indent))?
106-
)
102+
.checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 2)?;
103+
let lo = context.snippet_provider.span_after(self.span, "@");
104+
combine_strs_with_missing_comments(
105+
context,
106+
"@",
107+
&p.rewrite(context, Shape::legacy(width, shape.indent))?,
108+
mk_sp(lo, p.span.lo()),
109+
shape,
110+
true,
111+
)?
107112
}
108113
None => "".to_owned(),
109114
};
110115

111-
Some(format!("{}{}{}{}", prefix, mut_infix, id_str, sub_pat))
116+
// combine prefix and mut
117+
let (first_lo, first) = if !prefix.is_empty() && !mut_infix.is_empty() {
118+
let hi = context.snippet_provider.span_before(self.span, "mut");
119+
let lo = context.snippet_provider.span_after(self.span, "ref");
120+
(
121+
context.snippet_provider.span_after(self.span, "mut"),
122+
combine_strs_with_missing_comments(
123+
context,
124+
prefix,
125+
mut_infix,
126+
mk_sp(lo, hi),
127+
shape,
128+
true,
129+
)?,
130+
)
131+
} else if !prefix.is_empty() {
132+
(
133+
context.snippet_provider.span_after(self.span, "ref"),
134+
prefix.to_owned(),
135+
)
136+
} else if !mut_infix.is_empty() {
137+
(
138+
context.snippet_provider.span_after(self.span, "mut"),
139+
mut_infix.to_owned(),
140+
)
141+
} else {
142+
(self.span.lo(), "".to_owned())
143+
};
144+
145+
let next = if !sub_pat.is_empty() {
146+
let hi = context.snippet_provider.span_before(self.span, "@");
147+
combine_strs_with_missing_comments(
148+
context,
149+
id_str,
150+
&sub_pat,
151+
mk_sp(ident.span.hi(), hi),
152+
shape,
153+
true,
154+
)?
155+
} else {
156+
id_str.to_owned()
157+
};
158+
159+
combine_strs_with_missing_comments(
160+
context,
161+
&first,
162+
&next,
163+
mk_sp(first_lo, ident.span.lo()),
164+
shape,
165+
true,
166+
)
112167
}
113168
PatKind::Wild => {
114169
if 1 <= shape.width {

tests/source/issue_3853.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
fn by_ref_with_block_before_ident() {
2+
if let Some(ref /*def*/ state)= foo{
3+
println!(
4+
"asdfasdfasdf"); }
5+
}
6+
7+
fn mut_block_before_ident() {
8+
if let Some(mut /*def*/ state ) =foo{
9+
println!(
10+
"123" ); }
11+
}
12+
13+
fn ref_and_mut_blocks_before_ident() {
14+
if let Some(ref /*abc*/
15+
mut /*def*/ state ) = foo {
16+
println!(
17+
"deefefefefefwea" ); }
18+
}
19+
20+
fn sub_pattern() {
21+
let foo @ /*foo*/
22+
bar(f) = 42;
23+
}
24+
25+
fn no_prefix_block_before_ident() {
26+
if let Some(
27+
/*def*/ state ) = foo {
28+
println!(
29+
"129387123123" ); }
30+
}
31+
32+
fn issue_3853() {
33+
if let Some(ref /*mut*/ state) = foo {
34+
}
35+
}
36+
37+
fn double_slash_comment_between_lhs_and_rhs() {
38+
if let Some(e) =
39+
// self.foo.bar(e, tx)
40+
packet.transaction.state.committed
41+
{
42+
// body
43+
println!(
44+
"a2304712836123");
45+
}
46+
}
47+
48+
fn block_comment_between_lhs_and_rhs() {
49+
if let Some(ref /*def*/ mut /*abc*/ state)= /*abc*/foo{
50+
println!(
51+
"asdfasdfasdf"); }
52+
}

tests/target/issue_3853.rs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
fn by_ref_with_block_before_ident() {
2+
if let Some(ref /*def*/ state) = foo {
3+
println!("asdfasdfasdf");
4+
}
5+
}
6+
7+
fn mut_block_before_ident() {
8+
if let Some(mut /*def*/ state) = foo {
9+
println!("123");
10+
}
11+
}
12+
13+
fn ref_and_mut_blocks_before_ident() {
14+
if let Some(ref /*abc*/ mut /*def*/ state) = foo {
15+
println!("deefefefefefwea");
16+
}
17+
}
18+
19+
fn sub_pattern() {
20+
let foo @ /*foo*/ bar(f) = 42;
21+
}
22+
23+
fn no_prefix_block_before_ident() {
24+
if let Some(/*def*/ state) = foo {
25+
println!("129387123123");
26+
}
27+
}
28+
29+
fn issue_3853() {
30+
if let Some(ref /*mut*/ state) = foo {}
31+
}
32+
33+
fn double_slash_comment_between_lhs_and_rhs() {
34+
if let Some(e) =
35+
// self.foo.bar(e, tx)
36+
packet.transaction.state.committed
37+
{
38+
// body
39+
println!("a2304712836123");
40+
}
41+
}
42+
43+
fn block_comment_between_lhs_and_rhs() {
44+
if let Some(ref /*def*/ mut /*abc*/ state) = /*abc*/ foo {
45+
println!("asdfasdfasdf");
46+
}
47+
}

0 commit comments

Comments
 (0)