1
0
Эх сурвалжийг харах

Change the semantics of exprs/for loops allocations strategy

This commit adjusts how exprs and for loops are handled within
rsx. This is a breaking change in terms of codegen, but has
slight semantic changes as well.

Now, when exprs/for loops are allocated, they are given a temporary.
The temporary is elided to the <'a> lifetime of the bump, to satisfy
the borrow checker. This fixes issues with signals where exprs/for
loops mapping vecs out of RefCells would be caught up without a
temporary lifetime.
Jonathan Kelley 1 жил өмнө
parent
commit
14b3fa72e4

+ 11 - 0
examples/signals.rs

@@ -7,6 +7,7 @@ fn main() {
 
 fn app(cx: Scope) -> Element {
     let mut count = dioxus_signals::use_signal(cx, || 0);
+    let saved_values = dioxus_signals::use_signal(cx, || vec![0]);
 
     use_future!(cx, || async move {
         loop {
@@ -19,9 +20,19 @@ fn app(cx: Scope) -> Element {
         h1 { "High-Five counter: {count}" }
         button { onclick: move |_| count += 1, "Up high!" }
         button { onclick: move |_| count -= 1, "Down low!" }
+        button {
+            onclick: move |_| saved_values.push(count.value()),
+            "Save this value"
+        }
 
+        // We can do boolean operations on the current signal value
         if count.value() > 5 {
             rsx!{ h2 { "High five!" } }
         }
+
+        // We can cleanly map signals with iterators
+        for value in saved_values.read().iter() {
+            h3 { "Saved value: {value}" }
+        }
     })
 }

+ 13 - 4
packages/rsx/src/node.rs

@@ -125,7 +125,11 @@ impl ToTokens for BodyNode {
                 __cx.text_node(#txt)
             }),
             BodyNode::RawExpr(exp) => tokens.append_all(quote! {
-                 __cx.make_node(#exp)
+                {
+                    use ::dioxus::core::IntoDynNode;
+                    let ___nodes =(#exp).into_vnode(__cx);
+                    ___nodes
+                }
             }),
             BodyNode::ForLoop(exp) => {
                 let ForLoop {
@@ -137,10 +141,15 @@ impl ToTokens for BodyNode {
                     location: None,
                 };
 
+                // Signals expose an issue with temporary lifetimes
+                // We need to directly render out the nodes first to collapse their lifetime to <'a>
+                // And then we can return them into the dyn loop
                 tokens.append_all(quote! {
-                     __cx.make_node(
-                        (#expr).into_iter().map(|#pat| { #renderer })
-                     )
+                    {
+                        use ::dioxus::core::IntoDynNode;
+                        let ___nodes =(#expr).into_iter().map(|#pat| { #renderer }).into_vnode(__cx);
+                        ___nodes
+                    }
                 })
             }
             BodyNode::IfChain(chain) => {