Skip to content

RSX macro changes expression evaluation order #3737

@ealmloff

Description

@ealmloff
Member

Problem

The rsx macro can include expressions in the dynamic nodes or dynamic attributes arrays. We evaluate all expressions in the dynamic nodes before expressions in the dynamic attributes. This can lead to counterintuitive compiler errors because the execution order is changed

Steps To Reproduce

This code looks like it would work in debug and release mode, but it fails to compile in release mode:

use dioxus::prelude::*;

#[derive(Clone, PartialEq, Eq)]
struct TestOuter;

impl TestOuter {
    fn borrow(&self) -> String {
        "".to_string()
    }
}

fn Parent() -> Element {
    let outer = TestOuter;

    rsx! {
        Fragment { key: outer.borrow(),
            Child { outer }
        }
    }
}

#[component]
fn Child(outer: TestOuter) -> Element {
    rsx! {
        div { "Hello" }
    }
}

fn main() {}

Expected behavior

The RSX macro should execute expressions in the order they were created in. We could pull out all expressions in the rsx macro and evaluate them in order then use the results as needed inside the macro expansion.

Environment:

  • Dioxus version: main
  • Rust version: nightly
  • OS info: macO
  • App platform: all

Activity

added
bugSomething isn't working
rsxRelated to rsx or the dioxus-rsx crate
on Feb 13, 2025
self-assigned this
on Apr 1, 2025
ealmloff

ealmloff commented on Apr 1, 2025

@ealmloff
MemberAuthor

New reproduction without keys. The original reproduction is invalid after #3936:

use dioxus::prelude::*;

fn main() {}

#[derive(Clone, PartialEq, Eq)]
struct TestOuter;

impl TestOuter {
    fn borrow(&self) -> String {
        "".to_string()
    }
}

#[component]
fn Component(value: String, children: Element) -> Element {
    rsx! {
        div {
            "{value}"
            {children}
        }
    }
}

#[component]
fn Child(outer: TestOuter) -> Element {
    rsx! {
        div { "Hello" }
    }
}

fn Parent() -> Element {
    let outer = TestOuter;

    rsx! {
        div { width: outer.borrow(),
            Component { value: outer.borrow(),
                Child { outer }
            }
        }
    }
}
linked a pull request that will close this issue on Apr 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingrsxRelated to rsx or the dioxus-rsx crate

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @ealmloff

    Issue actions

      RSX macro changes expression evaluation order · Issue #3737 · DioxusLabs/dioxus