From f2fb3c9659e072d7df6315906f1adbd06c3bc9e3 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 6 Oct 2021 13:09:24 -0400 Subject: [PATCH] Update connector search in ControlFlow::rewrite_pat_expr for for loops Resolves 5009 For loops represented by a ControlFlow object use " in" as their connector. 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: rustfmt 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. rustfmt 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". --- src/expr.rs | 2 +- tests/target/issue-5009/1_minimum_example.rs | 4 +++ .../2_many_in_connectors_in_pattern.rs | 3 ++ ...sted_for_loop_with_connector_in_pattern.rs | 5 +++ .../4_nested_for_loop_with_if_elseif_else.rs | 13 ++++++++ ...r_loop_with_connector_in_if_elseif_else.rs | 15 +++++++++ ...sted_for_loop_with_connector_in_pattern.rs | 32 +++++++++++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5009/1_minimum_example.rs create mode 100644 tests/target/issue-5009/2_many_in_connectors_in_pattern.rs create mode 100644 tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs create mode 100644 tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs create mode 100644 tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs create mode 100644 tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs diff --git a/src/expr.rs b/src/expr.rs index 3a54426b0dd..f40f80e4253 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -822,7 +822,7 @@ impl<'a> ControlFlow<'a> { let pat_string = pat.rewrite(context, pat_shape)?; let comments_lo = context .snippet_provider - .span_after(self.span, self.connector.trim()); + .span_after(self.span.with_lo(pat.span.hi()), self.connector.trim()); let comments_span = mk_sp(comments_lo, expr.span.lo()); return rewrite_assign_rhs_with_comments( context, diff --git a/tests/target/issue-5009/1_minimum_example.rs b/tests/target/issue-5009/1_minimum_example.rs new file mode 100644 index 00000000000..55836f4bf52 --- /dev/null +++ b/tests/target/issue-5009/1_minimum_example.rs @@ -0,0 +1,4 @@ +fn main() { + // the "in" inside the pattern produced invalid syntax + for variable_in_here /* ... */ in 0..1 {} +} diff --git a/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs b/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs new file mode 100644 index 00000000000..d83590c6852 --- /dev/null +++ b/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs @@ -0,0 +1,3 @@ +fn main() { + for in_in_in_in_in_in_in_in /* ... */ in 0..1 {} +} diff --git a/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs b/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 00000000000..9c800723939 --- /dev/null +++ b/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,5 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 {} + } +} diff --git a/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs b/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs new file mode 100644 index 00000000000..a716d0d3082 --- /dev/null +++ b/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs @@ -0,0 +1,13 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if false { + + } else if false { + + } else { + + } + } + } +} diff --git a/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs b/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs new file mode 100644 index 00000000000..41ea46d4cb9 --- /dev/null +++ b/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs @@ -0,0 +1,15 @@ +fn main() { + let in_ = false; + + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if in_ { + + } else if in_ { + + } else { + + } + } + } +} diff --git a/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs b/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 00000000000..789e54f7e5f --- /dev/null +++ b/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,32 @@ +fn main() { + for variable_in_a /* ... */ in 0..1 { + for variable_in_b /* ... */ in 0..1 { + for variable_in_c /* ... */ in 0..1 { + for variable_in_d /* ... */ in 0..1 { + for variable_in_e /* ... */ in 0..1 { + for variable_in_f /* ... */ in 0..1 { + for variable_in_g /* ... */ in 0..1 { + for variable_in_h /* ... */ in 0..1 { + for variable_in_i /* ... */ in 0..1 { + for variable_in_j /* ... */ in 0..1 { + for variable_in_k /* ... */ in 0..1 { + for variable_in_l /* ... */ in 0..1 { + for variable_in_m /* ... */ in 0..1 { + for variable_in_n /* ... */ in 0..1 { + for variable_in_o /* ... */ in 0..1 { + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +}