Repository: rust-lang/rustfmt (rust)

Issue:
Const expressions break formatting
stable

`rustc --version`: `rustc 1.59.0 (9d1b2106e 2022-02-23)`
`rustfmt --version`: `rustfmt 1.4.38-stable (9d1b210 2022-02-23)`

nightly

`rustc --version`: `rustc 1.61.0-nightly (8d60bf427 2022-03-19)`
`rustfmt --version`: `rustfmt 1.4.38-nightly (8d60bf4 2022-03-19)`

Current stable and nightly `rustfmt`s format the following code incorrectly

```rust
struct Example<const N: usize = { 1048576 }> {
    //
}
```

to

```rust
struct Example<const N: usize = { 1048576 }> {
    1048576 }> {
//
}
```

Or, with `normalize_comments = true` set

```rust
struct Example<const N: usize = { 1048576 }> {
    // 1048576 }> {
}
```

In this case there is a new `// 1048576 }> {` prepended on every format operation

Pull request:
Search for struct body span after any generic arguments
Fixes #5273

Previously, rustfmt searched for the start of a struct body after the opening `{`. In most cases this works just fine, but const values can also be defined inside `{ }`, which lead to issues when rewriting the struct body (as highlighted by the linked issue).

Now, rustfmt will search for the `{` after the generic argument list to guarantee that the `{` it finds is the start of the struct body.

Patch:
diff --git a/src/items.rs b/src/items.rs
index 9b35d28f..92f423bb 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -1273,7 +1273,13 @@ pub(crate) fn format_struct_struct(
     result.push_str(&header_str);
 
     let header_hi = struct_parts.ident.span.hi();
-    let body_lo = context.snippet_provider.span_after(span, "{");
+    let body_lo = if let Some(generics) = struct_parts.generics {
+        // Adjust the span to start at the end of the generic arguments before searching for the '{'
+        let span = span.with_lo(generics.span.hi());
+        context.snippet_provider.span_after(span, "{")
+    } else {
+        context.snippet_provider.span_after(span, "{")
+    };
 
     let generics_str = match struct_parts.generics {
         Some(g) => format_generics(


Test patch:
diff --git a/tests/target/issue_5273.rs b/tests/target/issue_5273.rs
new file mode 100644
index 00000000..3bb9048a
--- /dev/null
+++ b/tests/target/issue_5273.rs
@@ -0,0 +1,3 @@
+struct Example<const N: usize = { 1048576 }> {
+    //
+}