Bläddra i källkod

work on fixing some core tests

Evan Almloff 1 år sedan
förälder
incheckning
55f76fede6
35 ändrade filer med 422 tillägg och 460 borttagningar
  1. 2 0
      packages/core/Cargo.toml
  2. 1 0
      packages/core/src/mutations.rs
  3. 1 1
      packages/core/src/scopes.rs
  4. 29 2
      packages/core/src/virtual_dom.rs
  5. 1 1
      packages/core/tests/README.md
  6. 11 15
      packages/core/tests/attr_cleanup.rs
  7. 3 3
      packages/core/tests/boolattrs.rs
  8. 8 10
      packages/core/tests/borrowedstate.rs
  9. 4 6
      packages/core/tests/bubble_error.rs
  10. 12 12
      packages/core/tests/context_api.rs
  11. 25 36
      packages/core/tests/create_dom.rs
  12. 4 4
      packages/core/tests/create_element.rs
  13. 20 23
      packages/core/tests/create_fragments.rs
  14. 8 8
      packages/core/tests/create_lists.rs
  15. 14 18
      packages/core/tests/create_passthru.rs
  16. 8 10
      packages/core/tests/cycle.rs
  17. 18 21
      packages/core/tests/diff_component.rs
  18. 17 17
      packages/core/tests/diff_element.rs
  19. 48 48
      packages/core/tests/diff_keyed_list.rs
  20. 78 80
      packages/core/tests/diff_unkeyed_list.rs
  21. 4 6
      packages/core/tests/error_boundary.rs
  22. 3 3
      packages/core/tests/event_propagation.rs
  23. 3 3
      packages/core/tests/fuzzing.rs
  24. 15 13
      packages/core/tests/kitchen_sink.rs
  25. 12 12
      packages/core/tests/lifecycle.rs
  26. 6 11
      packages/core/tests/miri_full_app.rs
  27. 27 37
      packages/core/tests/miri_simple.rs
  28. 26 46
      packages/core/tests/miri_stress.rs
  29. 1 1
      packages/core/tests/safety.rs
  30. 3 3
      packages/core/tests/suspense.rs
  31. 2 2
      packages/core/tests/task.rs
  32. 3 3
      packages/native-core/src/utils/persistant_iterator.rs
  33. 1 1
      packages/signals/tests/create.rs
  34. 3 3
      packages/signals/tests/selector.rs
  35. 1 1
      packages/signals/tests/subscribe.rs

+ 2 - 0
packages/core/Cargo.toml

@@ -33,6 +33,7 @@ serde = { version = "1", features = ["derive"], optional = true }
 [dev-dependencies]
 tokio = { workspace = true, features = ["full"] }
 dioxus = { workspace = true }
+dioxus-core = { workspace = true, features = ["internal-testing"] }
 dioxus-html = { workspace = true, features = ["serialize"] }
 pretty_assertions = "1.3.0"
 rand = "0.8.5"
@@ -42,3 +43,4 @@ trybuild = "1.0"
 [features]
 default = []
 serialize = ["serde"]
+internal-testing = []

+ 1 - 0
packages/core/src/mutations.rs

@@ -326,6 +326,7 @@ pub enum Mutation {
 }
 
 /// A static list of mutations that can be applied to the DOM. Note: this list does not contain any `Any` attribute values
+#[derive(Debug, PartialEq, Default)]
 pub struct MutationsVec {
     /// The list of Scopes that were diffed, created, and removed during the Diff process.
     pub dirty_scopes: FxHashSet<ScopeId>,

+ 1 - 1
packages/core/src/scopes.rs

@@ -10,7 +10,7 @@ use std::{cell::Ref, fmt::Debug, rc::Rc};
 /// time for any logic that relies on these IDs to properly update.
 #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
-pub struct ScopeId(pub(crate) usize);
+pub struct ScopeId(pub usize);
 
 impl ScopeId {
     /// The root ScopeId.

+ 29 - 2
packages/core/src/virtual_dom.rs

@@ -13,7 +13,7 @@ use crate::{
     nodes::{Template, TemplateId},
     runtime::{Runtime, RuntimeGuard},
     scopes::{ScopeId, ScopeState},
-    AttributeValue, Element, Event,
+    AttributeValue, Element, Event, MutationsVec,
 };
 use futures_util::{pin_mut, StreamExt};
 use rustc_hash::{FxHashMap, FxHashSet};
@@ -300,7 +300,7 @@ impl VirtualDom {
     /// Get the single scope at the top of the VirtualDom tree that will always be around
     ///
     /// This scope has a ScopeId of 0 and is the root of the tree
-    pub(crate) fn base_scope(&self) -> &ScopeState {
+    pub fn base_scope(&self) -> &ScopeState {
         self.get_scope(ScopeId::ROOT).unwrap()
     }
 
@@ -563,6 +563,14 @@ impl VirtualDom {
         to.append_children(ElementId(0), m);
     }
 
+    #[cfg(features = "internal-testing")]
+    /// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes
+    pub fn rebuild_to_vec(&mut self) -> MutationsVec {
+        let mut mutations = MutationsVec::default();
+        self.rebuild(&mut mutations);
+        mutations
+    }
+
     /// Render whatever the VirtualDom has ready as fast as possible without requiring an executor to progress
     /// suspended subtrees.
     pub fn render_immediate(&mut self, to: &mut impl WriteMutations) {
@@ -582,6 +590,14 @@ impl VirtualDom {
         }
     }
 
+    #[cfg(features = "internal-testing")]
+    /// [`Self::render_immediate`] to a vector of mutations for testing purposes
+    pub fn render_immediate_to_vec(&mut self) -> MutationsVec {
+        let mut mutations = MutationsVec::default();
+        self.render_immediate(&mut mutations);
+        mutations
+    }
+
     /// Render the virtual dom, waiting for all suspense to be finished
     ///
     /// The mutations will be thrown out, so it's best to use this method for things like SSR that have async content
@@ -646,6 +662,17 @@ impl VirtualDom {
         }
     }
 
+    #[cfg(features = "internal-testing")]
+    /// [`Self::render_with_deadline`] to a vector of mutations for testing purposes
+    pub async fn render_with_deadline_to_vec(
+        &mut self,
+        deadline: impl Future<Output = ()>,
+    ) -> MutationsVec {
+        let mut mutations = MutationsVec::default();
+        self.render_with_deadline(deadline, &mut mutations).await;
+        mutations
+    }
+
     /// Get the current runtime
     pub fn runtime(&self) -> Rc<Runtime> {
         self.runtime.clone()

+ 1 - 1
packages/core/tests/README.md

@@ -44,5 +44,5 @@ Hooks
 
 VirtualDOM API
 - [] work
-- [] rebuild
+- [] rebuild_to_vec
 - [] change props

+ 11 - 15
packages/core/tests/attr_cleanup.rs

@@ -10,16 +10,12 @@ use dioxus_core::BorrowedAttributeValue;
 #[test]
 fn attrs_cycle() {
     let mut dom = VirtualDom::new(|cx| {
-        let id = cx.generation();
-        match cx.generation() % 2 {
-            0 => cx.render(rsx! {
-                div {}
-            }),
-            1 => cx.render(rsx! {
-                div {
-                    h1 { class: "{id}", id: "{id}" }
-                }
-            }),
+        let id = generation();
+        match generation() % 2 {
+            0 => render! { div {} },
+            1 => render! {
+                div { h1 { class: "{id}", id: "{id}" } }
+            },
             _ => unreachable!(),
         }
     });
@@ -27,7 +23,7 @@ fn attrs_cycle() {
     let bump = Bump::new();
 
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             AppendChildren { m: 1, id: ElementId(0) },
@@ -36,7 +32,7 @@ fn attrs_cycle() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
             AssignId { path: &[0,], id: ElementId(3,) },
@@ -58,7 +54,7 @@ fn attrs_cycle() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             ReplaceWith { id: ElementId(2), m: 1 }
@@ -67,7 +63,7 @@ fn attrs_cycle() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2) },
             AssignId { path: &[0], id: ElementId(3) },
@@ -90,7 +86,7 @@ fn attrs_cycle() {
     // we take the node taken by attributes since we reused it
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             ReplaceWith { id: ElementId(2), m: 1 }

+ 3 - 3
packages/core/tests/boolattrs.rs

@@ -4,16 +4,16 @@ use dioxus::prelude::*;
 
 #[test]
 fn bool_test() {
-    let mut app = VirtualDom::new(|cx| cx.render(rsx!(div { hidden: false })));
+    let mut app = VirtualDom::new(|cx| render!(div { hidden: false })));
     let bump = Bump::new();
 
     assert_eq!(
-        app.rebuild().santize().edits,
+        app.rebuild_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             SetAttribute {
                 name: "hidden",
-                value: (&*bump.alloc(false.into_value(&bump))).into(),
+                value: dioxus_core::AttributeValue::Bool(false),
                 id: ElementId(1,),
                 ns: None
             },

+ 8 - 10
packages/core/tests/borrowedstate.rs

@@ -8,12 +8,12 @@ fn test_borrowed_state() {
     let mut dom = VirtualDom::new(Parent);
 
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
             LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
-            HydrateText { path: &[0,], value: "Hello w1!", id: ElementId(4,) },
+            HydrateText { path: &[0,], value: "Hello w1!".to_string(), id: ElementId(4,) },
             ReplacePlaceholder { path: &[1,], m: 1 },
             ReplacePlaceholder { path: &[0,], m: 1 },
             AppendChildren { m: 1, id: ElementId(0) },
@@ -24,11 +24,9 @@ fn test_borrowed_state() {
 fn Parent(cx: Scope) -> Element {
     let w1 = cx.use_hook(|| String::from("w1"));
 
-    cx.render(rsx! {
-        div {
-            Child { name: w1 }
-        }
-    })
+    render! {
+        div { Child { name: w1 } }
+    }
 }
 
 #[derive(Props)]
@@ -37,12 +35,12 @@ struct ChildProps<'a> {
 }
 
 fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
-    cx.render(rsx! {
+    render! {
         div {
             h1 { "it's nested" }
             Child2 { name: cx.props.name }
         }
-    })
+    }
 }
 
 #[derive(Props)]
@@ -51,5 +49,5 @@ struct Grandchild<'a> {
 }
 
 fn Child2<'a>(cx: Scope<'a, Grandchild<'a>>) -> Element {
-    cx.render(rsx!(div { "Hello {cx.props.name}!" }))
+    render!( div { "Hello {cx.props.name}!" } )
 }

+ 4 - 6
packages/core/tests/bubble_error.rs

@@ -3,7 +3,7 @@
 use dioxus::prelude::*;
 
 fn app(cx: Scope) -> Element {
-    let raw = match cx.generation() % 2 {
+    let raw = match generation() % 2 {
         0 => "123.123",
         1 => "123.123.123",
         _ => unreachable!(),
@@ -11,9 +11,7 @@ fn app(cx: Scope) -> Element {
 
     let value = raw.parse::<f32>().unwrap_or(123.123);
 
-    cx.render(rsx! {
-        div { "hello {value}" }
-    })
+    render! { div { "hello {value}" } }
 }
 
 #[test]
@@ -21,10 +19,10 @@ fn bubbles_error() {
     let mut dom = VirtualDom::new(app);
 
     {
-        let _edits = dom.rebuild().santize();
+        let _edits = dom.rebuild_to_vec().santize();
     }
 
     dom.mark_dirty(ScopeId::ROOT);
 
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }

+ 12 - 12
packages/core/tests/context_api.rs

@@ -4,48 +4,48 @@ use dioxus::prelude::*;
 #[test]
 fn state_shares() {
     fn app(cx: Scope) -> Element {
-        cx.provide_context(cx.generation() as i32);
+        cx.provide_context(generation() as i32);
 
-        cx.render(rsx!(child_1 {}))
+        render!(child_1 {})
     }
 
     fn child_1(cx: Scope) -> Element {
-        cx.render(rsx!(child_2 {}))
+        render!(child_2 {})
     }
 
     fn child_2(cx: Scope) -> Element {
         let value = cx.consume_context::<i32>().unwrap();
-        cx.render(rsx!("Value is {value}"))
+        render!("Value is {value}")
     }
 
     let mut dom = VirtualDom::new(app);
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
-            CreateTextNode { value: "Value is 0", id: ElementId(1,) },
+            CreateTextNode { value: "Value is 0".to_string(), id: ElementId(1,) },
             AppendChildren { m: 1, id: ElementId(0) },
         ]
     );
 
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
     assert_eq!(dom.base_scope().consume_context::<i32>().unwrap(), 1);
 
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
     assert_eq!(dom.base_scope().consume_context::<i32>().unwrap(), 2);
 
     dom.mark_dirty(ScopeId(2));
     assert_eq!(
-        dom.render_immediate().santize().edits,
-        [SetText { value: "Value is 2", id: ElementId(1,) },]
+        dom.render_immediate_to_vec().santize().edits,
+        [SetText { value: "Value is 2".to_string(), id: ElementId(1,) },]
     );
 
     dom.mark_dirty(ScopeId::ROOT);
     dom.mark_dirty(ScopeId(2));
-    let edits = dom.render_immediate();
+    let edits = dom.render_immediate_to_vec();
     assert_eq!(
         edits.santize().edits,
-        [SetText { value: "Value is 3", id: ElementId(1,) },]
+        [SetText { value: "Value is 3".to_string(), id: ElementId(1,) },]
     );
 }

+ 25 - 36
packages/core/tests/create_dom.rs

@@ -2,8 +2,8 @@
 
 //! Prove that the dom works normally through virtualdom methods.
 //!
-//! This methods all use "rebuild" which completely bypasses the scheduler.
-//! Hard rebuilds don't consume any events from the event queue.
+//! This methods all use "rebuild_to_vec" which completely bypasses the scheduler.
+//! Hard rebuild_to_vecs don't consume any events from the event queue.
 
 use dioxus::core::Mutation::*;
 use dioxus::prelude::*;
@@ -12,16 +12,12 @@ use dioxus_core::ElementId;
 #[test]
 fn test_original_diff() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
-            div {
-                div {
-                    "Hello, world!"
-                }
-            }
-        })
+        render! {
+            div { div { "Hello, world!" } }
+        }
     });
 
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     assert_eq!(
         edits.edits,
@@ -36,24 +32,21 @@ fn test_original_diff() {
 #[test]
 fn create() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
+        render! {
             div {
                 div {
                     "Hello, world!"
                     div {
                         div {
-                            Fragment {
-                                "hello"
-                                "world"
-                            }
+                            Fragment { "hello""world" }
                         }
                     }
                 }
             }
-        })
+        }
     });
 
-    let _edits = dom.rebuild().santize();
+    let _edits = dom.rebuild_to_vec().santize();
 
     // todo: we don't test template mutations anymore since the templates are passed along
 
@@ -82,13 +75,9 @@ fn create() {
 
 #[test]
 fn create_list() {
-    let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
-            (0..3).map(|f| rsx!( div { "hello" } ))
-        })
-    });
+    let mut dom = VirtualDom::new(|cx| render! {(0..3).map(|f| render!( div { "hello" } ))}));
 
-    let _edits = dom.rebuild().santize();
+    let _edits = dom.rebuild_to_vec().santize();
 
     // note: we dont test template edits anymore
     // assert_eq!(
@@ -106,15 +95,15 @@ fn create_list() {
 #[test]
 fn create_simple() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
+        render! {
             div {}
             div {}
             div {}
             div {}
-        })
+        }
     });
 
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     // note: we dont test template edits anymore
     // assert_eq!(
@@ -133,11 +122,11 @@ fn create_simple() {
 #[test]
 fn create_components() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
+        render! {
             Child { "abc1" }
             Child { "abc2" }
             Child { "abc3" }
-        })
+        }
     });
 
     #[derive(Props)]
@@ -146,14 +135,14 @@ fn create_components() {
     }
 
     fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
-        cx.render(rsx! {
+        render! {
             h1 {}
             div { &cx.props.children }
             p {}
-        })
+        }
     }
 
-    let _edits = dom.rebuild().santize();
+    let _edits = dom.rebuild_to_vec().santize();
 
     // todo: test this
 }
@@ -161,18 +150,18 @@ fn create_components() {
 #[test]
 fn anchors() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
+        render! {
             if true {
-                rsx!( div { "hello" } )
+                render!( div { "hello" } )
             }
             if false {
-                rsx!( div { "goodbye" } )
+                render!( div { "goodbye" } )
             }
-        })
+        }
     });
 
     // note that the template under "false" doesn't show up since it's not loaded
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     // note: we dont test template edits anymore
     // assert_eq!(

+ 4 - 4
packages/core/tests/create_element.rs

@@ -4,18 +4,18 @@ use dioxus::prelude::*;
 #[test]
 fn multiroot() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
+        render! {
             div { "Hello a" }
             div { "Hello b" }
             div { "Hello c" }
-        })
+        }
     });
 
     // note: we dont test template edits anymore
-    let _templates = dom.rebuild().santize().templates;
+    let _templates = dom.rebuild_to_vec().santize().templates;
 
     // assert_eq!(
-    //     dom.rebuild().santize().templates,
+    //     dom.rebuild_to_vec().santize().templates,
     //     [
     //         CreateElement { name: "div" },
     //         CreateStaticText { value: "Hello a" },

+ 20 - 23
packages/core/tests/create_fragments.rs

