dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Allow a borrowed key to move into children

Open Threated opened this issue 8 months ago • 2 comments

The follwing code compiles did not compile in release mode before this PR but did in debug:

fn app(arg: String) -> Element {
    rsx! {
        div {
            key: "{arg}",
            for arg in Vec::from(arg) {}
        }
    }
}

This does not work in release as the macro only assembles the key at the end but the example moves the key into the children therefore not compiling. But in a debug build it works as the key is handled differently because of hot-reloading magic I guess.

I should probably include a test but I am not sure where as the rsx crate only includes macro parsing tests it seems.

Threated avatar Jun 13 '25 17:06 Threated

RSX currently evaluates expressions in an odd order. Keys generally just borrow the contents of the expressions, but with dioxus' expanded version of formatted strings you can take a value inside of the expression. That can cause some expressions you would expect to be valid to fail to compile in this branch:

fn app(arg: String) -> Element {
    rsx! {
        div {
            width: "{arg}", // I would expect this to run first and borrow arg
            key: "{take(arg)}", // Then this to run and move arg
        }
    }
}

fn take<T>(t: T) -> T {
    t
}

There is some overlap with https://github.com/DioxusLabs/dioxus/pull/3944 which switches to a more traditional evaluation order, but this PR fixes a case with keys #3944 doesn't handle.

ealmloff avatar Jun 13 '25 17:06 ealmloff

Hm I see. Funnily enough your example compiles in release mode on main but not in debug builds because the take call is part of the __dynamic_literal_pool and arg is then later used in __dynamic_attributes but its already gone.

So I think in practice its very unlikely that people actually rely on this because if would only work in release builds. Also I think its not that common to have a key expression that takes ownership of a value to produce a key. I feel like my approach here still makes sense over all as it matches the debug build behavior better and from what I can tell does not really interfere with your PR?

Threated avatar Jun 15 '25 12:06 Threated