Skip to content

Commit b58eb2a

Browse files
committed
Update comment search in ControlFlow::rewrite_pat_expr for for loops
Resolves 5009 For loops represented by a ControlFlow object use " in" as their connector. In order to find the span where comments might be located, rustfmt searches for the first uncommented occurrence of the word "in" within the current span and adjusts it's starting point to look for comments right after that. visually this looks like this: ruftfmt starts looking for comments here | V for x in /* ... */ 0..1 {} This works well in most cases, however when the pattern also contains the word "in", this leads to issues. ruftfmt starts looking for comments here | V for in_here in /* ... */ 0..1 {} ------- pattern In order to correctly identify the connector, the new approach first updates the span to start after the pattern and then searches for the first uncommented occurrence of "in".
1 parent 365a2f8 commit b58eb2a

9 files changed

+96
-3
lines changed

src/expr.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,9 +820,20 @@ impl<'a> ControlFlow<'a> {
820820
.offset_left(matcher.len())?
821821
.sub_width(self.connector.len())?;
822822
let pat_string = pat.rewrite(context, pat_shape)?;
823-
let comments_lo = context
824-
.snippet_provider
825-
.span_after(self.span, self.connector.trim());
823+
// When handling for loops we want to avoid incorrectly finding "in"
824+
// inside the pattern so we first offset the span to start after the pattern
825+
// see https://github.com/rust-lang/rustfmt/issues/5009
826+
let comments_lo = if self.keyword == "for" {
827+
let lo_after_pat = context.snippet_provider.span_after(self.span, &pat_string);
828+
829+
context
830+
.snippet_provider
831+
.span_after(self.span.with_lo(lo_after_pat), self.connector.trim())
832+
} else {
833+
context
834+
.snippet_provider
835+
.span_after(self.span, self.connector.trim())
836+
};
826837
let comments_span = mk_sp(comments_lo, expr.span.lo());
827838
return rewrite_assign_rhs_with_comments(
828839
context,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
// the "in" inside the pattern produced invalid syntax
3+
for variable_in_here /* ... */ in 0..1 {}
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
for in_in_in_in_in_in_in_in /* ... */ in 0..1 {}
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
for variable_in_x /* ... */ in 0..1 {
3+
for variable_in_y /* ... */ in 0..1 {}
4+
}
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {
2+
for variable_in_x /* ... */ in 0..1 {
3+
for variable_in_y /* ... */ in 0..1 {
4+
if false {
5+
6+
} else if false {
7+
8+
} else {
9+
10+
}
11+
}
12+
}
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
fn main() {
2+
let in_ = false;
3+
4+
for variable_in_x /* ... */ in 0..1 {
5+
for variable_in_y /* ... */ in 0..1 {
6+
if in_ {
7+
8+
} else if in_ {
9+
10+
} else {
11+
12+
}
13+
}
14+
}
15+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
fn main() {
2+
for variable_in_a /* ... */ in 0..1 {
3+
for variable_in_b /* ... */ in 0..1 {
4+
for variable_in_c /* ... */ in 0..1 {
5+
for variable_in_d /* ... */ in 0..1 {
6+
for variable_in_e /* ... */ in 0..1 {
7+
for variable_in_f /* ... */ in 0..1 {
8+
for variable_in_g /* ... */ in 0..1 {
9+
for variable_in_h /* ... */ in 0..1 {
10+
for variable_in_i /* ... */ in 0..1 {
11+
for variable_in_j /* ... */ in 0..1 {
12+
for variable_in_k /* ... */ in 0..1 {
13+
for variable_in_l /* ... */ in 0..1 {
14+
for variable_in_m /* ... */ in 0..1 {
15+
for variable_in_n /* ... */ in 0..1 {
16+
for variable_in_o /* ... */ in 0..1 {
17+
}
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}
24+
}
25+
}
26+
}
27+
}
28+
}
29+
}
30+
}
31+
}
32+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// should not reformat
2+
fn main() {
3+
for x /* ... */ in 0..1 {}
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// should not reformat
2+
fn main() {
3+
for x /* ... */ in 0..1 {
4+
for y /* ... */ in 0..1 {}
5+
}
6+
}

0 commit comments

Comments
 (0)