Skip to main content

make_send_sync/
lib.rs

1//! [![crates.io](https://img.shields.io/crates/v/make-send-sync.svg)](https://crates.io/crates/make-send-sync)
2//! [![docs.rs](https://img.shields.io/docsrs/make-send-sync.svg)](https://docs.rs/make-send-sync)
3//! [![license](https://img.shields.io/crates/l/make-send-sync.svg)](https://unlicense.org/)
4//! [![repository](https://img.shields.io/badge/repo-codeberg.org-blue.svg)](https://codeberg.org/Aseminaunz/make-send-sync)
5//! [![no-std](https://img.shields.io/badge/no--std-compatible-green.svg)](https://docs.rs/make-send-sync)
6//!
7//! Wrapper types to unsafely make any type [`Send`] and/or [`Sync`].
8//!
9//! ```rust
10//! use ::core::{
11//! 	cell::UnsafeCell,
12//! 	ptr,
13//! };
14//! use ::make_send_sync::{
15//! 	UnsafeSendSync,
16//! 	UnsafeSync,
17//! };
18//!
19//! // A type that is not Send or Sync
20//! let not_thread_safe: *const u8 = ptr::dangling();
21//!
22//! let wrapped: UnsafeSendSync<*const u8> = unsafe { UnsafeSendSync::new(not_thread_safe) };
23//!
24//! fn assert_send_sync<T: Send + Sync>(_: T) {}
25//!
26//! // `wrapper` is Send + Sync, even though `not_thread_safe` is not.
27//! assert_send_sync(wrapped);
28//!
29//! // Look! SyncUnsafeCell on stable!
30//! static MY_CELL: UnsafeSync<UnsafeCell<u8>> = unsafe { UnsafeSync::new(UnsafeCell::new(0)) };
31//! ```
32#![no_std]
33
34use ::core::{
35	mem::transmute,
36	ops::{
37		Deref,
38		DerefMut,
39	},
40};
41use raw_transmute::raw_transmute;
42
43macro_rules! create_wrapper {
44	($name:ident: $($trait:path),+) => {
45		#[doc = concat!("A wrapper that unsafely makes `T` " $(, "[`", stringify!($trait), "`]", )" + "+ " without requiring it for `T`.")]
46		///
47		/// Construction of this type is unsafe, as the caller must ensure that every use of the resulting value is indeed thread-safe. Do not expose instances of this type to safe code!
48		///
49		/// This is a `#[repr(transparent)]` wrapper around `T`, so it has the same memory layout as `T`.
50		#[doc = concat!("Transmuting between this type and `T` is valid, but you must uphold the safety requirements for [`", stringify!($name), "::new`].")]
51		#[repr(transparent)]
52		#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
53		pub struct $name<T: ?Sized>(T);
54
55		$(
56			// SAFETY: Construction requires ensuring that every use of the resulting value is thread-safe.
57			/// The wrapper forces the unsafe implementation for `T`.
58			unsafe impl<T: ?Sized> $trait for $name<T> {}
59		)+
60
61		impl<T> $name<T> {
62			#[doc = concat!("Creates a new [`", stringify!($name), "<T>`] wrapping the given value.")]
63			///
64			/// # Safety
65			///
66			#[doc = concat!("Creating [`", stringify!($name), "<T>`] requires unsafe for construction only.")]
67			/// The caller must ensure that every use of the resulting value is thread-safe; later uses are
68			/// not marked unsafe. Do not expose instances of this type to safe code!
69			#[must_use = "this is a zero-cost wrapper."]
70			#[inline(always)]
71			pub const unsafe fn new(value: T) -> Self {
72				Self(value)
73			}
74
75			#[doc = concat!("A safe alternative to construct [`", stringify!($name), "<T>`] when `T` already implements the required traits.")]
76			#[must_use = "this is a zero-cost wrapper."]
77			#[inline(always)]
78			pub const fn safe_new(value: T) -> Self where $(T: $trait),+ {
79				// SAFETY: `T` already implements the required traits, so it's safe to wrap it.
80				unsafe { Self::new(value) }
81			}
82
83			#[doc = concat!("Consumes the [`", stringify!($name), "<T>`] and returns the inner value.")]
84			#[must_use = "unwrapping is pure. Did you mean to `drop` the wrapper instead?"]
85			#[inline(always)]
86			pub const fn into_inner(this: Self) -> T {
87				// SAFETY: wrapper is repr(transparent)
88				unsafe { raw_transmute::<Self, T>(this) }
89			}
90		}
91
92		impl<T: ?Sized> $name<T> {
93			#[doc = concat!("Returns a reference to the inner value of the [`", stringify!($name), "<T>`].")]
94			///
95			/// This is a `const` alternative to dereferencing the wrapper.
96			#[must_use = "dereferencing is pure."]
97			#[inline(always)]
98			pub const fn inner_ref(this: &Self) -> &T {
99				&this.0
100			}
101
102			#[doc = concat!("Returns a mutable reference to the inner value of the [`", stringify!($name), "<T>`].")]
103			///
104			/// This is a `const` alternative to dereferencing the wrapper.
105			#[must_use = "dereferencing is pure."]
106			#[inline(always)]
107			pub const fn inner_mut(this: &mut Self) -> &mut T {
108				&mut this.0
109			}
110
111			#[doc = concat!("Maps `&T` to [`&", stringify!($name), "<T>`](", stringify!($name), ").")]
112			///
113			/// This is useful if you receive a reference to a value that you know will be used in a thread-safe manner.
114			///
115			/// # Safety
116			///
117			#[doc = concat!("See [`", stringify!($name), "<T>::new`].")]
118			#[must_use = "creating references is pure."]
119			#[inline(always)]
120			pub const unsafe fn from_ref(value: &T) -> &Self {
121				// SAFETY: wrapper is repr(transparent)
122				unsafe { transmute::<&T, &Self>(value) }
123			}
124
125			#[doc = concat!("A safe alternative to [`", stringify!($name), "<T>::from_ref`] when `T` already implements the required traits.")]
126			#[must_use = "creating references is pure."]
127			#[inline(always)]
128			pub const fn safe_from_ref(value: &T) -> &Self where $(T: $trait),+ {
129				// SAFETY: `T` already implements the required traits, so it's safe to wrap it.
130				unsafe { Self::from_ref(value) }
131			}
132
133			#[doc = concat!("Maps `&mut T` to [`&mut ", stringify!($name), "<T>`](", stringify!($name), ").")]
134			///
135			/// This is useful if you receive a mutable reference to a value that you know will be used in a thread-safe manner.
136			///
137			/// # Safety
138			///
139			#[doc = concat!("See [`", stringify!($name), "<T>::new`].")]
140			#[must_use = "creating references is pure."]
141			#[inline(always)]
142			pub const unsafe fn from_mut(value: &mut T) -> &mut Self {
143				// SAFETY: wrapper is repr(transparent)
144				unsafe { transmute::<&mut T, &mut Self>(value) }
145			}
146
147			#[doc = concat!("A safe alternative to [`", stringify!($name), "<T>::from_mut`] when `T` already implements the required traits.")]
148			#[must_use = "creating references is pure."]
149			#[inline(always)]
150			pub const fn safe_from_mut(value: &mut T) -> &mut Self where $(T: $trait),+ {
151				// SAFETY: `T` already implements the required traits, so it's safe to wrap it.
152				unsafe { Self::from_mut(value) }
153			}
154		}
155
156		impl<T: ?Sized> Deref for $name<T> {
157			type Target = T;
158
159			#[inline(always)]
160			fn deref(&self) -> &Self::Target {
161				Self::inner_ref(self)
162			}
163		}
164
165		impl<T: ?Sized> DerefMut for $name<T> {
166			#[inline(always)]
167			fn deref_mut(&mut self) -> &mut Self::Target {
168				Self::inner_mut(self)
169			}
170		}
171	};
172}
173
174create_wrapper! { UnsafeSend: Send }
175create_wrapper! { UnsafeSync: Sync }
176create_wrapper! { UnsafeSendSync: Send, Sync }