Repository: DioxusLabs/dioxus (2026-03-17T23:24:32Z)

Issue:
`dx fmt` adds extra whitespaces in a forloop
**Problem**

`dx fmt` adds extra whitespace in a forloop, like `for (index , name , value) in data`

<!-- A clear and concise description of what the bug is. -->

**Steps To Reproduce**

Steps to reproduce the behavior:

```rust
rsx! {
     for (index, name, value) in data {
          div { "{index}: {name}, {value}" }
     }
}
```

Run `dx fmt`:

```rust
rsx! {
     for (index , name , value) in data {
          div { "{index}: {name}, {value}" }
     }
}
```

**Expected behavior**

It should be `for (index, name, value) in data`, which is consistent with `cargo fmt`.

<!-- A clear and concise description of what you expected to happen. -->

**Screenshots**

<!-- If applicable, add screenshots to help explain your problem. -->

**Environment:**

- Dioxus version:  0.7.3 <!-- e.g. v0.17, main -->
- Rust version: 1.93    <!-- e.g. 1.123.0, nightly -->
- OS info:   Windows      <!-- e.g. macOS, NixOS 25.05 -->
- App platform:  desktop   <!-- e.g. web, desktop -->

**Questionnaire**

<!-- If you feel up to the challenge, please uncomment applicable lines below: -->

I'm interested in fixing this myself but don't know where to start. 
<!-- I would like to fix and I have a solution. -->
<!-- I don't have time to fix this right now, but maybe later. -->



Discussion:

Patch:
diff --git a/packages/autofmt/src/prettier_please.rs b/packages/autofmt/src/prettier_please.rs
index 2b24c9dbf7..88c6e4a58f 100644
--- a/packages/autofmt/src/prettier_please.rs
+++ b/packages/autofmt/src/prettier_please.rs
@@ -7,6 +7,10 @@ impl Writer<'_> {
     pub fn unparse_expr(&mut self, expr: &Expr) -> String {
         unparse_expr(expr, self.raw_src, &self.out.indent)
     }
+
+    pub fn unparse_pat(&self, pat: &syn::Pat) -> String {
+        unparse_pat(pat)
+    }
 }
 
 // we use weird unicode alternatives to avoid conflicts with the actual rsx! macro
@@ -163,6 +167,32 @@ pub fn unparse_inner(expr: &Expr) -> String {
     unwrapped(wrapped)
 }
 
+/// Unparse a pattern into a properly formatted string using prettyplease.
+///
+/// Wraps the pattern in `fn main() { for PAT in () {} }`, formats with prettyplease,
+/// then extracts just the pattern text between "for " and " in".
+pub fn unparse_pat(pat: &syn::Pat) -> String {
+    let file = File {
+        shebang: None,
+        attrs: vec![],
+        items: vec![Item::Verbatim(quote::quote! {
+            fn main() {
+                for #pat in () {}
+            }
+        })],
+    };
+    let formatted = prettyplease::unparse(&file);
+    let after_for = formatted
+        .find("for ")
+        .map(|i| i + 4)
+        .expect("prettyplease output missing 'for' keyword in pattern wrapper");
+    let before_in = formatted[after_for..]
+        .find(" in ")
+        .map(|i| i + after_for)
+        .expect("prettyplease output missing 'in' keyword in pattern wrapper");
+    formatted[after_for..before_in].trim().to_string()
+}
+
 // Split off the fn main and then cut the tabs off the front
 fn unwrapped(raw: String) -> String {
     let mut o = raw
diff --git a/packages/autofmt/src/writer.rs b/packages/autofmt/src/writer.rs
index 26e2aa5949..cac750b4b0 100644
--- a/packages/autofmt/src/writer.rs
+++ b/packages/autofmt/src/writer.rs
@@ -153,11 +153,7 @@ impl<'a> Writer<'a> {
     }
 
     fn write_for_loop(&mut self, forloop: &ForLoop) -> std::fmt::Result {
-        write!(
-            self.out,
-            "for {} in ",
-            forloop.pat.clone().into_token_stream(),
-        )?;
+        write!(self.out, "for {} in ", self.unparse_pat(&forloop.pat),)?;
 
         self.write_inline_expr(&forloop.expr)?;
 


Test patch:
diff --git a/packages/autofmt/tests/samples.rs b/packages/autofmt/tests/samples.rs
index b2ec30a75c..4bb494929b 100644
--- a/packages/autofmt/tests/samples.rs
+++ b/packages/autofmt/tests/samples.rs
@@ -64,4 +64,5 @@ twoway![
     expr_on_conditional,
     blank_lines,
     blank_lines_preserved,
+    forloop_tuple,
 ];
diff --git a/packages/autofmt/tests/samples/forloop_tuple.rsx b/packages/autofmt/tests/samples/forloop_tuple.rsx
new file mode 100644
index 0000000000..f9bb375211
--- /dev/null
+++ b/packages/autofmt/tests/samples/forloop_tuple.rsx
@@ -0,0 +1,17 @@
+rsx! {
+    for (index, name, value) in data.iter() {
+        div { "{index}: {name} = {value}" }
+    }
+
+    for item in items {
+        div { "{item}" }
+    }
+
+    for (a, b) in pairs.iter().enumerate() {
+        span { "{a}-{b}" }
+    }
+
+    for (_, value) in pairs {
+        span { "{value}" }
+    }
+}