@@ -7,11 +7,11 @@ use dioxus_core::ElementId;
 #[test]
 fn empty_fragment_creates_nothing() {
     fn app(cx: Scope) -> Element {
-        cx.render(rsx!(()))
+        render!(())
     }
 
     let mut vdom = VirtualDom::new(app);
-    let edits = vdom.rebuild();
+    let edits = vdom.rebuild_to_vec();
 
     assert_eq!(
         edits.edits,
@@ -25,14 +25,14 @@ fn empty_fragment_creates_nothing() {
 #[test]
 fn root_fragments_work() {
     let mut vdom = VirtualDom::new(|cx| {
-        cx.render(rsx!(
+        render!(
             div { "hello" }
             div { "goodbye" }
-        ))
+        )
     });
 
     assert_eq!(
-        vdom.rebuild().edits.last().unwrap(),
+        vdom.rebuild_to_vec().edits.last().unwrap(),
         &AppendChildren { id: ElementId(0), m: 2 }
     );
 }
@@ -40,26 +40,26 @@ fn root_fragments_work() {
 #[test]
 fn fragments_nested() {
     let mut vdom = VirtualDom::new(|cx| {
-        cx.render(rsx!(
+        render!(
             div { "hello" }
             div { "goodbye" }
-            rsx! {
+            render! {
                 div { "hello" }
                 div { "goodbye" }
-                rsx! {
+                render! {
                     div { "hello" }
                     div { "goodbye" }
-                    rsx! {
+                    render! {
                         div { "hello" }
                         div { "goodbye" }
                     }
                 }
             }
-        ))
+        )
     });
 
     assert_eq!(
-        vdom.rebuild().edits.last().unwrap(),
+        vdom.rebuild_to_vec().edits.last().unwrap(),
         &AppendChildren { id: ElementId(0), m: 8 }
     );
 }
@@ -67,24 +67,21 @@ fn fragments_nested() {
 #[test]
 fn fragments_across_components() {
     fn app(cx: Scope) -> Element {
-        cx.render(rsx! {
+        render! {
             demo_child {}
             demo_child {}
             demo_child {}
             demo_child {}
-        })
+        }
     }
 
     fn demo_child(cx: Scope) -> Element {
         let world = "world";
-        cx.render(rsx! {
-            "hellO!"
-            world
-        })
+        render! { "hellO!", world }
     }
 
     assert_eq!(
-        VirtualDom::new(app).rebuild().edits.last().unwrap(),
+        VirtualDom::new(app).rebuild_to_vec().edits.last().unwrap(),
         &AppendChildren { id: ElementId(0), m: 8 }
     );
 }
@@ -92,13 +89,13 @@ fn fragments_across_components() {
 #[test]
 fn list_fragments() {
     fn app(cx: Scope) -> Element {
-        cx.render(rsx!(
-            h1 {"hello"}
-            (0..6).map(|f| rsx!( span { "{f}" }))
-        ))
+        render!(
+            h1 { "hello" }
+            (0..6).map(|f| render!( span { "{f}" }))
+        )
     }
     assert_eq!(
-        VirtualDom::new(app).rebuild().edits.last().unwrap(),
+        VirtualDom::new(app).rebuild_to_vec().edits.last().unwrap(),
         &AppendChildren { id: ElementId(0), m: 7 }
     );
 }

+ 8 - 8
packages/core/tests/create_lists.rs

@@ -5,27 +5,27 @@ use dioxus_core::ElementId;
 // A real-world usecase of templates at peak performance
 // In react, this would be a lot of node creation.
 //
-// In Dioxus, we memoize the rsx! body and simplify it down to a few template loads
+// In Dioxus, we memoize the render! body and simplify it down to a few template loads
 //
 // Also note that the IDs increase linearly. This lets us drive a vec on the renderer for O(1) re-indexing
 fn app(cx: Scope) -> Element {
-    cx.render(rsx! {
+    render! {
         div {
-            (0..3).map(|i| rsx! {
+            (0..3).map(|i| render! {
                 div {
                     h1 { "hello world! "}
                     p { "{i}" }
                 }
             })
         }
-    })
+    }
 }
 
 #[test]
 fn list_renders() {
     let mut dom = VirtualDom::new(app);
 
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     // note: we dont test template edits anymore
     // assert_eq!(
@@ -58,11 +58,11 @@ fn list_renders() {
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             // Load each template one-by-one, rehydrating it
             LoadTemplate { name: "template", index: 0, id: ElementId(2) },
-            HydrateText { path: &[1, 0], value: "0", id: ElementId(3) },
+            HydrateText { path: &[1, 0], value: "0".to_string(), id: ElementId(3) },
             LoadTemplate { name: "template", index: 0, id: ElementId(4) },
-            HydrateText { path: &[1, 0], value: "1", id: ElementId(5) },
+            HydrateText { path: &[1, 0], value: "1".to_string(), id: ElementId(5) },
             LoadTemplate { name: "template", index: 0, id: ElementId(6) },
-            HydrateText { path: &[1, 0], value: "2", id: ElementId(7) },
+            HydrateText { path: &[1, 0], value: "2".to_string(), id: ElementId(7) },
             // Replace the 0th childn on the div with the 3 templates on the stack
             ReplacePlaceholder { m: 3, path: &[0] },
             // Append the container div to the dom

+ 14 - 18
packages/core/tests/create_passthru.rs

@@ -7,24 +7,22 @@ use dioxus_core::ElementId;
 fn nested_passthru_creates() {
     #[component]
     fn App(cx: Scope) -> Element {
-        cx.render(rsx! {
+        render! {
             PassThru {
                 PassThru {
-                    PassThru {
-                        div { "hi" }
-                    }
+                    PassThru { div { "hi" } }
                 }
             }
-        })
+        }
     }
 
     #[component]
     fn PassThru<'a>(cx: Scope<'a>, children: Element) -> Element {
-        cx.render(rsx!(children))
+        render!(children)
     }
 
     let mut dom = VirtualDom::new(App);
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     assert_eq!(
         edits.edits,
@@ -42,31 +40,29 @@ fn nested_passthru_creates() {
 fn nested_passthru_creates_add() {
     #[component]
     fn App(cx: Scope) -> Element {
-        cx.render(rsx! {
+        render! {
             ChildComp {
                 "1"
                 ChildComp {
                     "2"
                     ChildComp {
                         "3"
-                        div {
-                            "hi"
-                        }
+                        div { "hi" }
                     }
                 }
             }
-        })
+        }
     }
 
     #[component]
     fn ChildComp<'a>(cx: Scope, children: Element) -> Element {
-        cx.render(rsx! { children })
+        render! {children}
     }
 
     let mut dom = VirtualDom::new(App);
 
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             // load 1
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
@@ -88,11 +84,11 @@ fn dynamic_node_as_root() {
     fn App(cx: Scope) -> Element {
         let a = 123;
         let b = 456;
-        cx.render(rsx! { "{a}" "{b}" })
+        render! { "{a}", "{b}" }
     }
 
     let mut dom = VirtualDom::new(App);
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     // Since the roots were all dynamic, they should not cause any template muations
     assert!(edits.templates.is_empty());
@@ -101,8 +97,8 @@ fn dynamic_node_as_root() {
     assert_eq!(
         edits.edits,
         [
-            CreateTextNode { value: "123", id: ElementId(1) },
-            CreateTextNode { value: "456", id: ElementId(2) },
+            CreateTextNode { value: "123".to_string(), id: ElementId(1) },
+            CreateTextNode { value: "456".to_string(), id: ElementId(2) },
             AppendChildren { id: ElementId(0), m: 2 }
         ]
     )

+ 8 - 10
packages/core/tests/cycle.rs

@@ -4,16 +4,14 @@ use dioxus::prelude::*;
 /// As we clean up old templates, the ID for the node should cycle
 #[test]
 fn cycling_elements() {
-    let mut dom = VirtualDom::new(|cx| {
-        cx.render(match cx.generation() % 2 {
-            0 => rsx! { div { "wasd" } },
-            1 => rsx! { div { "abcd" } },
-            _ => unreachable!(),
-        })
+    let mut dom = VirtualDom::new(|cx| match generation() % 2 {
+        0 => render! { div { "wasd" } },
+        1 => render! { div { "abcd" } },
+        _ => unreachable!(),
     });
 
     {
-        let edits = dom.rebuild().santize();
+        let edits = dom.rebuild_to_vec().santize();
         assert_eq!(
             edits.edits,
             [
@@ -25,7 +23,7 @@ fn cycling_elements() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
             ReplaceWith { id: ElementId(1,), m: 1 },
@@ -35,7 +33,7 @@ fn cycling_elements() {
     // notice that the IDs cycle back to ElementId(1), preserving a minimal memory footprint
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             ReplaceWith { id: ElementId(2,), m: 1 },
@@ -44,7 +42,7 @@ fn cycling_elements() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
             ReplaceWith { id: ElementId(1,), m: 1 },

+ 18 - 21
packages/core/tests/diff_component.rs

@@ -12,55 +12,52 @@ fn component_swap() {
 
         *render_phase += 1;
 
-        cx.render(match *render_phase {
-            0 => rsx! {
+        match *render_phase {
+            0 => render! {
                 nav_bar {}
                 dash_board {}
             },
-            1 => rsx! {
+            1 => render! {
                 nav_bar {}
                 dash_results {}
             },
-            2 => rsx! {
+            2 => render! {
                 nav_bar {}
                 dash_board {}
             },
-            3 => rsx! {
+            3 => render! {
                 nav_bar {}
                 dash_results {}
             },
-            4 => rsx! {
+            4 => render! {
                 nav_bar {}
                 dash_board {}
             },
-            _ => rsx!("blah"),
-        })
+            _ => render!("blah"),
+        }
     }
 
     fn nav_bar(cx: Scope) -> Element {
-        cx.render(rsx! {
-            h1 {
-                "NavBar"
-                (0..3).map(|_| rsx!(nav_link {}))
-            }
-        })
+        render! {
+            h1 { "NavBar", (0..3).map(|_| render!(nav_link {})) }
+        }
     }
 
     fn nav_link(cx: Scope) -> Element {
-        cx.render(rsx!( h1 { "nav_link" } ))
+        render!( h1 { "nav_link" } )
     }
 
     fn dash_board(cx: Scope) -> Element {
-        cx.render(rsx!( div { "dashboard" } ))
+        render!( div { "dashboard" } )
     }
 
     fn dash_results(cx: Scope) -> Element {
-        cx.render(rsx!( div { "results" } ))
+        render!( div { "results" } )
     }
 
     let mut dom = VirtualDom::new(app);
     {
-        let edits = dom.rebuild().santize();
+        let edits = dom.rebuild_to_vec().santize();
         assert_eq!(
             edits.edits,
             [
@@ -77,7 +74,7 @@ fn component_swap() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(6) },
             ReplaceWith { id: ElementId(5), m: 1 }
@@ -86,7 +83,7 @@ fn component_swap() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(5) },
             ReplaceWith { id: ElementId(6), m: 1 }
@@ -95,7 +92,7 @@ fn component_swap() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(6) },
             ReplaceWith { id: ElementId(5), m: 1 }

+ 17 - 17
packages/core/tests/diff_element.rs

@@ -5,50 +5,50 @@ use dioxus_core::ElementId;
 #[test]
 fn text_diff() {
     fn app(cx: Scope) -> Element {
-        let gen = cx.generation();
-        cx.render(rsx!( h1 { "hello {gen}" } ))
+        let gen = generation();
+        render!( h1 { "hello {gen}" } )
     }
 
     let mut vdom = VirtualDom::new(app);
-    _ = vdom.rebuild();
+    _ = vdom.rebuild_to_vec();
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().edits,
-        [SetText { value: "hello 1", id: ElementId(2) }]
+        vdom.render_immediate_to_vec().edits,
+        [SetText { value: "hello 1".to_string(), id: ElementId(2) }]
     );
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().edits,
-        [SetText { value: "hello 2", id: ElementId(2) }]
+        vdom.render_immediate_to_vec().edits,
+        [SetText { value: "hello 2".to_string(), id: ElementId(2) }]
     );
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().edits,
-        [SetText { value: "hello 3", id: ElementId(2) }]
+        vdom.render_immediate_to_vec().edits,
+        [SetText { value: "hello 3".to_string(), id: ElementId(2) }]
     );
 }
 
 #[test]
 fn element_swap() {
     fn app(cx: Scope) -> Element {
-        let gen = cx.generation();
+        let gen = generation();
 
         match gen % 2 {
-            0 => cx.render(rsx!( h1 { "hello 1" } )),
-            1 => cx.render(rsx!( h2 { "hello 2" } )),
+            0 => render!( h1 { "hello 1" } ),
+            1 => render!( h2 { "hello 2" } ),
             _ => unreachable!(),
         }
     }
 
     let mut vdom = VirtualDom::new(app);
-    _ = vdom.rebuild();
+    _ = vdom.rebuild_to_vec();
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().santize().edits,
+        vdom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
             ReplaceWith { id: ElementId(1,), m: 1 },
@@ -57,7 +57,7 @@ fn element_swap() {
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().santize().edits,
+        vdom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             ReplaceWith { id: ElementId(2,), m: 1 },
@@ -66,7 +66,7 @@ fn element_swap() {
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().santize().edits,
+        vdom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
             ReplaceWith { id: ElementId(1,), m: 1 },
@@ -75,7 +75,7 @@ fn element_swap() {
 
     vdom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        vdom.render_immediate().santize().edits,
+        vdom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             ReplaceWith { id: ElementId(2,), m: 1 },

+ 48 - 48
packages/core/tests/diff_keyed_list.rs

@@ -11,18 +11,18 @@ use dioxus::prelude::*;
 #[test]
 fn keyed_diffing_out_of_order() {
     let mut dom = VirtualDom::new(|cx| {
-        let order = match cx.generation() % 2 {
+        let order = match generation() % 2 {
             0 => &[0, 1, 2, 3, /**/ 4, 5, 6, /**/ 7, 8, 9],
             1 => &[0, 1, 2, 3, /**/ 6, 4, 5, /**/ 7, 8, 9],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
     {
         assert_eq!(
-            dom.rebuild().santize().edits,
+            dom.rebuild_to_vec().santize().edits,
             [
                 LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
                 LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
@@ -41,7 +41,7 @@ fn keyed_diffing_out_of_order() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().edits,
+        dom.render_immediate_to_vec().edits,
         [
             PushRoot { id: ElementId(7,) },
             InsertBefore { id: ElementId(5,), m: 1 },
@@ -53,20 +53,20 @@ fn keyed_diffing_out_of_order() {
 #[test]
 fn keyed_diffing_out_of_order_adds() {
     let mut dom = VirtualDom::new(|cx| {
-        let order = match cx.generation() % 2 {
+        let order = match generation() % 2 {
             0 => &[/**/ 4, 5, 6, 7, 8 /**/],
             1 => &[/**/ 8, 7, 4, 5, 6 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().edits,
+        dom.render_immediate_to_vec().edits,
         [
             PushRoot { id: ElementId(5,) },
             PushRoot { id: ElementId(4,) },
@@ -79,20 +79,20 @@ fn keyed_diffing_out_of_order_adds() {
 #[test]
 fn keyed_diffing_out_of_order_adds_3() {
     let mut dom = VirtualDom::new(|cx| {
-        let order = match cx.generation() % 2 {
+        let order = match generation() % 2 {
             0 => &[/**/ 4, 5, 6, 7, 8 /**/],
             1 => &[/**/ 4, 8, 7, 5, 6 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().edits,
+        dom.render_immediate_to_vec().edits,
         [
             PushRoot { id: ElementId(5,) },
             PushRoot { id: ElementId(4,) },
@@ -105,20 +105,20 @@ fn keyed_diffing_out_of_order_adds_3() {
 #[test]
 fn keyed_diffing_out_of_order_adds_4() {
     let mut dom = VirtualDom::new(|cx| {
-        let order = match cx.generation() % 2 {
+        let order = match generation() % 2 {
             0 => &[/**/ 4, 5, 6, 7, 8 /**/],
             1 => &[/**/ 4, 5, 8, 7, 6 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().edits,
+        dom.render_immediate_to_vec().edits,
         [
             PushRoot { id: ElementId(5,) },
             PushRoot { id: ElementId(4,) },
@@ -131,20 +131,20 @@ fn keyed_diffing_out_of_order_adds_4() {
 #[test]
 fn keyed_diffing_out_of_order_adds_5() {
     let mut dom = VirtualDom::new(|cx| {
-        let order = match cx.generation() % 2 {
+        let order = match generation() % 2 {
             0 => &[/**/ 4, 5, 6, 7, 8 /**/],
             1 => &[/**/ 4, 5, 6, 8, 7 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().edits,
+        dom.render_immediate_to_vec().edits,
         [
             PushRoot { id: ElementId(5,) },
             InsertBefore { id: ElementId(4,), m: 1 },
@@ -156,20 +156,20 @@ fn keyed_diffing_out_of_order_adds_5() {
 #[test]
 fn keyed_diffing_additions() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[/**/ 4, 5, 6, 7, 8 /**/],
             1 => &[/**/ 4, 5, 6, 7, 8, 9, 10 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(6) },
             LoadTemplate { name: "template", index: 0, id: ElementId(7) },
@@ -181,20 +181,20 @@ fn keyed_diffing_additions() {
 #[test]
 fn keyed_diffing_additions_and_moves_on_ends() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[/**/ 4, 5, 6, 7 /**/],
             1 => &[/**/ 7, 4, 5, 6, 11, 12 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             // create 11, 12
             LoadTemplate { name: "template", index: 0, id: ElementId(5) },
@@ -210,21 +210,21 @@ fn keyed_diffing_additions_and_moves_on_ends() {
 #[test]
 fn keyed_diffing_additions_and_moves_in_middle() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[/**/ 1, 2, 3, 4 /**/],
             1 => &[/**/ 4, 1, 7, 8, 2, 5, 6, 3 /**/],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     // LIS: 4, 5, 6
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             // create 5, 6
             LoadTemplate { name: "template", index: 0, id: ElementId(5) },
@@ -244,21 +244,21 @@ fn keyed_diffing_additions_and_moves_in_middle() {
 #[test]
 fn controlled_keyed_diffing_out_of_order() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[4, 5, 6, 7],
             1 => &[0, 5, 9, 6, 4],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     // LIS: 5, 6
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             // remove 7
             Remove { id: ElementId(4,) },
@@ -278,20 +278,20 @@ fn controlled_keyed_diffing_out_of_order() {
 #[test]
 fn controlled_keyed_diffing_out_of_order_max_test() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[0, 1, 2, 3, 4],
             1 => &[3, 0, 1, 10, 2],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             Remove { id: ElementId(5,) },
             LoadTemplate { name: "template", index: 0, id: ElementId(5) },
@@ -307,20 +307,20 @@ fn controlled_keyed_diffing_out_of_order_max_test() {
 #[test]
 fn remove_list() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[9, 8, 7, 6, 5],
             1 => &[9, 8],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             Remove { id: ElementId(5) },
             Remove { id: ElementId(4) },
@@ -332,20 +332,20 @@ fn remove_list() {
 #[test]
 fn no_common_keys() {
     let mut dom = VirtualDom::new(|cx| {
-        let order: &[_] = match cx.generation() % 2 {
+        let order: &[_] = match generation() % 2 {
             0 => &[1, 2, 3],
             1 => &[4, 5, 6],
             _ => unreachable!(),
         };
 
-        cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
+        render!(order.iter().map(|i| render!(div { key: "{i}" })))
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             Remove { id: ElementId(3) },
             Remove { id: ElementId(2) },

+ 78 - 80
packages/core/tests/diff_unkeyed_list.rs

@@ -5,20 +5,20 @@ use pretty_assertions::assert_eq;
 #[test]
 fn list_creates_one_by_one() {
     let mut dom = VirtualDom::new(|cx| {
-        let gen = cx.generation();
+        let gen = generation();
 
-        cx.render(rsx! {
+        render! {
             div {
-                (0..gen).map(|i| rsx! {
+                (0..gen).map(|i| render! {
                     div { "{i}" }
                 })
             }
-        })
+        }
     });
 
     // load the div and then assign the empty fragment as a placeholder
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             AssignId { path: &[0], id: ElementId(2,) },
@@ -29,10 +29,10 @@ fn list_creates_one_by_one() {
     // Rendering the first item should replace the placeholder with an element
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
-            HydrateText { path: &[0], value: "0", id: ElementId(4,) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(4,) },
             ReplaceWith { id: ElementId(2,), m: 1 },
         ]
     );
@@ -40,10 +40,10 @@ fn list_creates_one_by_one() {
     // Rendering the next item should insert after the previous
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
-            HydrateText { path: &[0], value: "1", id: ElementId(5,) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(5,) },
             InsertAfter { id: ElementId(3,), m: 1 },
         ]
     );
@@ -51,10 +51,10 @@ fn list_creates_one_by_one() {
     // ... and again!
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(6,) },
-            HydrateText { path: &[0], value: "2", id: ElementId(7,) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(7,) },
             InsertAfter { id: ElementId(2,), m: 1 },
         ]
     );
@@ -62,10 +62,10 @@ fn list_creates_one_by_one() {
     // once more
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(8,) },
-            HydrateText { path: &[0], value: "3", id: ElementId(9,) },
+            HydrateText { path: &[0], value: "3".to_string(), id: ElementId(9,) },
             InsertAfter { id: ElementId(6,), m: 1 },
         ]
     );
@@ -74,30 +74,30 @@ fn list_creates_one_by_one() {
 #[test]
 fn removes_one_by_one() {
     let mut dom = VirtualDom::new(|cx| {
-        let gen = 3 - cx.generation() % 4;
+        let gen = 3 - generation() % 4;
 
-        cx.render(rsx! {
+        render! {
             div {
-                (0..gen).map(|i| rsx! {
+                (0..gen).map(|i| render! {
                     div { "{i}" }
                 })
             }
-        })
+        }
     });
 
     // load the div and then assign the empty fragment as a placeholder
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             // The container
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             // each list item
             LoadTemplate { name: "template", index: 0, id: ElementId(2) },
-            HydrateText { path: &[0], value: "0", id: ElementId(3) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(3) },
             LoadTemplate { name: "template", index: 0, id: ElementId(4) },
-            HydrateText { path: &[0], value: "1", id: ElementId(5) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(5) },
             LoadTemplate { name: "template", index: 0, id: ElementId(6) },
-            HydrateText { path: &[0], value: "2", id: ElementId(7) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(7) },
             // replace the placeholder in the template with the 3 templates on the stack
             ReplacePlaceholder { m: 3, path: &[0] },
             // Mount the div
@@ -109,14 +109,14 @@ fn removes_one_by_one() {
     // Rendering the first item should replace the placeholder with an element
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [Remove { id: ElementId(6) }]
     );
 
     // Remove div(2)
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [Remove { id: ElementId(4) }]
     );
 
@@ -124,7 +124,7 @@ fn removes_one_by_one() {
     // todo: this should just be a remove with no placeholder
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             CreatePlaceholder { id: ElementId(4) },
             ReplaceWith { id: ElementId(2), m: 1 }
@@ -135,14 +135,14 @@ fn removes_one_by_one() {
     // todo: this should actually be append to, but replace placeholder is fine for now
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2) },
-            HydrateText { path: &[0], value: "0", id: ElementId(3) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(3) },
             LoadTemplate { name: "template", index: 0, id: ElementId(5) },
-            HydrateText { path: &[0], value: "1", id: ElementId(6) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(6) },
             LoadTemplate { name: "template", index: 0, id: ElementId(7) },
-            HydrateText { path: &[0], value: "2", id: ElementId(8) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(8) },
             ReplaceWith { id: ElementId(4), m: 3 }
         ]
     );
@@ -151,18 +151,18 @@ fn removes_one_by_one() {
 #[test]
 fn list_shrink_multiroot() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
+        render! {
             div {
-                (0..cx.generation()).map(|i| rsx! {
+                (0..generation()).map(|i| render! {
                     div { "{i}" }
                     div { "{i}" }
                 })
             }
-        })
+        }
     });
 
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
             AssignId { path: &[0,], id: ElementId(2,) },
@@ -172,36 +172,36 @@ fn list_shrink_multiroot() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(3) },
-            HydrateText { path: &[0], value: "0", id: ElementId(4) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(4) },
             LoadTemplate { name: "template", index: 1, id: ElementId(5) },
-            HydrateText { path: &[0], value: "0", id: ElementId(6) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(6) },
             ReplaceWith { id: ElementId(2), m: 2 }
         ]
     );
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(2) },
-            HydrateText { path: &[0], value: "1", id: ElementId(7) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(7) },
             LoadTemplate { name: "template", index: 1, id: ElementId(8) },
-            HydrateText { path: &[0], value: "1", id: ElementId(9) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(9) },
             InsertAfter { id: ElementId(5), m: 2 }
         ]
     );
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(10) },
-            HydrateText { path: &[0], value: "2", id: ElementId(11) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(11) },
             LoadTemplate { name: "template", index: 1, id: ElementId(12) },
-            HydrateText { path: &[0], value: "2", id: ElementId(13) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(13) },
             InsertAfter { id: ElementId(8), m: 2 }
         ]
     );
@@ -210,38 +210,38 @@ fn list_shrink_multiroot() {
 #[test]
 fn removes_one_by_one_multiroot() {
     let mut dom = VirtualDom::new(|cx| {
-        let gen = 3 - cx.generation() % 4;
+        let gen = 3 - generation() % 4;
 
-        cx.render(rsx! {
+        render! {
             div {
-                (0..gen).map(|i| rsx! {
+                (0..gen).map(|i| render! {
                     div { "{i}" }
                     div { "{i}" }
                 })
             }
-        })
+        }
     });
 
     // load the div and then assign the empty fragment as a placeholder
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             //
             LoadTemplate { name: "template", index: 0, id: ElementId(2) },
-            HydrateText { path: &[0], value: "0", id: ElementId(3) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(3) },
             LoadTemplate { name: "template", index: 1, id: ElementId(4) },
-            HydrateText { path: &[0], value: "0", id: ElementId(5) },
+            HydrateText { path: &[0], value: "0".to_string(), id: ElementId(5) },
             //
             LoadTemplate { name: "template", index: 0, id: ElementId(6) },
-            HydrateText { path: &[0], value: "1", id: ElementId(7) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(7) },
             LoadTemplate { name: "template", index: 1, id: ElementId(8) },
-            HydrateText { path: &[0], value: "1", id: ElementId(9) },
+            HydrateText { path: &[0], value: "1".to_string(), id: ElementId(9) },
             //
             LoadTemplate { name: "template", index: 0, id: ElementId(10) },
-            HydrateText { path: &[0], value: "2", id: ElementId(11) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(11) },
             LoadTemplate { name: "template", index: 1, id: ElementId(12) },
-            HydrateText { path: &[0], value: "2", id: ElementId(13) },
+            HydrateText { path: &[0], value: "2".to_string(), id: ElementId(13) },
             //
             ReplacePlaceholder { path: &[0], m: 6 },
             //
@@ -251,19 +251,19 @@ fn removes_one_by_one_multiroot() {
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [Remove { id: ElementId(10) }, Remove { id: ElementId(12) }]
     );
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [Remove { id: ElementId(6) }, Remove { id: ElementId(8) }]
     );
 
     dom.mark_dirty(ScopeId::ROOT);
     assert_eq!(
-        dom.render_immediate().santize().edits,
+        dom.render_immediate_to_vec().santize().edits,
         [
             CreatePlaceholder { id: ElementId(8) },
             Remove { id: ElementId(2) },
@@ -275,48 +275,46 @@ fn removes_one_by_one_multiroot() {
 #[test]
 fn two_equal_fragments_are_equal_static() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
-            (0..5).map(|_| rsx! {
+        render! {
+            (0..5).map(|_| render! {
                 div { "hello" }
             })
-        })
+        }
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
-    assert!(dom.render_immediate().edits.is_empty());
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
+    assert!(dom.render_immediate_to_vec().edits.is_empty());
 }
 
 #[test]
 fn two_equal_fragments_are_equal() {
     let mut dom = VirtualDom::new(|cx| {
-        cx.render(rsx! {
-            (0..5).map(|i| rsx! {
+        render! {
+            (0..5).map(|i| render! {
                 div { "hello {i}" }
             })
-        })
+        }
     });
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
-    assert!(dom.render_immediate().edits.is_empty());
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
+    assert!(dom.render_immediate_to_vec().edits.is_empty());
 }
 
 #[test]
 fn remove_many() {
     let mut dom = VirtualDom::new(|cx| {
-        let num = match cx.generation() % 3 {
+        let num = match generation() % 3 {
             0 => 0,
             1 => 1,
             2 => 5,
             _ => unreachable!(),
         };
 
-        cx.render(rsx! {
-            (0..num).map(|i| rsx! { div { "hello {i}" } })
-        })
+        render! {(0..num).map(|i| render! { div { "hello {i}" } })}
     });
 
     {
-        let edits = dom.rebuild().santize();
+        let edits = dom.rebuild_to_vec().santize();
         assert!(edits.templates.is_empty());
         assert_eq!(
             edits.edits,
@@ -329,12 +327,12 @@ fn remove_many() {
 
     {
         dom.mark_dirty(ScopeId::ROOT);
-        let edits = dom.render_immediate().santize();
+        let edits = dom.render_immediate_to_vec().santize();
         assert_eq!(
             edits.edits,
             [
                 LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
-                HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
+                HydrateText { path: &[0,], value: "hello 0".to_string(), id: ElementId(3,) },
                 ReplaceWith { id: ElementId(1,), m: 1 },
             ]
         );
@@ -342,18 +340,18 @@ fn remove_many() {
 
     {
         dom.mark_dirty(ScopeId::ROOT);
-        let edits = dom.render_immediate().santize();
+        let edits = dom.render_immediate_to_vec().santize();
         assert_eq!(
             edits.edits,
             [
                 LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
-                HydrateText { path: &[0,], value: "hello 1", id: ElementId(4,) },
+                HydrateText { path: &[0,], value: "hello 1".to_string(), id: ElementId(4,) },
                 LoadTemplate { name: "template", index: 0, id: ElementId(5,) },
-                HydrateText { path: &[0,], value: "hello 2", id: ElementId(6,) },
+                HydrateText { path: &[0,], value: "hello 2".to_string(), id: ElementId(6,) },
                 LoadTemplate { name: "template", index: 0, id: ElementId(7,) },
-                HydrateText { path: &[0,], value: "hello 3", id: ElementId(8,) },
+                HydrateText { path: &[0,], value: "hello 3".to_string(), id: ElementId(8,) },
                 LoadTemplate { name: "template", index: 0, id: ElementId(9,) },
-                HydrateText { path: &[0,], value: "hello 4", id: ElementId(10,) },
+                HydrateText { path: &[0,], value: "hello 4".to_string(), id: ElementId(10,) },
                 InsertAfter { id: ElementId(2,), m: 4 },
             ]
         );
@@ -361,7 +359,7 @@ fn remove_many() {
 
     {
         dom.mark_dirty(ScopeId::ROOT);
-        let edits = dom.render_immediate().santize();
+        let edits = dom.render_immediate_to_vec().santize();
         assert_eq!(
             edits.edits,
             [
@@ -377,12 +375,12 @@ fn remove_many() {
 
     {
         dom.mark_dirty(ScopeId::ROOT);
-        let edits = dom.render_immediate().santize();
+        let edits = dom.render_immediate_to_vec().santize();
         assert_eq!(
             edits.edits,
             [
                 LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
-                HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
+                HydrateText { path: &[0,], value: "hello 0".to_string(), id: ElementId(3,) },
                 ReplaceWith { id: ElementId(11,), m: 1 },
             ]
         )

+ 4 - 6
packages/core/tests/error_boundary.rs

@@ -5,18 +5,18 @@ use dioxus::prelude::*;
 #[test]
 fn catches_panic() {
     let mut dom = VirtualDom::new(app);
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 }
 
 fn app(cx: Scope) -> Element {
-    cx.render(rsx! {
+    render! {
         div {
             h1 { "Title" }
 
             NoneChild {}
             ThrowChild {}
         }
-    })
+    }
 }
 
 fn NoneChild(_cx: Scope) -> Element {
@@ -28,7 +28,5 @@ fn ThrowChild(cx: Scope) -> Element {
 
     let _g: i32 = "123123".parse().throw()?;
 
-    cx.render(rsx! {
-        div {}
-    })
+    render! { div {} }
 }

+ 3 - 3
packages/core/tests/event_propagation.rs

@@ -9,7 +9,7 @@ fn events_propagate() {
     set_event_converter(Box::new(dioxus_html::SerializedHtmlEventConverter));
 
     let mut dom = VirtualDom::new(app);
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     // Top-level click is registered
     dom.handle_event(
@@ -23,7 +23,7 @@ fn events_propagate() {
     // break reference....
     for _ in 0..5 {
         dom.mark_dirty(ScopeId(0));
-        _ = dom.render_immediate();
+        _ = dom.render_immediate_to_vec();
     }
 
     // Lower click is registered
@@ -38,7 +38,7 @@ fn events_propagate() {
     // break reference....
     for _ in 0..5 {
         dom.mark_dirty(ScopeId(0));
-        _ = dom.render_immediate();
+        _ = dom.render_immediate_to_vec();
     }
 
     // Stop propagation occurs

+ 3 - 3
packages/core/tests/fuzzing.rs

@@ -311,7 +311,7 @@ fn create() {
     for _ in 0..repeat_count {
         let mut vdom =
             VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
-        let _ = vdom.rebuild();
+        let _ = vdom.rebuild_to_vec();
     }
 }
 
@@ -323,7 +323,7 @@ fn diff() {
     for _ in 0..repeat_count {
         let mut vdom =
             VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
-        let _ = vdom.rebuild();
+        let _ = vdom.rebuild_to_vec();
         // A list of all elements that have had event listeners
         // This is intentionally never cleared, so that we can test that calling event listeners that are removed doesn't cause a panic
         let mut event_listeners = HashSet::new();
@@ -338,7 +338,7 @@ fn diff() {
                 );
             }
             {
-                let muts = vdom.render_immediate();
+                let muts = vdom.render_immediate_to_vec();
                 for mut_ in muts.edits {
                     if let Mutation::NewEventListener { name, id } = mut_ {
                         println!("new event listener on {:?} for {:?}", id, name);

+ 15 - 13
packages/core/tests/kitchen_sink.rs

@@ -6,32 +6,34 @@ fn basic_syntax_is_a_template(cx: Scope) -> Element {
     let asd = 123;
     let var = 123;
 
-    cx.render(rsx! {
-        div { key: "12345",
-            class: "asd",
-            class: "{asd}",
-            class: if true { "{asd}" },
-            class: if false { "{asd}" },
-            onclick: move |_| {},
+    render! {
+        div { key: "12345", class: "asd", class: "{asd}", class: if true {
+                "{asd}"
+            }, class: if false {
+                "{asd}"
+            }, onclick: move |_| {},
             div { "{var}" }
             div {
                 h1 { "var" }
                 p { "you're great!" }
                 div { background_color: "red",
                     h1 { "var" }
-                    div { b { "asd" } "not great" }
+                    div {
+                        b { "asd" }
+                        "not great"
+                    }
                 }
                 p { "you're great!" }
             }
         }
-    })
+    }
 }
 
 #[test]
 fn dual_stream() {
     let mut dom = VirtualDom::new(basic_syntax_is_a_template);
     let bump = Bump::new();
-    let edits = dom.rebuild().santize();
+    let edits = dom.rebuild_to_vec().santize();
 
     use Mutation::*;
     assert_eq!(edits.edits, {
@@ -39,12 +41,12 @@ fn dual_stream() {
             LoadTemplate { name: "template", index: 0, id: ElementId(1) },
             SetAttribute {
                 name: "class",
-                value: (&*bump.alloc("asd 123 123".into_value(&bump))).into(),
+                value: "asd 123 123".into_value(),
                 id: ElementId(1),
                 ns: None,
             },
-            NewEventListener { name: "click", id: ElementId(1) },
-            HydrateText { path: &[0, 0], value: "123", id: ElementId(2) },
+            NewEventListener { name: "click".to_string(), id: ElementId(1) },
+            HydrateText { path: &[0, 0], value: "123".to_string(), id: ElementId(2) },
             AppendChildren { id: ElementId(0), m: 1 },
         ]
     });

+ 12 - 12
packages/core/tests/lifecycle.rs

@@ -18,21 +18,21 @@ fn manual_diffing() {
 
     fn app(cx: Scope<AppProps>) -> Element {
         let val = cx.props.value.lock().unwrap();
-        cx.render(rsx! { div { "{val}" } })
+        render! { div { "{val}" } }
     };
 
     let value = Arc::new(Mutex::new("Hello"));
     let mut dom = VirtualDom::new_with_props(app, AppProps { value: value.clone() });
 
-    let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     *value.lock().unwrap() = "goodbye";
 
     assert_eq!(
-        dom.rebuild().santize().edits,
+        dom.rebuild_to_vec().santize().edits,
         [
             LoadTemplate { name: "template", index: 0, id: ElementId(3) },
-            HydrateText { path: &[0], value: "goodbye", id: ElementId(4) },
+            HydrateText { path: &[0], value: "goodbye".to_string(), id: ElementId(4) },
             AppendChildren { m: 1, id: ElementId(0) }
         ]
     );
@@ -45,18 +45,18 @@ fn events_generate() {
         let count = cx.use_hook(|| 0);
 
         match *count {
-            0 => cx.render(rsx! {
+            0 => render! {
                 div { onclick: move |_| *count += 1,
                     div { "nested" }
                     "Click me!"
                 }
-            }),
-            _ => cx.render(rsx!(())),
+            },
+            _ => render!(()),
         }
     };
 
     let mut dom = VirtualDom::new(app);
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     dom.handle_event(
         "click",
@@ -66,7 +66,7 @@ fn events_generate() {
     );
 
     dom.mark_dirty(ScopeId::ROOT);
-    let edits = dom.render_immediate();
+    let edits = dom.render_immediate_to_vec();
 
     assert_eq!(
         edits.edits,
@@ -83,7 +83,7 @@ fn events_generate() {
 //         let render_phase = cx.use_hook(|| 0);
 //         *render_phase += 1;
 
-//         cx.render(match *render_phase {
+//         match *render_phase {
 //             1 => rsx_without_templates!("Text0"),
 //             2 => rsx_without_templates!(div {}),
 //             3 => rsx_without_templates!("Text2"),
@@ -98,13 +98,13 @@ fn events_generate() {
 
 //     fn Child(cx: Scope) -> Element {
 //         println!("Running child");
-//         cx.render(rsx_without_templates! {
+//         render_without_templates! {
 //             h1 {}
 //         })
 //     }
 
 //     let mut dom = VirtualDom::new(app);
-//     let edits = dom.rebuild();
+//     let edits = dom.rebuild_to_vec();
 //     assert_eq!(
 //         edits.edits,
 //         [

+ 6 - 11
packages/core/tests/miri_full_app.rs

@@ -9,7 +9,7 @@ fn miri_rollover() {
     set_event_converter(Box::new(SerializedHtmlEventConverter));
     let mut dom = VirtualDom::new(App);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     for _ in 0..3 {
         dom.handle_event(
@@ -19,7 +19,7 @@ fn miri_rollover() {
             true,
         );
         dom.process_events();
-        _ = dom.render_immediate();
+        _ = dom.render_immediate_to_vec();
     }
 }
 
@@ -28,7 +28,7 @@ fn App(cx: Scope) -> Element {
     let mut idx = use_state(cx, || 0);
     let onhover = |_| println!("go!");
 
-    cx.render(rsx! {
+    render! {
         div {
             button {
                 onclick: move |_| {
@@ -39,20 +39,15 @@ fn App(cx: Scope) -> Element {
             }
             button { onclick: move |_| idx -= 1, "-" }
             ul {
-                (0..**idx).map(|i| rsx! {
+                (0..**idx).map(|i| render! {
                     ChildExample { i: i, onhover: onhover }
                 })
             }
         }
-    })
+    }
 }
 
 #[component]
 fn ChildExample<'a>(cx: Scope<'a>, i: i32, onhover: EventHandler<'a, MouseEvent>) -> Element {
-    cx.render(rsx! {
-        li {
-            onmouseover: move |e| onhover.call(e),
-            "{i}"
-        }
-    })
+    render! { li { onmouseover: move |e| onhover.call(e), "{i}" } }
 }

+ 27 - 37
packages/core/tests/miri_simple.rs

@@ -4,16 +4,14 @@ use dioxus::prelude::*;
 fn app_drops() {
     #[component]
     fn App(cx: Scope) -> Element {
-        cx.render(rsx! {
-            div {}
-        })
+        render! { div {} }
     }
 
     let mut dom = VirtualDom::new(App);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }
 
 #[test]
@@ -25,16 +23,14 @@ fn hooks_drop() {
         cx.use_hook(|| String::from("asd"));
         cx.use_hook(|| String::from("asd"));
 
-        cx.render(rsx! {
-            div {}
-        })
+        render! { div {} }
     }
 
     let mut dom = VirtualDom::new(App);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }
 
 #[test]
@@ -43,27 +39,23 @@ fn contexts_drop() {
     fn App(cx: Scope) -> Element {
         cx.provide_context(String::from("asd"));
 
-        cx.render(rsx! {
-            div {
-                ChildComp {}
-            }
-        })
+        render! {
+            div { ChildComp {} }
+        }
     }
 
     #[component]
     fn ChildComp(cx: Scope) -> Element {
         let el = cx.consume_context::<String>().unwrap();
 
-        cx.render(rsx! {
-            div { "hello {el}" }
-        })
+        render! { div { "hello {el}" } }
     }
 
     let mut dom = VirtualDom::new(App);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }
 
 #[test]
@@ -74,16 +66,14 @@ fn tasks_drop() {
             // tokio::time::sleep(std::time::Duration::from_millis(100000)).await;
         });
 
-        cx.render(rsx! {
-            div { }
-        })
+        render! { div {} }
     }
 
     let mut dom = VirtualDom::new(App);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }
 
 #[test]
@@ -91,43 +81,43 @@ fn root_props_drop() {
     struct RootProps(String);
 
     let mut dom = VirtualDom::new_with_props(
-        |cx| cx.render(rsx!( div { "{cx.props.0}"  } )),
+        |cx| render!( div { "{cx.props.0}" } ),
         RootProps("asdasd".to_string()),
     );
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     dom.mark_dirty(ScopeId::ROOT);
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }
 
 #[test]
 fn diffing_drops_old() {
     #[component]
     fn App(cx: Scope) -> Element {
-        cx.render(rsx! {
+        render! {
             div {
-                match cx.generation() % 2 {
-                    0 => rsx!( ChildComp1 { name: "asdasd".to_string() }),
-                    1 => rsx!( ChildComp2 { name: "asdasd".to_string() }),
+                match generation() % 2 {
+                    0 => render!( ChildComp1 { name: "asdasd".to_string() }),
+                    1 => render!( ChildComp2 { name: "asdasd".to_string() }),
                     _ => todo!()
                 }
             }
-        })
+        }
     }
 
     #[component]
     fn ChildComp1(cx: Scope, name: String) -> Element {
-        cx.render(rsx! { "Hello {name}" })
+        render! {"Hello {name}"}
     }
 
     #[component]
     fn ChildComp2(cx: Scope, name: String) -> Element {
-        cx.render(rsx! { "Goodbye {name}"  })
+        render! {"Goodbye {name}"}
     }
 
     let mut dom = VirtualDom::new(App);
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     dom.mark_dirty(ScopeId::ROOT);
 
-    _ = dom.render_immediate();
+    _ = dom.render_immediate_to_vec();
 }

+ 26 - 46
packages/core/tests/miri_stress.rs

@@ -10,19 +10,19 @@ use dioxus::prelude::*;
 #[test]
 fn test_memory_leak() {
     fn app(cx: Scope) -> Element {
-        let val = cx.generation();
+        let val = generation();
 
         cx.spawn(async {});
 
         if val == 2 || val == 4 {
-            return cx.render(rsx!(()));
+            return render!(());
         }
 
         let name = cx.use_hook(|| String::from("numbers: "));
 
         name.push_str("123 ");
 
-        cx.render(rsx!(
+        render!(
             div { "Hello, world!" }
             Child {}
             Child {}
@@ -35,7 +35,7 @@ fn test_memory_leak() {
             BorrowedChild { name: name }
             BorrowedChild { name: name }
             BorrowedChild { name: name }
-        ))
+        )
     }
 
     #[derive(Props)]
@@ -44,44 +44,44 @@ fn test_memory_leak() {
     }
 
     fn BorrowedChild<'a>(cx: Scope<'a, BorrowedProps<'a>>) -> Element {
-        cx.render(rsx! {
+        render! {
             div {
                 "goodbye {cx.props.name}"
                 Child {}
                 Child {}
             }
-        })
+        }
     }
 
     fn Child(cx: Scope) -> Element {
-        render!(div { "goodbye world" })
+        render!( div { "goodbye world" } )
     }
 
     let mut dom = VirtualDom::new(app);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     for _ in 0..5 {
         dom.mark_dirty(ScopeId::ROOT);
-        _ = dom.render_immediate();
+        _ = dom.render_immediate_to_vec();
     }
 }
 
 #[test]
 fn memo_works_properly() {
     fn app(cx: Scope) -> Element {
-        let val = cx.generation();
+        let val = generation();
 
         if val == 2 || val == 4 {
-            return cx.render(rsx!(()));
+            return render!(());
         }
 
         let name = cx.use_hook(|| String::from("asd"));
 
-        cx.render(rsx!(
+        render!(
             div { "Hello, world! {name}" }
             Child { na: "asdfg".to_string() }
-        ))
+        )
     }
 
     #[derive(PartialEq, Props)]
@@ -90,12 +90,12 @@ fn memo_works_properly() {
     }
 
     fn Child(cx: Scope<ChildProps>) -> Element {
-        render!(div { "goodbye world" })
+        render!( div { "goodbye world" } )
     }
 
     let mut dom = VirtualDom::new(app);
 
-    _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
     // todo!()
     // dom.hard_diff(ScopeId::ROOT);
     // dom.hard_diff(ScopeId::ROOT);
@@ -122,12 +122,12 @@ fn free_works_on_root_hooks() {
     }
 
     fn child_component(cx: Scope<AppProps>) -> Element {
-        render!(div { "{cx.props.inner}" })
+        render!( div { "{cx.props.inner}" } )
     }
 
     let ptr = Rc::new("asdasd".to_string());
     let mut dom = VirtualDom::new_with_props(app, AppProps { inner: ptr.clone() });
-    let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     // ptr gets cloned into props and then into the hook
     assert_eq!(Rc::strong_count(&ptr), 4);
@@ -166,35 +166,15 @@ fn supports_async() {
         let mid = colors[1];
         let small = colors[2];
 
-        cx.render(rsx! {
-            div {
-                background: "{big}",
-                height: "stretch",
-                width: "stretch",
-                padding: "50",
-                label {
-                    "hello",
+        render! {
+            div { background: "{big}", height: "stretch", width: "stretch", padding: "50",
+                label { "hello" }
+                div { background: "{mid}", height: "auto", width: "stretch", padding: "{padding}",
+                    label { "World" }
+                    div { background: "{small}", height: "auto", width: "stretch", padding: "20", label { "ddddddd" } }
                 }
-                div {
-                    background: "{mid}",
-                    height: "auto",
-                    width: "stretch",
-                    padding: "{padding}",
-                    label {
-                        "World",
-                    }
-                    div {
-                        background: "{small}",
-                        height: "auto",
-                        width: "stretch",
-                        padding: "20",
-                        label {
-                            "ddddddd",
-                        }
-                    }
-                },
             }
-        })
+        }
     }
 
     let rt = tokio::runtime::Builder::new_current_thread()
@@ -204,11 +184,11 @@ fn supports_async() {
 
     rt.block_on(async {
         let mut dom = VirtualDom::new(app);
-        let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+        let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
         for _ in 0..10 {
             dom.wait_for_work().await;
-            let _edits = dom.render_immediate();
+            let _edits = dom.render_immediate_to_vec();
         }
     });
 }

+ 1 - 1
packages/core/tests/safety.rs

@@ -2,7 +2,7 @@
 
 use dioxus::prelude::*;
 
-/// Ensure no issues with not calling rebuild
+/// Ensure no issues with not calling rebuild_to_vec
 #[test]
 fn root_node_isnt_null() {
     let dom = VirtualDom::new(|cx| render!("Hello world!"));

+ 3 - 3
packages/core/tests/suspense.rs

@@ -9,7 +9,7 @@ fn it_works() {
         .unwrap()
         .block_on(async {
             let mut dom = VirtualDom::new(app);
-            _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+            _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
             dom.wait_for_suspense().await;
             let out = dioxus_ssr::render(&dom);
 
@@ -20,12 +20,12 @@ fn it_works() {
 }
 
 fn app(cx: Scope) -> Element {
-    cx.render(rsx!(
+    render!(
         div {
             "Waiting for... "
             suspended_child {}
         }
-    ))
+    )
 }
 
 fn suspended_child(cx: Scope) -> Element {

+ 2 - 2
packages/core/tests/task.rs

@@ -25,12 +25,12 @@ async fn it_works() {
             });
         });
 
-        cx.render(rsx!(()))
+        render!(())
     }
 
     let mut dom = VirtualDom::new(app);
 
-    let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
+    let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
 
     tokio::select! {
         _ = dom.wait_for_work() => {}

+ 3 - 3
packages/native-core/src/utils/persistant_iterator.rs

@@ -300,7 +300,7 @@ fn persist_removes() {
     use dioxus::prelude::*;
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        let children = match cx.generation() % 2 {
+        let children = match generation() % 2 {
             0 => 3,
             1 => 2,
             _ => unreachable!(),
@@ -381,7 +381,7 @@ fn persist_instertions_before() {
     use dioxus::prelude::*;
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        let children = match cx.generation() % 2 {
+        let children = match generation() % 2 {
             0 => 3,
             1 => 2,
             _ => unreachable!(),
@@ -439,7 +439,7 @@ fn persist_instertions_after() {
     use dioxus::prelude::*;
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        let children = match cx.generation() % 2 {
+        let children = match generation() % 2 {
             0 => 3,
             1 => 2,
             _ => unreachable!(),

+ 1 - 1
packages/signals/tests/create.rs

@@ -56,7 +56,7 @@ fn deref_signal() {
 #[test]
 fn drop_signals() {
     let mut dom = VirtualDom::new(|cx| {
-        let generation = cx.generation();
+        let generation = generation();
 
         let count = if generation % 2 == 0 { 10 } else { 0 };
         render! {

+ 3 - 3
packages/signals/tests/selector.rs

@@ -65,10 +65,10 @@ fn memos_prevents_component_rerun() {
         |cx| {
             let mut signal = use_signal(cx, || 0);
 
-            if cx.generation() == 1 {
+            if generation() == 1 {
                 *signal.write() = 0;
             }
-            if cx.generation() == 2 {
+            if generation() == 2 {
                 println!("Writing to signal");
                 *signal.write() = 1;
             }
@@ -108,7 +108,7 @@ fn memos_prevents_component_rerun() {
                 signal.value()
             })
         });
-        match cx.generation() {
+        match generation() {
             0 => {
                 assert_eq!(memo.value(), 0);
             }

+ 1 - 1
packages/signals/tests/subscribe.rs

@@ -22,7 +22,7 @@ fn reading_subscribes() {
             let mut signal = use_signal(cx, || 0);
 
             println!("Parent: {:?}", cx.scope_id());
-            if cx.generation() == 1 {
+            if generation() == 1 {
                 signal += 1;
             }