Browse Source

handle height

Evan Almloff 2 years ago
parent
commit
f9059c3f30

+ 0 - 2
packages/native-core/src/node.rs

@@ -21,7 +21,6 @@ pub struct NodeData {
     pub node_type: NodeType,
     /// The number of parents before the root node. The root node has height 1.
     pub height: u16,
-    height_dirty: bool,
 }
 
 /// A type of node with data specific to the node type. The types are a subset of the [VNode] types.
@@ -48,7 +47,6 @@ impl<S: State> Node<S> {
                 node_type,
                 height: 0,
                 node_id: NodeId(0),
-                height_dirty: true,
             },
         }
     }

+ 71 - 47
packages/native-core/src/real_dom.rs

@@ -1,7 +1,7 @@
 use anymap::AnyMap;
 use dioxus_core::{ElementId, Mutations};
 use rustc_hash::{FxHashMap, FxHashSet};
-use std::ops::{Deref, DerefMut, Index, IndexMut};
+use std::ops::{Index, IndexMut};
 
 use crate::node::{Node, NodeData, NodeType, OwnedAttributeDiscription};
 use crate::node_ref::{AttributeMask, NodeMask};
@@ -9,6 +9,18 @@ use crate::state::State;
 use crate::tree::{NodeId, Tree, TreeLike, TreeView};
 use crate::RealNodeId;
 
+fn mark_dirty(
+    node_id: NodeId,
+    mask: NodeMask,
+    nodes_updated: &mut FxHashMap<RealNodeId, NodeMask>,
+) {
+    if let Some(node) = nodes_updated.get_mut(&node_id) {
+        *node = node.union(&mask);
+    } else {
+        nodes_updated.insert(node_id, mask);
+    }
+}
+
 /// A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
 /// The render state passes from parent to children and or accumulates state from children to parents.
 /// To get started implement [crate::state::ParentDepState], [crate::state::NodeDepState], or [crate::state::ChildDepState] and call [RealDom::apply_mutations] to update the dom and [RealDom::update_state] to update the state of the nodes.
@@ -79,12 +91,31 @@ impl<S: State> RealDom<S> {
         node_id
     }
 
+    fn add_child(&mut self, node_id: RealNodeId, child_id: RealNodeId) {
+        self.tree.add_child(node_id, child_id);
+        self.resolve_height(child_id);
+    }
+
+    fn resolve_height(&mut self, node_id: RealNodeId) {
+        if let Some((node, parent)) = self.tree.node_parent_mut(node_id) {
+            let height = parent.node_data.height;
+            node.node_data.height = height + 1;
+            unsafe {
+                let self_mut = self as *mut Self;
+                // Safety: No node will have itself as a child
+                for child in self.tree.children_ids(node_id).unwrap() {
+                    (*self_mut).resolve_height(*child);
+                }
+            }
+        }
+    }
+
     /// Updates the dom with some mutations and return a set of nodes that were updated. Pass the dirty nodes to update_state.
