# Trait rustc_data_structures::sync::Sync

1.0.0 · source ·

    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:

- `&T` is `Send` if and only if `T` is `Sync`
- `&mut T` is `Send` if and only if `T` is `Send`
- `&T` and `&mut T` are `Sync` if and only if `T` is `Sync`

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`.

## Implementors§

1.0.0 · source§

### impl !Sync for Arguments<'_>

source§

### impl !Sync for LocalWaker

1.26.0 · source§

### impl !Sync for Args

1.26.0 · source§

### impl !Sync for ArgsOs

source§

### impl Sync for OwnedSlice

1.6.0 · source§

### impl Sync for alloc::string::Drain<'_>

1.34.0 · source§

### impl Sync for AtomicI8

1.34.0 · source§

### impl Sync for AtomicI16

1.34.0 · source§

### impl Sync for AtomicI32

1.34.0 · source§

### impl Sync for AtomicI64

1.0.0 · source§

### impl Sync for AtomicIsize

1.34.0 · source§

### impl Sync for AtomicU8

1.34.0 · source§

### impl Sync for AtomicU16

1.36.0 · source§

### impl Sync for Waker

source§

### impl Sync for Select<'_>

source§

### impl Sync for Collector

source§

### impl Sync for Unparker

source§

### impl Sync for Scope<'_>

source§

### impl Sync for GuardNoSend

1.0.0 · source§

### impl Sync for AtomicBool

1.34.0 · source§

### impl Sync for AtomicU32

1.34.0 · source§

### impl Sync for AtomicU64

1.0.0 · source§

### impl Sync for AtomicUsize

1.44.0 · source§

### impl<'a> Sync for IoSlice<'a>

1.44.0 · source§

### impl<'a> Sync for IoSliceMut<'a>

source§

### impl<'a, 'b, K, Q, V, S, A> Sync for hashbrown::map::OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
where K: Sync, Q: Sync + ?Sized, V: Sync, S: Sync, A: Sync + Allocator,

source§

### impl<'a, 'b, K, Q, V, S, A> Sync for hashbrown::map::OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
where K: Sync, Q: Sync + ?Sized, V: Sync, S: Sync, A: Sync + Allocator,

source§

### impl<'a, R, G, T> Sync for MappedReentrantMutexGuard<'a, R, G, T>
where R: RawMutex + Sync + 'a, G: GetThreadId + Sync + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, R, G, T> Sync for ReentrantMutexGuard<'a, R, G, T>
where R: RawMutex + Sync + 'a, G: GetThreadId + Sync + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, R, T> Sync for lock_api::mutex::MappedMutexGuard<'a, R, T>
where R: RawMutex + Sync + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, R, T> Sync for lock_api::mutex::MutexGuard<'a, R, T>
where R: RawMutex + Sync + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, R, T> Sync for lock_api::rwlock::MappedRwLockReadGuard<'a, R, T>
where R: RawRwLock + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, R, T> Sync for lock_api::rwlock::MappedRwLockWriteGuard<'a, R, T>
where R: RawRwLock + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, R, T> Sync for RwLockUpgradableReadGuard<'a, R, T>
where R: RawRwLockUpgrade + 'a, T: Sync + 'a + ?Sized,

source§

### impl<'a, T> Sync for OnceRef<'a, T>
where T: Sync,

source§

### impl<'a, T> Sync for smallvec::Drain<'a, T>
where T: Sync + Array,

source§

### impl<'a, T, const CAP: usize> Sync for arrayvec::arrayvec::Drain<'a, T, CAP>
where T: Sync,

source§

### impl<Dyn> Sync for DynMetadata<Dyn>
where Dyn: ?Sized,

source§

### impl<K, V, A> Sync for RustcOccupiedEntry<'_, K, V, A>
where K: Sync, V: Sync, A: Allocator + Sync,

source§

### impl<K, V, S, A> Sync for hashbrown::map::OccupiedEntry<'_, K, V, S, A>
where K: Sync, V: Sync, S: Sync, A: Sync + Allocator,

source§

### impl<K, V, S, A> Sync for hashbrown::map::RawOccupiedEntryMut<'_, K, V, S, A>
where K: Sync, V: Sync, S: Sync, A: Sync + Allocator,

source§

### impl<K, V, S, A> Sync for hashbrown::map::OccupiedEntry<'_, K, V, S, A>
where K: Sync, V: Sync, S: Sync, A: Sync + Allocator,

source§

### impl<K, V, S, A> Sync for hashbrown::map::RawOccupiedEntryMut<'_, K, V, S, A>
where K: Sync, V: Sync, S: Sync, A: Sync + Allocator,

source§

### impl<P, T, const CP: bool> Sync for CopyTaggedPtr<P, T, CP>
where P: Sync + Pointer, T: Sync + Tag,

source§

### impl<R, G> Sync for RawReentrantMutex<R, G>
where R: RawMutex + Sync, G: GetThreadId + Sync,

source§

### impl<R, G, T> Sync for ReentrantMutex<R, G, T>
where R: RawMutex + Sync, G: GetThreadId + Sync, T: Send + ?Sized,

source§

### impl<R, T> Sync for lock_api::mutex::Mutex<R, T>
where R: RawMutex + Sync, T: Send + ?Sized,

source§

### impl<R, T> Sync for lock_api::rwlock::RwLock<R, T>
where R: RawRwLock + Sync, T: Send + Sync + ?Sized,

source§

### impl<R, T> Sync for lock_api::rwlock::RwLockReadGuard<'_, R, T>
where R: RawRwLock + Sync, T: Sync + ?Sized,

source§

### impl<R, T> Sync for lock_api::rwlock::RwLockWriteGuard<'_, R, T>
where R: RawRwLock + Sync, T: Sync + ?Sized,

1.0.0 · source§

### impl<T> !Sync for *const T
where T: ?Sized,

1.0.0 · source§

### impl<T> !Sync for *mut T
where T: ?Sized,

1.70.0 · source§

### impl<T> !Sync for OnceCell<T>

1.0.0 · source§

### impl<T> !Sync for Cell<T>
where T: ?Sized,

1.0.0 · source§

### impl<T> !Sync for RefCell<T>
where T: ?Sized,

1.0.0 · source§

### impl<T> !Sync for UnsafeCell<T>
where T: ?Sized,

1.25.0 · source§

### impl<T> !Sync for NonNull<T>
where T: ?Sized,

`NonNull` pointers are not `Sync` because the data they reference may be aliased.

1.0.0 · source§

### impl<T> !Sync for std::sync::mpsc::Receiver<T>

source§

### impl<T> Sync for ThinBox<T>
where T: Sync + ?Sized,

`ThinBox<T>` is `Sync` if `T` is `Sync` because the data is owned.

1.0.0 · source§

### impl<T> Sync for alloc::collections::linked_list::Iter<'_, T>
where T: Sync,

1.0.0 · source§

### impl<T> Sync for alloc::collections::linked_list::IterMut<'_, T>
where T: Sync,

source§

### impl<T> Sync for SyncUnsafeCell<T>
where T: Sync + ?Sized,

1.28.0 · source§

### impl<T> Sync for NonZero<T>
where T: ZeroablePrimitive + Sync,

1.31.0 · source§

### impl<T> Sync for ChunksExactMut<'_, T>
where T: Sync,

1.0.0 · source§

### impl<T> Sync for ChunksMut<'_, T>
where T: Sync,

1.0.0 · source§

### impl<T> Sync for core::slice::iter::Iter<'_, T>
where T: Sync,

1.0.0 · source§

### impl<T> Sync for core::slice::iter::IterMut<'_, T>
where T: Sync,

1.31.0 · source§

### impl<T> Sync for RChunksExactMut<'_, T>
where T: Sync,

1.31.0 · source§

### impl<T> Sync for RChunksMut<'_, T>
where T: Sync,

1.0.0 · source§

### impl<T> Sync for AtomicPtr<T>

source§

### impl<T> Sync for Exclusive<T>
where T: ?Sized,

1.72.0 · source§

### impl<T> Sync for std::sync::mpsc::Sender<T>
where T: Send,

source§

### impl<T> Sync for std::sync::mutex::MappedMutexGuard<'_, T>
where T: Sync + ?Sized,

1.0.0 · source§

### impl<T> Sync for std::sync::mutex::Mutex<T>
where T: Send + ?Sized,

1.19.0 · source§

### impl<T> Sync for std::sync::mutex::MutexGuard<'_, T>
where T: Sync + ?Sized,

source§

### impl<T> Sync for ReentrantLock<T>
where T: Send + ?Sized,

source§

### impl<T> Sync for ReentrantLockGuard<'_, T>
where T: Sync + ?Sized,

source§

### impl<T> Sync for std::sync::rwlock::MappedRwLockReadGuard<'_, T>
where T: Sync + ?Sized,

source§

### impl<T> Sync for std::sync::rwlock::MappedRwLockWriteGuard<'_, T>
where T: Sync + ?Sized,

1.0.0 · source§

### impl<T> Sync for std::sync::rwlock::RwLock<T>
where T: Send + Sync + ?Sized,

1.23.0 · source§

### impl<T> Sync for std::sync::rwlock::RwLockReadGuard<'_, T>
where T: Sync + ?Sized,

1.23.0 · source§

### impl<T> Sync for std::sync::rwlock::RwLockWriteGuard<'_, T>
where T: Sync + ?Sized,

1.29.0 · source§

### impl<T> Sync for JoinHandle<T>

source§

### impl<T> Sync for crossbeam_channel::channel::Receiver<T>
where T: Send,

source§

### impl<T> Sync for crossbeam_channel::channel::Sender<T>
where T: Send,

source§

### impl<T> Sync for Injector<T>
where T: Send,

source§

### impl<T> Sync for Stealer<T>
where T: Send,

source§

### impl<T> Sync for Atomic<T>
where T: Pointable + Send + Sync + ?Sized,

source§

### impl<T> Sync for AtomicCell<T>
where T: Send,

source§

### impl<T> Sync for CachePadded<T>
where T: Sync,

source§

### impl<T> Sync for ShardedLock<T>
where T: Send + Sync + ?Sized,

source§

### impl<T> Sync for ShardedLockReadGuard<'_, T>
where T: Sync + ?Sized,

source§

### impl<T> Sync for ShardedLockWriteGuard<'_, T>
where T: Sync + ?Sized,

source§

### impl<T> Sync for ScopedJoinHandle<'_, T>

source§

### impl<T> Sync for OnceBox<T>
where T: Sync + Send,

source§

### impl<T> Sync for rayon_core::worker_local::WorkerLocal<T>
where T: Send,

We prevent concurrent access to the underlying value in the Deref impl, thus any values safe to send across threads can be used with WorkerLocal.

source§

### impl<T> Sync for ThinVec<T>
where T: Sync,

1.70.0 · source§

### impl<T> Sync for OnceLock<T>
where T: Sync + Send,

1.0.0 · source§

### impl<T, A> !Sync for Rc<T, A>
where A: Allocator, T: ?Sized,

1.4.0 · source§

### impl<T, A> !Sync for alloc::rc::Weak<T, A>
where A: Allocator, T: ?Sized,

source§

### impl<T, A> Sync for Cursor<'_, T, A>
where T: Sync, A: Allocator + Sync,

source§

### impl<T, A> Sync for CursorMut<'_, T, A>
where T: Sync, A: Allocator + Sync,

1.0.0 · source§

### impl<T, A> Sync for LinkedList<T, A>
where T: Sync, A: Allocator + Sync,

1.6.0 · source§

### impl<T, A> Sync for alloc::collections::vec_deque::drain::Drain<'_, T, A>
where T: Sync, A: Allocator + Sync,

1.6.0 · source§

### impl<T, A> Sync for alloc::vec::drain::Drain<'_, T, A>
where T: Sync, A: Sync + Allocator,

1.0.0 · source§

### impl<T, A> Sync for alloc::vec::into_iter::IntoIter<T, A>
where T: Sync, A: Allocator + Sync,

source§

### impl<T, A> Sync for hashbrown::table::OccupiedEntry<'_, T, A>
where T: Sync, A: Sync + Allocator,

source§

### impl<T, A> Sync for Box<T, A>
where A: Allocator + Sync, T: Sync + ?Sized,

source§

### impl<T, A> Sync for allocator_api2::stable::vec::drain::Drain<'_, T, A>
where T: Sync, A: Sync + Allocator,

source§

### impl<T, A> Sync for allocator_api2::stable::vec::into_iter::IntoIter<T, A>
where T: Sync, A: Allocator + Sync,

source§

### impl<T, A> Sync for RawDrain<'_, T, A>
where A: Allocator + Sync, T: Sync,

source§

### impl<T, A> Sync for RawIntoIter<T, A>
where A: Allocator + Sync, T: Sync,

source§

### impl<T, A> Sync for RawTable<T, A>
where A: Allocator + Sync, T: Sync,

source§

### impl<T, A> Sync for hashbrown::table::OccupiedEntry<'_, T, A>
where T: Sync, A: Sync + Allocator,

1.0.0 · source§

### impl<T, A> Sync for Arc<T, A>
where T: Sync + Send + ?Sized, A: Allocator + Sync,

1.4.0 · source§

### impl<T, A> Sync for rustc_data_structures::sync::Weak<T, A>
where T: Sync + Send + ?Sized, A: Allocator + Sync,

1.80.0 · source§

### impl<T, F> Sync for LazyLock<T, F>
where T: Sync + Send, F: Send,

source§

### impl<T, F> Sync for Lazy<T, F>
where F: Send, OnceCell<T>: Sync,

source§

### impl<T, F, S> Sync for ScopeGuard<T, F, S>
where T: Sync, F: FnOnce(T), S: Strategy,

source§

### impl<T: DynSync> Sync for FromDyn<T>

source§

### impl<T: Send> Sync for rustc_data_structures::sync::worker_local::WorkerLocal<T>

## Auto implementors§

§

### impl !Sync for RegistryId

§

### impl !Sync for ThreadData

§

### impl !Sync for ModeUnion

§

### impl Sync for NodeStatus

§

### impl Sync for rustc_data_structures::obligation_forest::NodeState

§

### impl Sync for TimePassesFormat

§

### impl Sync for Mode

§

### impl Sync for BaseNString

§

### impl Sync for Fingerprint

§

### impl Sync for PackedFingerprint

§

### impl Sync for rustc_data_structures::flock::linux::Lock

§

### impl Sync for FxHasher

§

### impl Sync for PreorderIndex

§

### impl Sync for Time

§

### impl Sync for Direction

§

### impl Sync for EdgeIndex

§

### impl Sync for NodeIndex

§

### impl Sync for CycleDetector

§

### impl Sync for PrivateZst

§

### impl Sync for Client

§

### impl Sync for Mmap

§

### impl Sync for MmapMut

§

### impl Sync for ObligationTreeId

§

### impl Sync for Pu128

§

### impl Sync for EventFilter

§

### impl Sync for EventId

§

### impl Sync for QueryInvocationId

§

### impl Sync for SelfProfiler

§

### impl Sync for SelfProfilerRef

§

### impl Sync for VerboseInfo

§

### impl Sync for Sip13Rounds

§

### impl Sync for SipHasher128

§

### impl Sync for State

§

### impl Sync for SmallCStr

§

### impl Sync for Hash64

§

### impl Sync for Hash128

§

### impl Sync for HashingControls

§

### impl Sync for StableHasher

§

### impl Sync for FatalErrorMarker

§

### impl Sync for Svh

§

### impl Sync for MaybeTempDir

§

### impl Sync for rustc_data_structures::transitive_relation::Edge

§

### impl Sync for Index

§

### impl Sync for NoUndo

§

### impl Sync for rustc_data_structures::undo_log::Snapshot

§

### impl Sync for Unhasher

§

### impl Sync for NoError

§

### impl Sync for ParallelGuard

§

### impl Sync for Registry

§

### impl Sync for RegistryData

§

### impl<'a> Sync for JsonTimePassesEntry<'a>

§

### impl<'a> Sync for TimingGuard<'a>

§

### impl<'a> Sync for VerboseTimingGuard<'a>

§

### impl<'a, K, V> Sync for Entry<'a, K, V>
where K: Sync, V: Sync,

§

### impl<'a, T> !Sync for FreezeReadGuard<'a, T>

§

### impl<'a, T> !Sync for FreezeWriteGuard<'a, T>

§

### impl<'a, T> !Sync for LockGuard<'a, T>

§

### impl<'a, T> Sync for Interned<'a, T>
where T: Sync,

§

### impl<'c, G, S, A, F> Sync for SccsConstruction<'c, G, S, A, F>
where F: Sync, G: Sync, <G as DirectedGraph>::Node: Sync, S: Sync, A: Sync,

§

### impl<'g, N, E> Sync for AdjacentEdges<'g, N, E>
where N: Sync, E: Sync,

§

### impl<'g, N, E> Sync for DepthFirstTraversal<'g, N, E>
where N: Sync, E: Sync,

§

### impl<'graph, G> Sync for TriColorDepthFirstSearch<'graph, G>
where G: Sync + ?Sized, <G as DirectedGraph>::Node: Sync,

§

### impl<'p> Sync for EventArgRecorder<'p>

§

### impl<A> Sync for SccDetails<A>
where A: Sync,

§

### impl<D> Sync for rustc_data_structures::snapshot_vec::UndoLog<D>
where <D as SnapshotVecDelegate>::Value: Sync, <D as SnapshotVecDelegate>::Undo: Sync,

§

### impl<D, V, L> Sync for SnapshotVec<D, V, L>
where V: Sync, L: Sync, D: Sync,

§

### impl<E> Sync for rustc_data_structures::graph::implementation::Edge<E>
where E: Sync,

§

### impl<F> Sync for OnDrop<F>
where F: Sync,

§

### impl<G> Sync for DepthFirstSearch<G>
where G: Sync, <G as DirectedGraph>::Node: Sync,

§

### impl<I, K, V> Sync for SortedIndexMultiMap<I, K, V>
where I: Sync, K: Sync, V: Sync,

§

### impl<I, T> Sync for AppendOnlyIndexVec<I, T>

§

### impl<Iter> Sync for PreOrderFrame<Iter>
where Iter: Sync,

§

### impl<K> Sync for VarValue<K>
where K: Sync, <K as UnifyKey>::Value: Sync,

§

### impl<K, V> Sync for rustc_data_structures::snapshot_map::UndoLog<K, V>
where K: Sync, V: Sync,

§

### impl<K, V> Sync for SsoHashMap<K, V>
where K: Sync, V: Sync,

§

### impl<K, V> Sync for SortedMap<K, V>
where K: Sync, V: Sync,

§

### impl<K, V> Sync for UnordMap<K, V>
where K: Sync, V: Sync,

§

### impl<K, V, L> Sync for InPlace<K, V, L>
where V: Sync, L: Sync, K: Sync,

§

### impl<K, V, M, L> Sync for SnapshotMap<K, V, M, L>
where M: Sync, L: Sync, K: Sync, V: Sync,

§

### impl<N> Sync for Inner<N>
where N: Sync,

§

### impl<N> Sync for rustc_data_structures::graph::implementation::Node<N>
where N: Sync,

§

### impl<N> Sync for Event<N>
where N: Sync,

§

### impl<N, E> Sync for Graph<N, E>
where N: Sync, E: Sync,

§

### impl<N, S, A> Sync for rustc_data_structures::graph::scc::NodeState<N, S, A>
where A: Sync, S: Sync, N: Sync,

§

### impl<N, S, A> Sync for Sccs<N, S, A>
where S: Sync, A: Sync,

§

### impl<N, const BR: bool> Sync for VecGraph<N, BR>
where N: Sync,

§

### impl<Node> Sync for Kind<Node>
where Node: Sync,

§

### impl<Node> Sync for Dominators<Node>
where Node: Sync,

§

### impl<O> !Sync for rustc_data_structures::obligation_forest::Node<O>

§

### impl<O> !Sync for ObligationForest<O>

§

### impl<O, E> Sync for ProcessResult<O, E>
where E: Sync, O: Sync,

§

### impl<O, E> Sync for Error<O, E>
where E: Sync, O: Sync,

§

### impl<O, E> Sync for Outcome<O, E>
where E: Sync, O: Sync,

§

### impl<P, T, const COMPARE_PACKED: bool> Sync for TaggedPtr<P, T, COMPARE_PACKED>
where P: Sync, T: Sync,

§

### impl<S> Sync for rustc_data_structures::snapshot_vec::Snapshot<S>
where S: Sync,

§

### impl<S> Sync for rustc_data_structures::unify::Snapshot<S>
where <S as UnificationStore>::Snapshot: Sync, S: Sync,

§

### impl<S> Sync for UnificationTable<S>
where S: Sync,

§

### impl<S, A> Sync for WalkReturn<S, A>
where A: Sync, S: Sync,

§

### impl<S, A> Sync for SccData<S, A>
where S: Sync, A: Sync,

§

### impl<T> !Sync for Sharded<T>

§

### impl<T> !Sync for FreezeLock<T>

§

### impl<T> !Sync for rustc_data_structures::sync::lock::maybe_sync::Lock<T>

§

### impl<T> !Sync for rustc_data_structures::sync::lock::no_sync::Lock<T>

§

### impl<T> !Sync for MTLock<T>

§

### impl<T> Sync for AtomicRef<T>
where T: Sync,

§

### impl<T> Sync for Frozen<T>
where T: Sync,

§

### impl<T> Sync for IntoDynSyncSend<T>
where T: Sync + ?Sized,

§

### impl<T> Sync for SsoHashSet<T>
where T: Sync,

§

### impl<T> Sync for Steal<T>
where T: Send + Sync,

§

### impl<T> Sync for TransitiveRelation<T>
where T: Sync,

§

### impl<T> Sync for TransitiveRelationBuilder<T>
where T: Sync,

§

### impl<T> Sync for VecLog<T>
where T: Sync,

§

### impl<T> Sync for WorkQueue<T>
where T: Sync,

§

### impl<T> Sync for CacheAligned<T>
where T: Sync,

§

### impl<T> Sync for rustc_data_structures::sync::RwLock<T>
where T: Send + Sync,

§

### impl<T> Sync for AppendOnlyVec<T>
where T: Send + Sync,

§

### impl<T, I> Sync for UnordItems<T, I>
where I: Sync,

§

### impl<V> Sync for UnordBag<V>
where V: Sync,

§

### impl<V> Sync for UnordSet<V>
where V: Sync,