Skip to main content

relibc/
raw_cell.rs

1use core::cell::UnsafeCell;
2
3/// Wrapper over `UnsafeCell` that can directly be used in statics, where all modifications require
4/// unsafe.
5#[repr(transparent)]
6pub struct RawCell<T> {
7    inner: UnsafeCell<T>,
8}
9impl<T> RawCell<T> {
10    #[inline]
11    pub const fn new(t: T) -> Self {
12        Self {
13            inner: UnsafeCell::new(t),
14        }
15    }
16    #[inline]
17    pub fn as_mut_ptr(&self) -> *mut T {
18        self.inner.get()
19    }
20    #[inline]
21    pub fn get_mut(&mut self) -> &mut T {
22        self.inner.get_mut()
23    }
24    #[inline]
25    pub fn into_inner(self) -> T {
26        self.inner.into_inner()
27    }
28    #[inline]
29    pub unsafe fn unsafe_ref(&self) -> &T {
30        unsafe { &*self.inner.get() }
31    }
32    #[inline]
33    pub unsafe fn unsafe_set(&self, t: T) {
34        unsafe { *self.inner.get() = t };
35    }
36    #[inline]
37    pub unsafe fn unsafe_mut(&self) -> &mut T {
38        unsafe { &mut *self.inner.get() }
39    }
40}
41
42// SAFETY: Sync requires that no safe interface be allowed to act on &self in a way that is
43// undefined behavior when accessed concurrently. The interface above only allows get, set, and
44// as_mut_ptr, where the former two that access memory are unsafe anyway.
45unsafe impl<T> Sync for RawCell<T> {}
46
47const _: () = {
48    // Check that RawCell works for non-Sync types.
49    static X: RawCell<*mut ()> = RawCell::new(core::ptr::null_mut());
50};