pub unsafe auto trait Sync { }Expand description
Types for which it is safe to share references between threads.
This trait is automatically implemented when the compiler determines it’s appropriate.
The precise definition is: a type T is Sync if and only if &T is
Send. In other words, if there is no possibility of
undefined behavior (including data races) when passing
&T references between threads.
As one would expect, primitive types like u8 and f64
are all Sync, and so are simple aggregate types containing them,
like tuples, structs and enums. More examples of basic Sync
types include “immutable” types like &T, and those with simple
inherited mutability, such as Box<T>, Vec<T> and
most other collection types. (Generic parameters need to be Sync
for their container to be Sync.)
A somewhat surprising consequence of the definition is that &mut T
is Sync (if T is Sync) even though it seems like that might
provide unsynchronized mutation. The trick is that a mutable
reference behind a shared reference (that is, & &mut T)
becomes read-only, as if it were a & &T. Hence there is no risk
of a data race.
A shorter overview of how Sync and Send relate to referencing:
&TisSendif and only ifTisSync&mut TisSendif and only ifTisSend&Tand&mut TareSyncif and only ifTisSync
Types that are not Sync are those that have “interior
mutability” in a non-thread-safe form, such as Cell
and RefCell. These types allow for mutation of
their contents even through an immutable, shared reference. For
example the set method on Cell<T> takes &self, so it requires
only a shared reference &Cell<T>. The method performs no
synchronization, thus Cell cannot be Sync.
Another example of a non-Sync type is the reference-counting
pointer Rc. Given any reference &Rc<T>, you can clone
a new Rc<T>, modifying the reference counts in a non-atomic way.
For cases when one does need thread-safe interior mutability,
Rust provides atomic data types, as well as explicit locking via
sync::Mutex and sync::RwLock. These types
ensure that any mutation cannot cause data races, hence the types
are Sync. Likewise, sync::Arc provides a thread-safe
analogue of Rc.
Any types with interior mutability must also use the
cell::UnsafeCell wrapper around the value(s) which
can be mutated through a shared reference. Failing to doing this is
undefined behavior. For example, transmute-ing
from &T to &mut T is invalid.
See the Nomicon for more details about Sync.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl !Sync for Args
impl !Sync for ArgsOs
impl !Sync for Arguments<'_>
impl !Sync for LocalWaker
impl !Sync for VarsOs
impl Sync for AbortHandle
impl Sync for futures_core::task::__internal::atomic_waker::AtomicWaker
impl Sync for atomic_waker::AtomicWaker
impl Sync for bytes::bytes::Bytes
impl Sync for core::ffi::c_str::Bytes<'_>
impl Sync for BytesMut
impl Sync for Collector
impl Sync for DIR
impl Sync for lib::text::Drain<'_>
impl Sync for GuardNoSend
impl Sync for libloading::os::unix::Library
impl Sync for libloading::safe::Library
impl Sync for Location<'_>
impl Sync for OwnedNotified
impl Sync for crossbeam_utils::thread::Scope<'_>
impl Sync for Select<'_>
impl Sync for SqliteOwnedBuf
impl Sync for SqliteRow
impl Sync for TypeId
impl Sync for Unparker
impl Sync for Waker
impl<'a, 'b, K, Q, V, S, A> Sync for OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
impl<'a, K, S, M> Sync for dashmap::iter_set::Iter<'_, K, S, M>
impl<'a, K, V, S, M> Sync for dashmap::iter::Iter<'_, K, V, S, M>
impl<'a, K, V, S, M> Sync for dashmap::iter::IterMut<'_, K, V, S, M>
impl<'a, R, G, T> Sync for MappedReentrantMutexGuard<'a, R, G, T>
impl<'a, R, G, T> Sync for ReentrantMutexGuard<'a, R, G, T>
impl<'a, R, T> Sync for lock_api::mutex::MappedMutexGuard<'a, R, T>
impl<'a, R, T> Sync for lock_api::rwlock::MappedRwLockReadGuard<'a, R, T>
impl<'a, R, T> Sync for lock_api::rwlock::MappedRwLockWriteGuard<'a, R, T>
impl<'a, R, T> Sync for lock_api::mutex::MutexGuard<'a, R, T>
impl<'a, R, T> Sync for RwLockUpgradableReadGuard<'a, R, T>
impl<'a, T, const CAP: usize> Sync for arrayvec::arrayvec::Drain<'a, T, CAP>where
T: Sync,
impl<'a, T> Sync for smallvec::Drain<'a, T>
impl<'a, T> Sync for http::header::map::Drain<'a, T>where
T: Sync,
impl<'a, T> Sync for http::header::map::Iter<'a, T>where
T: Sync,
impl<'a, T> Sync for http::header::map::IterMut<'a, T>where
T: Sync,
impl<'a, T> Sync for tokio::sync::mutex::MappedMutexGuard<'a, T>
impl<'a, T> Sync for OnceRef<'a, T>where
T: Sync,
impl<'a, T> Sync for ValueDrain<'a, T>where
T: Sync,
impl<'a, T> Sync for ValueIterMut<'a, T>where
T: Sync,
impl<'a, T> Sync for ZeroVec<'a, T>
impl<'a> Sync for IoSlice<'a>
impl<'a> Sync for IoSliceMut<'a>
impl<'a> Sync for Notified<'a>
impl<C> Sync for CartableOptionPointer<C>where
C: Sync + CartablePointerLike,
impl<Dyn> Sync for DynMetadata<Dyn>where
Dyn: ?Sized,
impl<Fut> Sync for FuturesUnordered<Fut>
impl<Fut> Sync for futures_util::stream::futures_unordered::iter::IntoIter<Fut>
impl<Fut> Sync for IterPinMut<'_, Fut>where
Fut: Sync,
impl<Fut> Sync for IterPinRef<'_, Fut>where
Fut: Sync,
impl<K, S> Sync for dashmap::iter_set::OwningIter<K, S>
impl<K, V, S, A> Sync for hashbrown::map::OccupiedEntry<'_, K, V, S, A>
impl<K, V, S, A> Sync for hashbrown::map::OccupiedEntry<'_, K, V, S, A>
impl<K, V, S, A> Sync for hashbrown::map::OccupiedEntry<'_, K, V, S, A>
impl<K, V, S, A> Sync for hashbrown::map::RawOccupiedEntryMut<'_, K, V, S, A>
impl<K, V, S, A> Sync for hashbrown::raw_entry::RawOccupiedEntryMut<'_, K, V, S, A>
impl<K, V, S> Sync for LinkedHashMap<K, V, S>
impl<K, V, S> Sync for dashmap::iter::OwningIter<K, V, S>
impl<K, V, S> Sync for hashlink::linked_hash_map::RawOccupiedEntryMut<'_, K, V, S>
impl<K, V, S> Sync for RawVacantEntryMut<'_, K, V, S>
impl<K, V> Sync for hashlink::linked_hash_map::Drain<'_, K, V>
impl<K, V> Sync for hashlink::linked_hash_map::IntoIter<K, V>
impl<K, V> Sync for hashlink::linked_hash_map::Iter<'_, K, V>
impl<K, V> Sync for hashlink::linked_hash_map::IterMut<'_, K, V>
impl<K, V> Sync for dashmap::mapref::entry::OccupiedEntry<'_, K, V>
impl<K, V> Sync for dashmap::mapref::one::Ref<'_, K, V>
impl<K, V> Sync for RefMulti<'_, K, V>
impl<K, V> Sync for dashmap::mapref::one::RefMut<'_, K, V>
impl<K, V> Sync for RefMutMulti<'_, K, V>
impl<K, V> Sync for dashmap::mapref::entry::VacantEntry<'_, K, V>
impl<MutexType, T, A> Sync for GenericChannel<MutexType, T, A>
impl<MutexType, T> Sync for GenericMutexGuard<'_, MutexType, T>
impl<MutexType, T> Sync for GenericOneshotBroadcastChannel<MutexType, T>
impl<MutexType, T> Sync for GenericOneshotChannel<MutexType, T>
impl<MutexType, T> Sync for GenericStateBroadcastChannel<MutexType, T>
impl<MutexType> Sync for GenericManualResetEvent<MutexType>
impl<MutexType> Sync for GenericSemaphore<MutexType>
impl<MutexType> Sync for GenericTimerService<MutexType>
impl<R, G, T> Sync for ReentrantMutex<R, G, T>
impl<R, G> Sync for RawReentrantMutex<R, G>
impl<R, T> Sync for lock_api::mutex::Mutex<R, T>
impl<R, T> Sync for lock_api::rwlock::RwLock<R, T>
impl<R, T> Sync for lock_api::rwlock::RwLockReadGuard<'_, R, T>
impl<R, T> Sync for lock_api::rwlock::RwLockWriteGuard<'_, R, T>
impl<T, A> !Sync for Rc<T, A>
impl<T, A> !Sync for UniqueRc<T, A>
impl<T, A> !Sync for alloc::rc::Weak<T, A>
impl<T, A> Sync for Arc<T, A>
impl<T, A> Sync for Box<T, A>
impl<T, A> Sync for lib::collections::linked_list::Cursor<'_, T, A>
impl<T, A> Sync for lib::collections::linked_list::CursorMut<'_, T, A>
impl<T, A> Sync for lib::collections::vec_deque::Drain<'_, T, A>
impl<T, A> Sync for alloc::vec::drain::Drain<'_, T, A>
impl<T, A> Sync for allocator_api2::stable::vec::drain::Drain<'_, T, A>
impl<T, A> Sync for alloc::vec::into_iter::IntoIter<T, A>
impl<T, A> Sync for allocator_api2::stable::vec::into_iter::IntoIter<T, A>
impl<T, A> Sync for LinkedList<T, A>
impl<T, A> Sync for hashbrown::table::OccupiedEntry<'_, T, A>
impl<T, A> Sync for hashbrown::table::OccupiedEntry<'_, T, A>
impl<T, A> Sync for hashbrown::table::OccupiedEntry<'_, T, A>
impl<T, A> Sync for RawDrain<'_, T, A>
impl<T, A> Sync for RawIntoIter<T, A>
impl<T, A> Sync for RawTable<T, A>
impl<T, A> Sync for UniqueArc<T, A>
impl<T, A> Sync for lib::sync::Weak<T, A>
impl<T, F, S> Sync for ScopeGuard<T, F, S>
impl<T, F> Sync for spin::lazy::Lazy<T, F>
impl<T, F> Sync for once_cell::sync::Lazy<T, F>
impl<T, F> Sync for LazyLock<T, F>
impl<T, MutexType> Sync for GenericMutex<MutexType, T>
impl<T, N> Sync for GenericArray<T, N>where
T: Sync,
N: ArrayLength<T>,
impl<T, R> Sync for spin::mutex::Mutex<T, R>
impl<T, R> Sync for spin::once::Once<T, R>
impl<T, R> Sync for spin::rwlock::RwLock<T, R>
impl<T, R> Sync for RwLockUpgradableGuard<'_, T, R>
impl<T, R> Sync for spin::rwlock::RwLockWriteGuard<'_, T, R>
impl<T, R> Sync for SpinMutex<T, R>
impl<T, U> Sync for hybrid_array::Array<T, U>
SAFETY: Array is a repr(transparent) newtype for [T; N], so as long as T: Sync it should
also be Sync.
impl<T, U> Sync for futures_util::lock::mutex::MappedMutexGuard<'_, T, U>
impl<T, U> Sync for OwnedMappedMutexGuard<T, U>
impl<T, U> Sync for OwnedRwLockMappedWriteGuard<T, U>
impl<T, U> Sync for OwnedRwLockReadGuard<T, U>
impl<T> !Sync for *const Twhere
T: ?Sized,
impl<T> !Sync for *mut Twhere
T: ?Sized,
impl<T> !Sync for Cell<T>where
T: ?Sized,
impl<T> !Sync for CovariantUnsafeCell<T>where
T: ?Sized,
impl<T> !Sync for NonNull<T>where
T: ?Sized,
NonNull pointers are not Sync because the data they reference may be aliased.
impl<T> !Sync for lib::core::cell::OnceCell<T>
impl<T> !Sync for lib::sync::mpsc::Receiver<T>
impl<T> !Sync for RefCell<T>where
T: ?Sized,
impl<T> !Sync for UnsafeCell<T>where
T: ?Sized,
impl<T> Sync for ArrayQueue<T>where
T: Send,
impl<T> Sync for lib::sync::atomic::Atomic<T>where
T: AtomicPrimitive,
impl<T> Sync for crossbeam_epoch::atomic::Atomic<T>
impl<T> Sync for AtomicCell<T>where
T: Send,
impl<T> Sync for CachePadded<T>where
T: Sync,
impl<T> Sync for ChunksExactMut<'_, T>where
T: Sync,
impl<T> Sync for ChunksMut<'_, T>where
T: Sync,
impl<T> Sync for Event<T>where
T: Send,
impl<T> Sync for EventListener<T>where
T: Send,
impl<T> Sync for Injector<T>where
T: Send,
impl<T> Sync for core::slice::iter::Iter<'_, T>where
T: Sync,
impl<T> Sync for lib::collections::linked_list::Iter<'_, T>where
T: Sync,
impl<T> Sync for core::slice::iter::IterMut<'_, T>where
T: Sync,
impl<T> Sync for lib::collections::linked_list::IterMut<'_, T>where
T: Sync,
impl<T> Sync for lib::sync::thread::JoinHandle<T>
impl<T> Sync for tokio::runtime::task::join::JoinHandle<T>where
T: Send,
impl<T> Sync for lib::sync::nonpoison::MappedMutexGuard<'_, T>
impl<T> Sync for lib::sync::MappedMutexGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::MappedRwLockReadGuard<'_, T>
impl<T> Sync for lib::sync::MappedRwLockReadGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::MappedRwLockWriteGuard<'_, T>
impl<T> Sync for lib::sync::MappedRwLockWriteGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::Mutex<T>
T must be Send for Mutex to be Sync.
This ensures that the protected data can be accessed safely from multiple threads
without causing data races or other unsafe behavior.
Mutex<T> provides mutable access to T to one thread at a time. However, it’s essential
for T to be Send because it’s not safe for non-Send structures to be accessed in
this manner. For instance, consider Rc, a non-atomic reference counted smart pointer,
which is not Send. With Rc, we can have multiple copies pointing to the same heap
allocation with a non-atomic reference count. If we were to use Mutex<Rc<_>>, it would
only protect one instance of Rc from shared access, leaving other copies vulnerable
to potential data races.
Also note that it is not necessary for T to be Sync as &T is only made available
to one thread at a time if T is not Sync.
impl<T> Sync for lib::prelude::Mutex<T>
T must be Send for Mutex to be Sync.
This ensures that the protected data can be accessed safely from multiple threads
without causing data races or other unsafe behavior.
Mutex<T> provides mutable access to T to one thread at a time. However, it’s essential
for T to be Send because it’s not safe for non-Send structures to be accessed in
this manner. For instance, consider Rc, a non-atomic reference counted smart pointer,
which is not Send. With Rc, we can have multiple copies pointing to the same heap
allocation with a non-atomic reference count. If we were to use Mutex<Rc<_>>, it would
only protect one instance of Rc from shared access, leaving other copies vulnerable
to potential data races.
Also note that it is not necessary for T to be Sync as &T is only made available
to one thread at a time if T is not Sync.
impl<T> Sync for futures_util::lock::mutex::Mutex<T>
impl<T> Sync for tokio::sync::mutex::Mutex<T>
impl<T> Sync for tokio::sync::mutex::MutexGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::MutexGuard<'_, T>
T must be Sync for a MutexGuard<T> to be Sync
because it is possible to get a &T from &MutexGuard (via Deref).
impl<T> Sync for lib::sync::MutexGuard<'_, T>
T must be Sync for a MutexGuard<T> to be Sync
because it is possible to get a &T from &MutexGuard (via Deref).
impl<T> Sync for futures_util::lock::mutex::MutexGuard<'_, T>
impl<T> Sync for MutexLockFuture<'_, T>where
T: ?Sized,
impl<T> Sync for NonZero<T>where
T: ZeroablePrimitive + Sync,
impl<T> Sync for OnceBox<T>
impl<T> Sync for tokio::sync::once_cell::OnceCell<T>
impl<T> Sync for OnceLock<T>
impl<T> Sync for tokio::sync::mutex::OwnedMutexGuard<T>
impl<T> Sync for futures_util::lock::mutex::OwnedMutexGuard<T>
impl<T> Sync for OwnedMutexLockFuture<T>where
T: ?Sized,
impl<T> Sync for OwnedRwLockWriteGuard<T>
impl<T> Sync for RChunksExactMut<'_, T>where
T: Sync,
impl<T> Sync for RChunksMut<'_, T>where
T: Sync,
impl<T> Sync for ReadHalf<T>where
T: Sync,
impl<T> Sync for lib::sync::oneshot::Receiver<T>
impl<T> Sync for lib::sync::mpmc::Receiver<T>where
T: Send,
impl<T> Sync for crossbeam_channel::channel::Receiver<T>where
T: Send,
impl<T> Sync for ReentrantLock<T>
impl<T> Sync for ReentrantLockGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::RwLock<T>
impl<T> Sync for lib::prelude::RwLock<T>
impl<T> Sync for tokio::sync::rwlock::RwLock<T>
impl<T> Sync for RwLockMappedWriteGuard<'_, T>
impl<T> Sync for tokio::sync::rwlock::read_guard::RwLockReadGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::RwLockReadGuard<'_, T>
impl<T> Sync for lib::sync::RwLockReadGuard<'_, T>
impl<T> Sync for spin::rwlock::RwLockReadGuard<'_, T>
impl<T> Sync for tokio::sync::rwlock::write_guard::RwLockWriteGuard<'_, T>
impl<T> Sync for lib::sync::nonpoison::RwLockWriteGuard<'_, T>
impl<T> Sync for lib::sync::RwLockWriteGuard<'_, T>
impl<T> Sync for crossbeam_utils::thread::ScopedJoinHandle<'_, T>
impl<T> Sync for SegQueue<T>where
T: Send,
impl<T> Sync for lib::sync::oneshot::Sender<T>
impl<T> Sync for lib::sync::mpmc::Sender<T>where
T: Send,
impl<T> Sync for lib::sync::mpsc::Sender<T>where
T: Send,
impl<T> Sync for crossbeam_channel::channel::Sender<T>where
T: Send,
impl<T> Sync for SetOnce<T>
impl<T> Sync for ShardedLock<T>
impl<T> Sync for ShardedLockReadGuard<'_, T>
impl<T> Sync for ShardedLockWriteGuard<'_, T>
impl<T> Sync for SpinMutexGuard<'_, T>
impl<T> Sync for Stealer<T>where
T: Send,
impl<T> Sync for libloading::safe::Symbol<'_, T>where
T: Sync,
impl<T> Sync for libloading::os::unix::Symbol<T>where
T: Sync,
impl<T> Sync for SyncUnsafeCell<T>
impl<T> Sync for SyncView<T>where
T: ?Sized,
impl<T> Sync for SyncWrapper<T>
impl<T> Sync for ThinBox<T>
ThinBox<T> is Sync if T is Sync because the data is owned.