-    pub fn apply_mutations<'a>(
+    pub fn apply_mutations(
         &mut self,
-        mutations_vec: Vec<Mutations<'a>>,
-    ) -> Vec<(RealNodeId, NodeMask)> {
-        let mut nodes_updated: Vec<(RealNodeId, NodeMask)> = Vec::new();
+        mutations_vec: Vec<Mutations>,
+    ) -> FxHashMap<RealNodeId, NodeMask> {
+        let mut nodes_updated: FxHashMap<RealNodeId, NodeMask> = FxHashMap::default();
         for mutations in mutations_vec {
             for e in mutations.edits {
                 use dioxus_core::Mutation::*;
@@ -93,12 +124,12 @@ impl<S: State> RealDom<S> {
                         let data = self.stack.split_off(m);
                         let (parent, children) = data.split_first().unwrap();
                         for child in children {
-                            self.tree.add_child(*parent, *child);
-                            nodes_updated.push((*parent, NodeMask::ALL));
+                            self.add_child(*parent, *child);
+                            mark_dirty(*parent, NodeMask::ALL, &mut nodes_updated);
                         }
                     }
                     AssignId { path, id } => {
-                        self.set_element_id(self.load_child(&path), id);
+                        self.set_element_id(self.load_child(path), id);
                     }
                     CreateElement { name } => {
                         let node = Node::new(NodeType::Element {
@@ -109,7 +140,7 @@ impl<S: State> RealDom<S> {
                         });
                         let id = self.create_node(node);
                         self.stack.push(id);
-                        nodes_updated.push((id, NodeMask::ALL));
+                        mark_dirty(id, NodeMask::ALL, &mut nodes_updated);
                     }
                     CreateElementNamespace { name, namespace } => {
                         let node = Node::new(NodeType::Element {
@@ -120,20 +151,20 @@ impl<S: State> RealDom<S> {
                         });
                         let id = self.create_node(node);
                         self.stack.push(id);
-                        nodes_updated.push((id, NodeMask::ALL));
+                        mark_dirty(id, NodeMask::ALL, &mut nodes_updated);
                     }
                     CreatePlaceholder { id } => {
                         let node = Node::new(NodeType::Placeholder);
                         let node_id = self.create_node(node);
                         self.set_element_id(node_id, id);
                         self.stack.push(node_id);
-                        nodes_updated.push((node_id, NodeMask::ALL));
+                        mark_dirty(node_id, NodeMask::ALL, &mut nodes_updated);
                     }
                     CreateStaticPlaceholder => {
                         let node = Node::new(NodeType::Placeholder);
                         let id = self.create_node(node);
                         self.stack.push(id);
-                        nodes_updated.push((id, NodeMask::ALL));
+                        mark_dirty(id, NodeMask::ALL, &mut nodes_updated);
                     }
                     CreateStaticText { value } => {
                         let node = Node::new(NodeType::Text {
@@ -141,7 +172,7 @@ impl<S: State> RealDom<S> {
                         });
                         let id = self.create_node(node);
                         self.stack.push(id);
-                        nodes_updated.push((id, NodeMask::new().with_text()));
+                        mark_dirty(id, NodeMask::new().with_text(), &mut nodes_updated);
                     }
                     CreateTextNode { value, id } => {
                         let node = Node::new(NodeType::Text {
@@ -151,7 +182,7 @@ impl<S: State> RealDom<S> {
                         let node = self.tree.get_mut(node_id).unwrap();
                         node.node_data.element_id = Some(id);
                         self.stack.push(node_id);
-                        nodes_updated.push((node_id, NodeMask::new().with_text()));
+                        mark_dirty(node_id, NodeMask::new().with_text(), &mut nodes_updated);
                     }
                     HydrateText { path, value, id } => {
                         let node_id = self.load_child(path);
@@ -160,7 +191,7 @@ impl<S: State> RealDom<S> {
                         if let NodeType::Text { text } = &mut node.node_data.node_type {
                             *text = value.to_string();
                         }
-                        nodes_updated.push((node_id, NodeMask::new().with_text()));
+                        mark_dirty(node_id, NodeMask::new().with_text(), &mut nodes_updated);
                     }
                     LoadTemplate { name, index, id } => {
                         let template_id = self.templates[name][index];
@@ -172,7 +203,7 @@ impl<S: State> RealDom<S> {
                         let old_node_id = self.element_to_node_id(id);
                         for new in new_nodes {
                             self.tree.insert_after(old_node_id, new);
-                            nodes_updated.push((new, NodeMask::ALL));
+                            mark_dirty(new, NodeMask::ALL, &mut nodes_updated);
                         }
                         self.tree.remove(old_node_id);
                     }
@@ -181,7 +212,7 @@ impl<S: State> RealDom<S> {
                         let old_node_id = self.load_child(path);
                         for new in new_nodes {
                             self.tree.insert_after(old_node_id, new);
-                            nodes_updated.push((new, NodeMask::ALL));
+                            mark_dirty(new, NodeMask::ALL, &mut nodes_updated);
                         }
                         self.tree.remove(old_node_id);
                     }
@@ -190,7 +221,7 @@ impl<S: State> RealDom<S> {
                         let old_node_id = self.element_to_node_id(id);
                         for new in new_nodes {
                             self.tree.insert_after(old_node_id, new);
-                            nodes_updated.push((new, NodeMask::ALL));
+                            mark_dirty(new, NodeMask::ALL, &mut nodes_updated);
                         }
                     }
                     InsertBefore { id, m } => {
@@ -198,7 +229,7 @@ impl<S: State> RealDom<S> {
                         let old_node_id = self.element_to_node_id(id);
                         for new in new_nodes {
                             self.tree.insert_before(old_node_id, new);
-                            nodes_updated.push((new, NodeMask::ALL));
+                            mark_dirty(new, NodeMask::ALL, &mut nodes_updated);
                         }
                     }
                     SaveTemplate { name, m } => {
@@ -223,10 +254,11 @@ impl<S: State> RealDom<S> {
                                 },
                                 crate::node::OwnedAttributeValue::Text(value.to_string()),
                             );
-                            nodes_updated.push((
+                            mark_dirty(
                                 node_id,
                                 NodeMask::new_with_attrs(AttributeMask::single(name)),
-                            ));
+                                &mut nodes_updated,
+                            );
                         }
                     }
                     SetStaticAttribute { name, value, ns } => {
@@ -242,10 +274,11 @@ impl<S: State> RealDom<S> {
                                 },
                                 crate::node::OwnedAttributeValue::Text(value.to_string()),
                             );
-                            nodes_updated.push((
+                            mark_dirty(
                                 *node_id,
                                 NodeMask::new_with_attrs(AttributeMask::single(name)),
-                            ));
+                                &mut nodes_updated,
+                            );
                         }
                     }
                     SetBoolAttribute { name, value, id } => {
@@ -261,10 +294,11 @@ impl<S: State> RealDom<S> {
                                 },
                                 crate::node::OwnedAttributeValue::Bool(value),
                             );
-                            nodes_updated.push((
+                            mark_dirty(
                                 node_id,
                                 NodeMask::new_with_attrs(AttributeMask::single(name)),
-                            ));
+                                &mut nodes_updated,
+                            );
                         }
                     }
                     SetInnerText { value } => {
@@ -276,7 +310,7 @@ impl<S: State> RealDom<S> {
                                 text: value.to_string(),
                             });
                             let text_node_id = self.create_node(text_node);
-                            self.tree.add_child(node_id, text_node_id);
+                            self.add_child(node_id, text_node_id);
                         }
                     }
                     SetText { value, id } => {
@@ -285,7 +319,7 @@ impl<S: State> RealDom<S> {
                         if let NodeType::Text { text } = &mut node.node_data.node_type {
                             *text = value.to_string();
                         }
-                        nodes_updated.push((node_id, NodeMask::new().with_text()));
+                        mark_dirty(node_id, NodeMask::new().with_text(), &mut nodes_updated);
                     }
                     NewEventListener {
                         event_name,
@@ -321,14 +355,14 @@ impl<S: State> RealDom<S> {
                     }
                     Remove { id } => {
                         let node_id = self.element_to_node_id(id);
-                        self.remove(node_id);
+                        self.tree.remove(node_id);
                     }
                 }
             }
         }
 
         // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
-        nodes_updated.retain(|n| self.tree.get(n.0).is_some());
+        nodes_updated.retain(|k, _| self.tree.get(*k).is_some());
 
         nodes_updated
     }
@@ -336,7 +370,7 @@ impl<S: State> RealDom<S> {
     /// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
     pub fn update_state(
         &mut self,
-        nodes_updated: Vec<(RealNodeId, NodeMask)>,
+        nodes_updated: FxHashMap<RealNodeId, NodeMask>,
         ctx: AnyMap,
     ) -> FxHashSet<RealNodeId> {
         let (mut state_tree, node_tree) = self.split();
@@ -370,8 +404,12 @@ impl<S: State> RealDom<S> {
         let raw = self as *mut Self;
         // this is safe beacuse the treeview trait does not allow mutation of the position of elements, and within elements the access is disjoint.
         (
-            unsafe { &mut *raw }.map(|n| &n.state, |n| &mut n.state),
-            unsafe { &mut *raw }.map(|n| &n.node_data, |n| &mut n.node_data),
+            unsafe { &mut *raw }
+                .tree
+                .map(|n| &n.state, |n| &mut n.state),
+            unsafe { &mut *raw }
+                .tree
+                .map(|n| &n.node_data, |n| &mut n.node_data),
         )
     }
 
@@ -385,7 +423,7 @@ impl<S: State> RealDom<S> {
                 // this is safe because no node has itself as a child
                 let self_mut = &mut *self_ptr;
                 let child_id = self_mut.clone_node(*child);
-                self_mut.tree.add_child(new_id, child_id);
+                self_mut.add_child(new_id, child_id);
             }
         }
         new_id
@@ -419,17 +457,3 @@ impl<S: State> IndexMut<RealNodeId> for RealDom<S> {
         self.tree.get_mut(idx).unwrap()
     }
 }
-
-impl<S: State> Deref for RealDom<S> {
-    type Target = Tree<Node<S>>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.tree
-    }
-}
-
-impl<S: State> DerefMut for RealDom<S> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.tree
-    }
-}

