From 35cdd195130be61fae88c6ba952364038c313903 Mon Sep 17 00:00:00 2001
From: Lukas Markeffsky <@>
Date: Wed, 31 Jan 2024 23:54:22 +0100
Subject: [PATCH] write root target backref only once

---
 src/lib.rs | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 94d7a35..46b9828 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,7 +5,7 @@ use core::marker::PhantomPinned;
 use core::mem::{self, MaybeUninit};
 use core::ops::{Deref, DerefMut};
 use core::pin::Pin;
-use core::ptr::NonNull;
+use core::ptr::{self, NonNull};
 
 pub trait Reclaim: Sized {
     fn reclaim(self, unclaimed: Unclaimed<Self>);
@@ -80,7 +80,15 @@ impl<T> Root<T> {
             panic!("unclaimed called multiple times");
         }
         self.state.set(STATE_UNCLAIMED);
+
         let ptr = unsafe { NonNull::from(self.get_unchecked_mut()) };
+        let ptr_erased = ptr.cast::<Root<Erased>>();
+
+        unsafe {
+            let target_root = ptr::addr_of_mut!((*(*ptr.as_ptr()).target.as_mut_ptr()).root);
+            target_root.write(Cell::new(Some(ptr_erased)));
+        }
+
         Unclaimed { ptr }
     }
 }
@@ -126,20 +134,18 @@ pub struct Unclaimed<T> {
 
 impl<T> Unclaimed<T> {
     pub fn claim(self, value: T) -> Xrc<T> {
-        let root_erased = self.ptr.cast::<Root<Erased>>();
-        let target = unsafe {
-            (*self.ptr.as_ptr()).target.write(ProjectTarget {
-                root: Cell::new(Some(root_erased)),
-                value,
-            })
-        };
-
         unsafe {
             (*self.ptr.as_ptr()).state.set(STATE_SHARED_INIT);
         }
 
-        // shared reborrow
-        let ptr = NonNull::from(&*target);
+        unsafe {
+            let target_value = ptr::addr_of_mut!((*(*self.ptr.as_ptr()).target.as_mut_ptr()).value);
+            target_value.write(value);
+        }
+
+        // shared read-only reborrow
+        let target = unsafe { (*self.ptr.as_ptr()).target.assume_init_ref() };
+        let ptr = NonNull::from(target);
         Xrc { ptr }
     }
 }
-- 
GitLab