181a89169SAlex Crichton use core::fmt;
281a89169SAlex Crichton use core::hash::{Hash, Hasher};
381a89169SAlex Crichton use core::ptr::{self, NonNull};
472004aadSNick Fitzgerald 
572004aadSNick Fitzgerald /// A helper type in Wasmtime to store a raw pointer to `T` while automatically
672004aadSNick Fitzgerald /// inferring the `Send` and `Sync` traits for the container based on the
772004aadSNick Fitzgerald /// properties of `T`.
872004aadSNick Fitzgerald #[repr(transparent)]
972004aadSNick Fitzgerald pub struct SendSyncPtr<T: ?Sized>(NonNull<T>);
1072004aadSNick Fitzgerald 
1172004aadSNick Fitzgerald unsafe impl<T: Send + ?Sized> Send for SendSyncPtr<T> {}
1272004aadSNick Fitzgerald unsafe impl<T: Sync + ?Sized> Sync for SendSyncPtr<T> {}
1372004aadSNick Fitzgerald 
1472004aadSNick Fitzgerald impl<T: ?Sized> SendSyncPtr<T> {
1572004aadSNick Fitzgerald     /// Creates a new pointer wrapping the non-nullable pointer provided.
1672004aadSNick Fitzgerald     #[inline]
new(ptr: NonNull<T>) -> SendSyncPtr<T>1772004aadSNick Fitzgerald     pub fn new(ptr: NonNull<T>) -> SendSyncPtr<T> {
1872004aadSNick Fitzgerald         SendSyncPtr(ptr)
1972004aadSNick Fitzgerald     }
2072004aadSNick Fitzgerald 
2172004aadSNick Fitzgerald     /// Returns the underlying raw pointer.
2272004aadSNick Fitzgerald     #[inline]
as_ptr(&self) -> *mut T2372004aadSNick Fitzgerald     pub fn as_ptr(&self) -> *mut T {
2472004aadSNick Fitzgerald         self.0.as_ptr()
2572004aadSNick Fitzgerald     }
2672004aadSNick Fitzgerald 
2772004aadSNick Fitzgerald     /// Unsafely assert that this is a pointer to valid contents and it's also
2872004aadSNick Fitzgerald     /// valid to get a shared reference to it at this time.
2972004aadSNick Fitzgerald     #[inline]
as_ref<'a>(&self) -> &'a T3072004aadSNick Fitzgerald     pub unsafe fn as_ref<'a>(&self) -> &'a T {
31*35786823SAlex Crichton         unsafe { self.0.as_ref() }
3272004aadSNick Fitzgerald     }
3372004aadSNick Fitzgerald 
3472004aadSNick Fitzgerald     /// Unsafely assert that this is a pointer to valid contents and it's also
3572004aadSNick Fitzgerald     /// valid to get a mutable reference to it at this time.
3672004aadSNick Fitzgerald     #[inline]
as_mut<'a>(&mut self) -> &'a mut T3772004aadSNick Fitzgerald     pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
38*35786823SAlex Crichton         unsafe { self.0.as_mut() }
3972004aadSNick Fitzgerald     }
4072004aadSNick Fitzgerald 
4172004aadSNick Fitzgerald     /// Returns the underlying `NonNull<T>` wrapper.
4272004aadSNick Fitzgerald     #[inline]
as_non_null(&self) -> NonNull<T>4372004aadSNick Fitzgerald     pub fn as_non_null(&self) -> NonNull<T> {
4472004aadSNick Fitzgerald         self.0
4572004aadSNick Fitzgerald     }
4672004aadSNick Fitzgerald 
4772004aadSNick Fitzgerald     /// Cast this to a pointer to a `U`.
4872004aadSNick Fitzgerald     #[inline]
cast<U>(&self) -> SendSyncPtr<U>4972004aadSNick Fitzgerald     pub fn cast<U>(&self) -> SendSyncPtr<U> {
5072004aadSNick Fitzgerald         SendSyncPtr(self.0.cast::<U>())
5172004aadSNick Fitzgerald     }
5272004aadSNick Fitzgerald }
5372004aadSNick Fitzgerald 
5472004aadSNick Fitzgerald impl<T> SendSyncPtr<[T]> {
5572004aadSNick Fitzgerald     /// Returns the slice's length component of the pointer.
5672004aadSNick Fitzgerald     #[inline]
len(&self) -> usize5772004aadSNick Fitzgerald     pub fn len(&self) -> usize {
5872004aadSNick Fitzgerald         self.0.len()
5972004aadSNick Fitzgerald     }
6072004aadSNick Fitzgerald }
6172004aadSNick Fitzgerald 
6272004aadSNick Fitzgerald impl<T: ?Sized, U> From<U> for SendSyncPtr<T>
6372004aadSNick Fitzgerald where
6472004aadSNick Fitzgerald     U: Into<NonNull<T>>,
6572004aadSNick Fitzgerald {
6672004aadSNick Fitzgerald     #[inline]
from(ptr: U) -> SendSyncPtr<T>6772004aadSNick Fitzgerald     fn from(ptr: U) -> SendSyncPtr<T> {
6872004aadSNick Fitzgerald         SendSyncPtr::new(ptr.into())
6972004aadSNick Fitzgerald     }
7072004aadSNick Fitzgerald }
7172004aadSNick Fitzgerald 
7272004aadSNick Fitzgerald impl<T: ?Sized> fmt::Debug for SendSyncPtr<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result7372004aadSNick Fitzgerald     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7472004aadSNick Fitzgerald         self.as_ptr().fmt(f)
7572004aadSNick Fitzgerald     }
7672004aadSNick Fitzgerald }
7772004aadSNick Fitzgerald 
7872004aadSNick Fitzgerald impl<T: ?Sized> fmt::Pointer for SendSyncPtr<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result7972004aadSNick Fitzgerald     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8072004aadSNick Fitzgerald         self.as_ptr().fmt(f)
8172004aadSNick Fitzgerald     }
8272004aadSNick Fitzgerald }
8372004aadSNick Fitzgerald 
8472004aadSNick Fitzgerald impl<T: ?Sized> Clone for SendSyncPtr<T> {
8572004aadSNick Fitzgerald     #[inline]
clone(&self) -> Self8672004aadSNick Fitzgerald     fn clone(&self) -> Self {
8772004aadSNick Fitzgerald         *self
8872004aadSNick Fitzgerald     }
8972004aadSNick Fitzgerald }
9072004aadSNick Fitzgerald 
9172004aadSNick Fitzgerald impl<T: ?Sized> Copy for SendSyncPtr<T> {}
9272004aadSNick Fitzgerald 
9372004aadSNick Fitzgerald impl<T: ?Sized> PartialEq for SendSyncPtr<T> {
9472004aadSNick Fitzgerald     #[inline]
eq(&self, other: &SendSyncPtr<T>) -> bool9572004aadSNick Fitzgerald     fn eq(&self, other: &SendSyncPtr<T>) -> bool {
9681a89169SAlex Crichton         ptr::eq(self.0.as_ptr(), other.0.as_ptr())
9772004aadSNick Fitzgerald     }
9872004aadSNick Fitzgerald }
9972004aadSNick Fitzgerald 
10072004aadSNick Fitzgerald impl<T: ?Sized> Eq for SendSyncPtr<T> {}
10172004aadSNick Fitzgerald 
10272004aadSNick Fitzgerald impl<T: ?Sized> Hash for SendSyncPtr<T> {
hash<H: Hasher>(&self, state: &mut H)10381a89169SAlex Crichton     fn hash<H: Hasher>(&self, state: &mut H) {
10472004aadSNick Fitzgerald         self.as_ptr().hash(state);
10572004aadSNick Fitzgerald     }
10672004aadSNick Fitzgerald }
107