+ 61 - 21
packages/native-core/src/state.rs

@@ -5,7 +5,7 @@ use crate::node_ref::{NodeMask, NodeView};
 use crate::tree::TreeView;
 use crate::RealNodeId;
 use anymap::AnyMap;
-use rustc_hash::FxHashSet;
+use rustc_hash::{FxHashMap, FxHashSet};
 
 /// Join two sorted iterators
 pub(crate) fn union_ordered_iter<'a>(
@@ -81,15 +81,15 @@ pub trait ChildDepState {
     /// The context is passed to the [ChildDepState::reduce] when it is resolved.
     type Ctx;
     /// A state from each child node that this node depends on. Typically this is Self, but it could be any state that is within the state tree.
-    /// This must be either a [ChildDepState], or [NodeDepState].
-    type DepState;
+    /// Depstate must be a tuple containing any number of borrowed elements that are either [ChildDepState] or [NodeDepState].
+    type DepState: ElementBorrowable;
     /// The part of a node that this state cares about. This is used to determine if the state should be updated when a node is updated.
     const NODE_MASK: NodeMask = NodeMask::NONE;
     /// Resolve the state current node's state from the state of the children, the state of the node, and some external context.
     fn reduce<'a>(
         &mut self,
         node: NodeView,
-        children: impl Iterator<Item = &'a Self::DepState>,
+        children: impl Iterator<Item = <Self::DepState as ElementBorrowable>::ElementBorrowed<'a>>,
         ctx: &Self::Ctx,
     ) -> bool
     where
