pub struct SyncView<T>where
T: ?Sized,{ /* private fields */ }exclusive_wrapper #98407)Expand description
SyncView provides mutable access, also referred to as exclusive
access to the underlying value. However, it only permits immutable, or shared
access to the underlying value when that value is Sync.
While this may seem not very useful, it allows SyncView to unconditionally
implement Sync. Indeed, the safety requirements of Sync state that for SyncView
to be Sync, it must be sound to share across threads, that is, it must be sound
for &SyncView to cross thread boundaries. By design, a &SyncView<T> for non-Sync
T has no API whatsoever, making it useless, thus harmless, thus memory safe.
Certain constructs like Futures can only be used with exclusive access,
and are often Send but not Sync, so SyncView can be used as hint to the
Rust compiler that something is Sync in practice.
ยงExamples
Using a non-Sync future prevents the wrapping struct from being Sync:
use core::cell::Cell;
async fn other() {}
fn assert_sync<T: Sync>(t: T) {}
struct State<F> {
future: F
}
assert_sync(State {
future: async {
let cell = Cell::new(1);
let cell_ref = &cell;
other().await;
let value = cell_ref.get();
}
});SyncView ensures the struct is Sync without stripping the future of its
functionality:
#![feature(exclusive_wrapper)]
use core::cell::Cell;
use core::sync::SyncView;
async fn other() {}
fn assert_sync<T: Sync>(t: T) {}
struct State<F> {
future: SyncView<F>
}
assert_sync(State {
future: SyncView::new(async {
let cell = Cell::new(1);
let cell_ref = &cell;
other().await;
let value = cell_ref.get();
})
});ยงParallels with a mutex
In some sense, SyncView can be thought of as a compile-time version of
a mutex, as the borrow-checker guarantees that only one &mut can exist
for any value. This is a parallel with the fact that
& and &mut references together can be thought of as a compile-time
version of a read-write lock.
Implementationsยง
Sourceยงimpl<T> SyncView<T>where
T: ?Sized,
impl<T> SyncView<T>where
T: ?Sized,
Sourcepub const fn as_pin_mut(self: Pin<&mut SyncView<T>>) -> Pin<&mut T>
๐ฌThis is a nightly-only experimental API. (exclusive_wrapper #98407)
pub const fn as_pin_mut(self: Pin<&mut SyncView<T>>) -> Pin<&mut T>
exclusive_wrapper #98407)Gets pinned exclusive access to the underlying value.
SyncView is considered to structurally pin the underlying
value, which means unpinned SyncViews can produce unpinned
access to the underlying value, but pinned SyncViews only
produce pinned access to the underlying value.
Sourcepub const fn from_mut(r: &mut T) -> &mut SyncView<T> โ
๐ฌThis is a nightly-only experimental API. (exclusive_wrapper #98407)
pub const fn from_mut(r: &mut T) -> &mut SyncView<T> โ
exclusive_wrapper #98407)Build a mutable reference to an SyncView<T> from
a mutable reference to a T. This allows you to skip
building an SyncView with SyncView::new.
Sourcepub const fn from_pin_mut(r: Pin<&mut T>) -> Pin<&mut SyncView<T>>
๐ฌThis is a nightly-only experimental API. (exclusive_wrapper #98407)
pub const fn from_pin_mut(r: Pin<&mut T>) -> Pin<&mut SyncView<T>>
exclusive_wrapper #98407)Build a pinned mutable reference to an SyncView<T> from
a pinned mutable reference to a T. This allows you to skip
building an SyncView with SyncView::new.
Sourceยงimpl<T> SyncView<T>
impl<T> SyncView<T>
Sourcepub const fn as_pin(self: Pin<&SyncView<T>>) -> Pin<&T>
๐ฌThis is a nightly-only experimental API. (exclusive_wrapper #98407)
pub const fn as_pin(self: Pin<&SyncView<T>>) -> Pin<&T>
exclusive_wrapper #98407)Gets pinned shared access to the underlying value.
SyncView is considered to structurally pin the underlying
value, which means unpinned SyncViews can produce unpinned
access to the underlying value, but pinned SyncViews only
produce pinned access to the underlying value.
Trait Implementationsยง
Sourceยงimpl<F, Args> AsyncFn<Args> for SyncView<F>
impl<F, Args> AsyncFn<Args> for SyncView<F>
Sourceยงextern "rust-call" fn async_call(
&self,
args: Args,
) -> <SyncView<F> as AsyncFnMut<Args>>::CallRefFuture<'_> โ
extern "rust-call" fn async_call( &self, args: Args, ) -> <SyncView<F> as AsyncFnMut<Args>>::CallRefFuture<'_> โ
async_fn_traits)AsyncFn, returning a future which may borrow from the called closure.Sourceยงimpl<F, Args> AsyncFnMut<Args> for SyncView<F>where
F: AsyncFnMut<Args>,
Args: Tuple,
impl<F, Args> AsyncFnMut<Args> for SyncView<F>where
F: AsyncFnMut<Args>,
Args: Tuple,
Sourceยงtype CallRefFuture<'a> = <F as AsyncFnMut<Args>>::CallRefFuture<'a>
where
F: 'a
type CallRefFuture<'a> = <F as AsyncFnMut<Args>>::CallRefFuture<'a> where F: 'a
async_fn_traits)AsyncFnMut::async_call_mut and AsyncFn::async_call.Sourceยงextern "rust-call" fn async_call_mut(
&mut self,
args: Args,
) -> <SyncView<F> as AsyncFnMut<Args>>::CallRefFuture<'_> โ
extern "rust-call" fn async_call_mut( &mut self, args: Args, ) -> <SyncView<F> as AsyncFnMut<Args>>::CallRefFuture<'_> โ
async_fn_traits)AsyncFnMut, returning a future which may borrow from the called closure.Sourceยงimpl<F, Args> AsyncFnOnce<Args> for SyncView<F>where
F: AsyncFnOnce<Args>,
Args: Tuple,
impl<F, Args> AsyncFnOnce<Args> for SyncView<F>where
F: AsyncFnOnce<Args>,
Args: Tuple,
Sourceยงtype CallOnceFuture = <F as AsyncFnOnce<Args>>::CallOnceFuture
type CallOnceFuture = <F as AsyncFnOnce<Args>>::CallOnceFuture
async_fn_traits)AsyncFnOnce::async_call_once.Sourceยงtype Output = <F as AsyncFnOnce<Args>>::Output
type Output = <F as AsyncFnOnce<Args>>::Output
async_fn_traits)Sourceยงextern "rust-call" fn async_call_once(
self,
args: Args,
) -> <SyncView<F> as AsyncFnOnce<Args>>::CallOnceFuture โ
extern "rust-call" fn async_call_once( self, args: Args, ) -> <SyncView<F> as AsyncFnOnce<Args>>::CallOnceFuture โ
async_fn_traits)AsyncFnOnce, returning a future which may move out of the called closure.Sourceยงimpl<R, G> Coroutine<R> for SyncView<G>
impl<R, G> Coroutine<R> for SyncView<G>
Sourceยงtype Yield = <G as Coroutine<R>>::Yield
type Yield = <G as Coroutine<R>>::Yield
coroutine_trait #43122)Sourceยงimpl<T> Ord for SyncView<T>
impl<T> Ord for SyncView<T>
1.21.0 ยท Sourceยงfn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Sourceยงimpl<T, U> PartialOrd<SyncView<U>> for SyncView<T>
impl<T, U> PartialOrd<SyncView<U>> for SyncView<T>
impl<T> Copy for SyncView<T>
impl<T> Eq for SyncView<T>
impl<T> StructuralPartialEq for SyncView<T>
impl<T> Sync for SyncView<T>where
T: ?Sized,
Auto Trait Implementationsยง
impl<T> Freeze for SyncView<T>
impl<T> RefUnwindSafe for SyncView<T>where
T: RefUnwindSafe + ?Sized,
impl<T> Send for SyncView<T>
impl<T> Unpin for SyncView<T>
impl<T> UnsafeUnpin for SyncView<T>where
T: UnsafeUnpin + ?Sized,
impl<T> UnwindSafe for SyncView<T>where
T: UnwindSafe + ?Sized,
Blanket Implementationsยง
Sourceยงimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Sourceยงfn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Sourceยงimpl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Sourceยงimpl<F> IntoFuture for Fwhere
F: Future,
impl<F> IntoFuture for Fwhere
F: Future,
Sourceยงtype IntoFuture = F
type IntoFuture = F
Sourceยงfn into_future(self) -> <F as IntoFuture>::IntoFuture
fn into_future(self) -> <F as IntoFuture>::IntoFuture
Sourceยงimpl<F> Pattern for F
impl<F> Pattern for F
Sourceยงtype Searcher<'a> = CharPredicateSearcher<'a, F>
type Searcher<'a> = CharPredicateSearcher<'a, F>
pattern #27721)Sourceยงfn into_searcher<'a>(self, haystack: &'a str) -> CharPredicateSearcher<'a, F>
fn into_searcher<'a>(self, haystack: &'a str) -> CharPredicateSearcher<'a, F>
pattern #27721)self and the haystack to search in.Sourceยงfn is_contained_in<'a>(self, haystack: &'a str) -> bool
fn is_contained_in<'a>(self, haystack: &'a str) -> bool
pattern #27721)Sourceยงfn is_prefix_of<'a>(self, haystack: &'a str) -> bool
fn is_prefix_of<'a>(self, haystack: &'a str) -> bool
pattern #27721)Sourceยงfn strip_prefix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
fn strip_prefix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
pattern #27721)Sourceยงfn is_suffix_of<'a>(self, haystack: &'a str) -> boolwhere
CharPredicateSearcher<'a, F>: ReverseSearcher<'a>,
fn is_suffix_of<'a>(self, haystack: &'a str) -> boolwhere
CharPredicateSearcher<'a, F>: ReverseSearcher<'a>,
pattern #27721)Sourceยงfn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>where
CharPredicateSearcher<'a, F>: ReverseSearcher<'a>,
fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>where
CharPredicateSearcher<'a, F>: ReverseSearcher<'a>,
pattern #27721)Sourceยงfn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>>
fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>>
pattern #27721)