瀏覽代碼

use raw pointers instead of transmute to make miri happy

Evan Almloff 1 年之前
父節點
當前提交
cfc6887e34
共有 4 個文件被更改,包括 11 次插入9 次删除
  1. 6 4
      packages/core/src/arena.rs
  2. 2 2
      packages/core/src/create.rs
  3. 1 1
      packages/core/src/diff.rs
  4. 2 2
      packages/core/src/virtual_dom.rs

+ 6 - 4
packages/core/src/arena.rs

@@ -25,7 +25,7 @@ pub struct ElementRef<'a> {
     pub(crate) path: ElementPath,
 
     // The actual template
-    pub(crate) template: &'a VNode<'a>,
+    pub(crate) template: *const VNode<'a>,
 
     // The scope the element belongs to
     pub(crate) scope: ScopeId,
@@ -61,7 +61,10 @@ impl VirtualDom {
             );
         }
 
-        self.elements.try_remove(el.0).map(|_| ())
+        self.elements.try_remove(el.0).and_then(|id| match id {
+            Some(id) => self.element_refs.try_remove(id.0).map(|_| ()),
+            None => Some(()),
+        })
     }
 
     pub(crate) fn set_template(&mut self, el: ElementId, element_ref: ElementRef) {
@@ -80,8 +83,7 @@ impl VirtualDom {
         self.update_template_bubble(bubble_id, node)
     }
 
-    pub(crate) fn update_template_bubble(&mut self, bubble_id: BubbleId, node: &VNode) {
-        let node: *const VNode = node as *const _;
+    pub(crate) fn update_template_bubble(&mut self, bubble_id: BubbleId, node: *const VNode) {
         self.element_refs[bubble_id.0].template = unsafe { std::mem::transmute(node) };
     }
 

+ 2 - 2
packages/core/src/create.rs

@@ -187,7 +187,7 @@ impl<'b> VirtualDom {
                     path: ElementPath {
                         path: &template.template.get().node_paths[idx],
                     },
-                    template: &template,
+                    template: template,
                     scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
                 };
                 self.create_dynamic_node(template_ref, node)
@@ -197,7 +197,7 @@ impl<'b> VirtualDom {
                     path: ElementPath {
                         path: &template.template.get().node_paths[idx],
                     },
-                    template: &template,
+                    template: template,
                     scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
                 };
                 parent.set(Some(self.next_element_ref(template_ref)));

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

@@ -144,7 +144,7 @@ impl<'b> VirtualDom {
             .enumerate()
             .for_each(|(dyn_node_idx, (left_node, right_node))| {
                 let current_ref = ElementRef {
-                    template: right_template.into(),
+                    template: right_template,
                     path: ElementPath {
                         path: left_template.template.get().node_paths[dyn_node_idx],
                     },

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

@@ -371,7 +371,7 @@ impl VirtualDom {
             // Loop through each dynamic attribute (in a depth first order) in this template before moving up to the template's parent.
             while let Some(el_ref) = parent_path {
                 // safety: we maintain references of all vnodes in the element slab
-                let template = el_ref.template;
+                let template = unsafe { &*el_ref.template };
                 let node_template = template.template.get();
                 let target_path = el_ref.path;
 
@@ -421,7 +421,7 @@ impl VirtualDom {
             // Otherwise, we just call the listener on the target element
             if let Some(el_ref) = parent_path {
                 // safety: we maintain references of all vnodes in the element slab
-                let template = el_ref.template;
+                let template = unsafe { &*el_ref.template };
                 let node_template = template.template.get();
                 let target_path = el_ref.path;