@@ -143,15 +143,15 @@ pub trait ParentDepState {
     /// The context is passed to the [ParentDepState::reduce] when it is resolved.
     type Ctx;
     /// A state from from the parent node that this node depends on. Typically this is Self, but it could be any state that is within the state tree.
-    /// This must be either a [ParentDepState] or [NodeDepState]
-    type DepState;
+    /// Depstate must be a tuple containing any number of borrowed elements that are either [ParentDepState] or [NodeDepState].
+    type DepState: ElementBorrowable;
     /// The part of a node that this state cares about. This is used to determine if the state should be updated when a node is updated.
     const NODE_MASK: NodeMask = NodeMask::NONE;
     /// Resolve the state current node's state from the state of the parent node, the state of the node, and some external context.
     fn reduce<'a>(
         &mut self,
         node: NodeView,
-        parent: Option<&'a Self::DepState>,
+        parent: Option<<Self::DepState as ElementBorrowable>::ElementBorrowed<'a>>,
         ctx: &Self::Ctx,
     ) -> bool;
 }
@@ -193,23 +193,27 @@ pub trait ParentDepState {
 ///     }
 /// }
 /// ```
-/// The generic argument (Depstate) must be a tuple containing any number of borrowed elements that are either a [ChildDepState], [ParentDepState] or [NodeDepState].
-// Todo: once GATs land we can model multable dependencies better
-
-pub trait NodeDepState<DepState = ()> {
+pub trait NodeDepState {
+    /// Depstate must be a tuple containing any number of borrowed elements that are either [ChildDepState], [ParentDepState] or [NodeDepState].
+    type DepState: ElementBorrowable;
     /// The state passed to [NodeDepState::reduce] when it is resolved.
     type Ctx;
     /// The part of a node that this state cares about. This is used to determine if the state should be updated when a node is updated.
     const NODE_MASK: NodeMask = NodeMask::NONE;
     /// Resolve the state current node's state from the state of the sibling states, the state of the node, and some external context.
-    fn reduce(&mut self, node: NodeView, siblings: DepState, ctx: &Self::Ctx) -> bool;
+    fn reduce<'a>(
+        &mut self,
+        node: NodeView,
+        siblings: <Self::DepState as ElementBorrowable>::ElementBorrowed<'a>,
+        ctx: &Self::Ctx,
+    ) -> bool;
 }
 
 /// Do not implement this trait. It is only meant to be derived and used through [crate::real_dom::RealDom].
 pub trait State: Default + Clone {
     #[doc(hidden)]
     fn update<'a, T: TreeView<Self>, T2: TreeView<NodeData>>(
-        dirty: &[(RealNodeId, NodeMask)],
+        dirty: &FxHashMap<RealNodeId, NodeMask>,
         state_tree: &'a mut T,
         rdom: &'a T2,
         ctx: &AnyMap,
@@ -219,12 +223,7 @@ pub trait State: Default + Clone {
 impl ChildDepState for () {
     type Ctx = ();
     type DepState = ();
-    fn reduce<'a>(
-        &mut self,
-        _: NodeView,
-        _: impl Iterator<Item = &'a Self::DepState>,
-        _: &Self::Ctx,
-    ) -> bool
+    fn reduce<'a>(&mut self, _: NodeView, _: impl Iterator<Item = ()>, _: &Self::Ctx) -> bool
     where
         Self::DepState: 'a,
     {
@@ -235,14 +234,55 @@ impl ChildDepState for () {
 impl ParentDepState for () {
     type Ctx = ();
     type DepState = ();
-    fn reduce<'a>(&mut self, _: NodeView, _: Option<&'a Self::DepState>, _: &Self::Ctx) -> bool {
+    fn reduce<'a>(&mut self, _: NodeView, _: Option<()>, _: &Self::Ctx) -> bool {
         false
     }
 }
 
-impl NodeDepState<()> for () {
+impl NodeDepState for () {
+    type DepState = ();
     type Ctx = ();
     fn reduce(&mut self, _: NodeView, _sibling: (), _: &Self::Ctx) -> bool {
         false
     }
 }
+
+pub trait ElementBorrowable {
+    type ElementBorrowed<'a>
+    where
+        Self: 'a;
+
+    fn borrow_elements(&self) -> Self::ElementBorrowed<'_>;
+}
+
+macro_rules! impl_element_borrowable {
+    ($($t:ident),*) => {
+        impl< $($t),* > ElementBorrowable for ($($t,)*) {
+            type ElementBorrowed<'a> = ($(&'a $t,)*) where Self: 'a;
+
+            #[allow(clippy::unused_unit, non_snake_case)]
+            fn borrow_elements<'a>(&'a self) -> Self::ElementBorrowed<'a> {
+                let ($($t,)*) = self;
+                ($(&$t,)*)
+            }
+        }
+    };
+}
+
+impl_element_borrowable!();
+impl_element_borrowable!(A);
+impl_element_borrowable!(A, B);
+impl_element_borrowable!(A, B, C);
+impl_element_borrowable!(A, B, C, D);
+impl_element_borrowable!(A, B, C, D, E);
+impl_element_borrowable!(A, B, C, D, E, F);
+impl_element_borrowable!(A, B, C, D, E, F, G);
+impl_element_borrowable!(A, B, C, D, E, F, G, H);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J, K);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J, K, L);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J, K, L, M);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
+impl_element_borrowable!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);

+ 13 - 16
packages/native-core/src/tree.rs

@@ -72,14 +72,11 @@ pub trait TreeView<T>: Sized {
         unsafe { self.get_mut(id).unwrap_unchecked() }
     }
 
-    fn children<'a>(&'a self, id: NodeId) -> Option<Self::Iterator<'a>>;
+    fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>>;
 
-    fn children_mut<'a>(&'a mut self, id: NodeId) -> Option<Self::IteratorMut<'a>>;
+    fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>>;
 
-    fn parent_child_mut<'a>(
-        &'a mut self,
-        id: NodeId,
-    ) -> Option<(&'a mut T, Self::IteratorMut<'a>)> {
+    fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)> {
         let mut_ptr: *mut Self = self;
         unsafe {
             // Safety: No node has itself as a child.
@@ -91,7 +88,7 @@ pub trait TreeView<T>: Sized {
         }
     }
 
-    fn children_ids<'a>(&'a self, id: NodeId) -> Option<&'a [NodeId]>;
+    fn children_ids(&self, id: NodeId) -> Option<&[NodeId]>;
 
     fn parent(&self, id: NodeId) -> Option<&T>;
 
@@ -257,7 +254,7 @@ impl<T> TreeView<T> for Tree<T> {
         self.nodes.get_mut(id.0).map(|node| &mut node.value)
     }
 
-    fn children<'a>(&'a self, id: NodeId) -> Option<Self::Iterator<'a>> {
+    fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
         self.children_ids(id).map(|children_ids| ChildNodeIterator {
             tree: self,
             children_ids,
@@ -266,7 +263,7 @@ impl<T> TreeView<T> for Tree<T> {
         })
     }
 
-    fn children_mut<'a>(&'a mut self, id: NodeId) -> Option<Self::IteratorMut<'a>> {
+    fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
         let raw_ptr = self as *mut Self;
         unsafe {
             // Safety: No node will appear as a child twice
@@ -280,7 +277,7 @@ impl<T> TreeView<T> for Tree<T> {
         }
     }
 
-    fn children_ids<'a>(&'a self, id: NodeId) -> Option<&'a [NodeId]> {
+    fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
         self.nodes.get(id.0).map(|node| node.children.as_slice())
     }
 
@@ -462,7 +459,7 @@ where
         self.tree.get_mut(id).map(|node| (self.map_mut)(node))
     }
 
-    fn children<'b>(&'b self, id: NodeId) -> Option<Self::Iterator<'b>> {
+    fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
         self.children_ids(id).map(|children_ids| ChildNodeIterator {
             tree: self,
             children_ids,
@@ -471,7 +468,7 @@ where
         })
     }
 
-    fn children_mut<'b>(&'b mut self, id: NodeId) -> Option<Self::IteratorMut<'b>> {
+    fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
         let raw_ptr = self as *mut Self;
         unsafe {
             // Safety: No node can be a child twice.
@@ -485,7 +482,7 @@ where
         }
     }
 
-    fn children_ids<'b>(&'b self, id: NodeId) -> Option<&'b [NodeId]> {
+    fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
         self.tree.children_ids(id)
     }
 
@@ -609,15 +606,15 @@ impl<'a, T, Tr: TreeView<T>> TreeView<T> for SharedView<'a, T, Tr> {
         self.with_node(id, |t| t.get_mut(id))
     }
 
-    fn children<'b>(&'b self, id: NodeId) -> Option<Self::Iterator<'b>> {
+    fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
         self.with_node(id, |t| t.children(id))
     }
 
-    fn children_mut<'b>(&'b mut self, id: NodeId) -> Option<Self::IteratorMut<'b>> {
+    fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
         self.with_node(id, |t| t.children_mut(id))
     }
 
-    fn children_ids<'b>(&'b self, id: NodeId) -> Option<&'b [NodeId]> {
+    fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
         self.with_node(id, |t| t.children_ids(id))
     }
 

+ 1 - 0
packages/native-core/src/worker_pool.rs

@@ -0,0 +1 @@
+