Skip to content

dx fmt corrupts RSX onclick closures with cfg-gated let bindings #5523

@enaut

Description

@enaut

Problem

Disclaimer: the problem occured to me, AI was used to minify the breaking code and summarize the issue. I hope that is OK

dx fmt --file rewrites a valid Dioxus RSX event handler into invalid Rust.

The breakage appears when an onclick: { ... } handler contains:

  • an outer #[cfg(...)] let
  • a move |_| { ... } closure
  • an inner #[cfg(...)] let
  • an if let Err(err) block with error.set(format!(...))

After formatting, dx fmt inserts stray fragments like .clone(); and truncates the error.set(format!(...)) call, so the file no longer compiles.

Steps To Reproduce

Steps to reproduce the behavior:

  • Save this as repro.rs:
    use dioxus::prelude::*;
    
    fn app() -> Element {
        let mut uploading = use_signal(|| false);
        let mut error = use_signal(String::new);
        let create_photo_collection = String::new();
    
        rsx! {
            button {
                onclick: {
                    #[cfg(target_os = "android")]
                    let create_photo_collection_gallery = create_photo_collection.clone();
    
                    move |_| {
                        uploading.set(true);
                        error.set(String::new());
    
                        #[cfg(target_os = "android")]
                        let create_photo_collection_gallery_call =
                            create_photo_collection_gallery.clone();
    
                        if let Err(err) = Err::<(), _>("x") {
                            error.set(format!(
                                "{}: {}",
                                "err",
                                err
                            ));
                            uploading.set(false);
                            return;
                        }
                    }
                },
                "x"
            }
        }
    }
    
    fn main() {}
  • Run:
    dx fmt --file repro.rs
  • Inspect the formatted file.

Expected behavior

dx fmt should preserve valid Rust/RSX and produce a formatted file that still compiles.

Instead, it rewrites the snippet into broken code like:

#[cfg(target_os = "android")]
let create_photo_collection_gallery_call =
    create_photo_collection_gallery.clone();
    .clone();

if let Err(err) = Err::<(), _>("x") {
    err
    ));
    uploading.set(false);
    return;
}

Screenshots

N/A

Environment:

  • Dioxus version: dioxus 0.7.7
  • Rust version: rustc 1.95.0
  • OS info: Linux
  • App platform: N/A (formatter / RSX source issue)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions