Skip to content

Commit 1e3cf6e

Browse files
committed
sync: arc: Implement write() and assume_init() for UniqueArc
Implementation of write() and assume_init() method for UniqueArc, write() is for proper initialization for UniqueArc, assume_init() can check whether the instance is properly initialized or not, UB should be triggered immediately if it isn't, however, for the current implementation, the compiler won't complain. Fix it in the future iteration. Signed-off-by: I Hsin Cheng <richard120310@gmail.com>
1 parent 89377d7 commit 1e3cf6e

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

sync/src/arc/arc.rs

+38
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,30 @@ impl<T> UniqueArc<T> {
3939
}
4040
}
4141

42+
impl<T> UniqueArc<MaybeUninit<T>> {
43+
/// Converts a `UniqueArc<MaybeUninit<T>>` into a `UniqueArc<T>` by writing a value into it.
44+
#[allow(dead_code)]
45+
pub fn write(mut self, value: T) -> UniqueArc<T> {
46+
Arc::get_mut(&mut self.inner).unwrap().write(value);
47+
// SAFETY: We just wrote the value to be initialised.
48+
unsafe { self.assume_init() }
49+
}
50+
51+
/// Unsafely assume that `self` is initialized.
52+
///
53+
/// # Safety
54+
///
55+
/// The caller guarantees that the value behind this pointer has been initialized. It is
56+
/// *immediate* UB to call this when the value is not initialized.
57+
#[allow(dead_code)]
58+
pub unsafe fn assume_init(self) -> UniqueArc<T> {
59+
let inner = unsafe { self.inner.assume_init() };
60+
UniqueArc {
61+
inner: Arc::from_raw(Arc::into_raw(inner) as *const T),
62+
}
63+
}
64+
}
65+
4266
impl<T: ?Sized> Deref for UniqueArc<T> {
4367
type Target = T;
4468

@@ -119,6 +143,20 @@ mod tests {
119143
let x = UniqueArc::<MockData>::new_uninit().unwrap();
120144
assert_eq!(Arc::strong_count(&x.inner), 1);
121145
}
146+
147+
// FIXME : assume_init() doesn't triggered the UB even if the value isn't initialized
148+
// explicitly.
149+
#[test]
150+
fn test_unique_arc_write() {
151+
struct MockData {
152+
a: u32,
153+
}
154+
155+
let x = unsafe { UniqueArc::<MockData>::new_uninit().unwrap() };
156+
let y = x.write(MockData{a: 10});
157+
158+
assert_eq!(y.a, 10);
159+
}
122160
}
123161

124162

0 commit comments

Comments
 (0)