use std::marker::PhantomData; // FIXME: remove this and use std::ptr::NonNull when Firefox requires Rust 1.25+ pub struct NonZeroPtr(&'static T); impl NonZeroPtr { pub unsafe fn new_unchecked(ptr: *mut T) -> Self { NonZeroPtr(&*ptr) } pub fn as_ptr(&self) -> *mut T { self.0 as *const T as *mut T } } pub struct Unique { ptr: NonZeroPtr, _marker: PhantomData, } impl Unique { pub unsafe fn new_unchecked(ptr: *mut T) -> Self { Unique { ptr: NonZeroPtr::new_unchecked(ptr), _marker: PhantomData, } } pub fn as_ptr(&self) -> *mut T { self.ptr.as_ptr() } } unsafe impl Send for Unique {} unsafe impl Sync for Unique {} pub struct Shared { ptr: NonZeroPtr, _marker: PhantomData, // force it to be !Send/!Sync _marker2: PhantomData<*const u8>, } impl Shared { pub unsafe fn new_unchecked(ptr: *mut T) -> Self { Shared { ptr: NonZeroPtr::new_unchecked(ptr), _marker: PhantomData, _marker2: PhantomData, } } pub unsafe fn as_mut(&self) -> &mut T { &mut *self.ptr.as_ptr() } } impl<'a, T> From<&'a mut T> for Shared { fn from(reference: &'a mut T) -> Self { unsafe { Shared::new_unchecked(reference) } } }