diff --git a/src/lib.rs b/src/lib.rs
index 94d7a3580f3d9ce66aea183773d4b646d9b15ca7..46b9828c185d081a60cb0d45a29d713a2e1fb868 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 }
     }
 }