pub struct Exclusive<T>where
T: ?Sized,{ /* private fields */ }
exclusive_wrapper
)Expand description
Exclusive
provides only mutable access, also referred to as exclusive
access to the underlying value. It provides no immutable, or shared
access to the underlying value.
While this may seem not very useful, it allows Exclusive
to unconditionally
implement Sync
. Indeed, the safety requirements of Sync
state that for Exclusive
to be Sync
, it must be sound to share across threads, that is, it must be sound
for &Exclusive
to cross thread boundaries. By design, a &Exclusive
has no API
whatsoever, making it useless, thus harmless, thus memory safe.
Certain constructs like Future
s can only be used with exclusive access,
and are often Send
but not Sync
, so Exclusive
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();
}
});
Exclusive
ensures the struct is Sync
without stripping the future of its
functionality.
#![feature(exclusive_wrapper)]
use core::cell::Cell;
use core::sync::Exclusive;
async fn other() {}
fn assert_sync<T: Sync>(t: T) {}
struct State<F> {
future: Exclusive<F>
}
assert_sync(State {
future: Exclusive::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, Exclusive
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> Exclusive<T>
impl<T> Exclusive<T>
Sourcepub const fn new(t: T) -> Exclusive<T> ⓘ
🔬This is a nightly-only experimental API. (exclusive_wrapper
)Available on crate feature std
only.
pub const fn new(t: T) -> Exclusive<T> ⓘ
exclusive_wrapper
)std
only.Wrap a value in an Exclusive
Sourcepub const fn into_inner(self) -> T
🔬This is a nightly-only experimental API. (exclusive_wrapper
)Available on crate feature std
only.
pub const fn into_inner(self) -> T
exclusive_wrapper
)std
only.Unwrap the value contained in the Exclusive
Source§impl<T> Exclusive<T>where
T: ?Sized,
impl<T> Exclusive<T>where
T: ?Sized,
Sourcepub const fn get_mut(&mut self) -> &mut T
🔬This is a nightly-only experimental API. (exclusive_wrapper
)Available on crate feature std
only.
pub const fn get_mut(&mut self) -> &mut T
exclusive_wrapper
)std
only.Gets exclusive access to the underlying value.
Sourcepub const fn get_pin_mut(self: Pin<&mut Exclusive<T>>) -> Pin<&mut T>
🔬This is a nightly-only experimental API. (exclusive_wrapper
)Available on crate feature std
only.
pub const fn get_pin_mut(self: Pin<&mut Exclusive<T>>) -> Pin<&mut T>
exclusive_wrapper
)std
only.Gets pinned exclusive access to the underlying value.
Exclusive
is considered to structurally pin the underlying
value, which means unpinned Exclusive
s can produce unpinned
access to the underlying value, but pinned Exclusive
s only
produce pinned access to the underlying value.
Sourcepub const fn from_mut(r: &mut T) -> &mut Exclusive<T> ⓘ
🔬This is a nightly-only experimental API. (exclusive_wrapper
)Available on crate feature std
only.
pub const fn from_mut(r: &mut T) -> &mut Exclusive<T> ⓘ
exclusive_wrapper
)std
only.Build a mutable reference to an Exclusive<T>
from
a mutable reference to a T
. This allows you to skip
building an Exclusive
with Exclusive::new
.
Sourcepub const fn from_pin_mut(r: Pin<&mut T>) -> Pin<&mut Exclusive<T>>
🔬This is a nightly-only experimental API. (exclusive_wrapper
)Available on crate feature std
only.
pub const fn from_pin_mut(r: Pin<&mut T>) -> Pin<&mut Exclusive<T>>
exclusive_wrapper
)std
only.Build a pinned mutable reference to an Exclusive<T>
from
a pinned mutable reference to a T
. This allows you to skip
building an Exclusive
with Exclusive::new
.
Trait Implementations§
Source§impl<R, G> Coroutine<R> for Exclusive<G>
impl<R, G> Coroutine<R> for Exclusive<G>
Source§type Yield = <G as Coroutine<R>>::Yield
type Yield = <G as Coroutine<R>>::Yield
coroutine_trait
)impl<T> Sync for Exclusive<T>where
T: ?Sized,
Auto Trait Implementations§
impl<T> Freeze for Exclusive<T>
impl<T> RefUnwindSafe for Exclusive<T>where
T: RefUnwindSafe + ?Sized,
impl<T> Send for Exclusive<T>
impl<T> Unpin for Exclusive<T>
impl<T> UnwindSafe for Exclusive<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> ByteSized for T
impl<T> ByteSized for T
Source§const BYTE_ALIGN: usize = _
const BYTE_ALIGN: usize = _
Source§fn byte_align(&self) -> usize
fn byte_align(&self) -> usize
Source§fn ptr_size_ratio(&self) -> [usize; 2]
fn ptr_size_ratio(&self) -> [usize; 2]
Source§impl<T, R> Chain<R> for Twhere
T: ?Sized,
impl<T, R> Chain<R> for Twhere
T: ?Sized,
Source§impl<T> ExtAny for T
impl<T> ExtAny for T
Source§fn type_hash_with<H: Hasher>(&self, hasher: H) -> u64
fn type_hash_with<H: Hasher>(&self, hasher: H) -> u64
TypeId
of Self
using a custom hasher.Source§fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
Source§impl<F> ExtFuture for Fwhere
F: Future,
impl<F> ExtFuture for Fwhere
F: Future,
Source§fn pending<T>() -> FuturePending<T> ⓘ
fn pending<T>() -> FuturePending<T> ⓘ
Source§fn poll_fn<T, F>(function: F) -> FuturePollFn<F> ⓘ
fn poll_fn<T, F>(function: F) -> FuturePollFn<F> ⓘ
function
returning TaskPoll
.Source§fn ready<T>(value: T) -> FutureReady<T> ⓘ
fn ready<T>(value: T) -> FutureReady<T> ⓘ
value
.Source§impl<T> ExtMem for Twhere
T: ?Sized,
impl<T> ExtMem for Twhere
T: ?Sized,
Source§const NEEDS_DROP: bool = _
const NEEDS_DROP: bool = _
Source§fn mem_align_of<T>() -> usize
fn mem_align_of<T>() -> usize
Source§fn mem_align_of_val(&self) -> usize
fn mem_align_of_val(&self) -> usize
Source§fn mem_size_of<T>() -> usize
fn mem_size_of<T>() -> usize
Source§fn mem_size_of_val(&self) -> usize
fn mem_size_of_val(&self) -> usize
Source§fn mem_needs_drop(&self) -> bool
fn mem_needs_drop(&self) -> bool
true
if dropping values of this type matters. Read moreSource§fn mem_forget(self)where
Self: Sized,
fn mem_forget(self)where
Self: Sized,
self
without running its destructor. Read moreSource§fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
Source§unsafe fn mem_zeroed<T>() -> T
unsafe fn mem_zeroed<T>() -> T
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§fn mem_as_bytes(&self) -> &[u8] ⓘ
fn mem_as_bytes(&self) -> &[u8] ⓘ
unsafe_slice
only.§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Hook for T
impl<T> Hook for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§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
§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
§impl<I, O, E, F> Parser<I, O, E> for F
impl<I, O, E, F> Parser<I, O, E> for F
§fn parse_next(&mut self, i: &mut I) -> Result<O, E> ⓘ
fn parse_next(&mut self, i: &mut I) -> Result<O, E> ⓘ
§fn parse(
&mut self,
input: I,
) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>> ⓘwhere
Self: Sized,
I: Stream + StreamIsPartial,
E: ParserError<I>,
<E as ParserError<I>>::Inner: ParserError<I>,
fn parse(
&mut self,
input: I,
) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>> ⓘwhere
Self: Sized,
I: Stream + StreamIsPartial,
E: ParserError<I>,
<E as ParserError<I>>::Inner: ParserError<I>,
input
, generating O
from it§fn parse_peek(&mut self, input: I) -> Result<(I, O), E> ⓘ
fn parse_peek(&mut self, input: I) -> Result<(I, O), E> ⓘ
§fn by_ref(&mut self) -> ByRef<'_, Self, I, O, E>where
Self: Sized,
fn by_ref(&mut self) -> ByRef<'_, Self, I, O, E>where
Self: Sized,
&mut Self
as a parser Read more§fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
§fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E>
fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E>
std::convert::From
Read more§fn with_taken(self) -> WithTaken<Self, I, O, E>
fn with_taken(self) -> WithTaken<Self, I, O, E>
§fn span(self) -> Span<Self, I, O, E>
fn span(self) -> Span<Self, I, O, E>
§fn with_span(self) -> WithSpan<Self, I, O, E>
fn with_span(self) -> WithSpan<Self, I, O, E>
§fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E>
fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E>
§fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2>where
Self: Sized,
G: FnMut(O) -> Result<O2, E2>,
I: Stream,
E: FromExternalError<I, E2> + ParserError<I>,
fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2>where
Self: Sized,
G: FnMut(O) -> Result<O2, E2>,
I: Stream,
E: FromExternalError<I, E2> + ParserError<I>,
Result
over the output of a parser. Read more§fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E>
fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E>
§fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E>
fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E>
§fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E>
fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E>
§fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E>
fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E>
std::str::FromStr
to the output of the parser Read more§fn verify<G, O2>(self, filter: G) -> Verify<Self, G, I, O, O2, E>
fn verify<G, O2>(self, filter: G) -> Verify<Self, G, I, O, O2, E>
§fn context<C>(self, context: C) -> Context<Self, I, O, E, C>
fn context<C>(self, context: C) -> Context<Self, I, O, E, C>
§fn complete_err(self) -> CompleteErr<Self, I, O, E>where
Self: Sized,
fn complete_err(self) -> CompleteErr<Self, I, O, E>where
Self: Sized,
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
)Source§fn into_searcher<'a>(self, haystack: &'a str) -> CharPredicateSearcher<'a, F>
fn into_searcher<'a>(self, haystack: &'a str) -> CharPredicateSearcher<'a, F>
pattern
)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
)Source§fn is_prefix_of<'a>(self, haystack: &'a str) -> bool
fn is_prefix_of<'a>(self, haystack: &'a str) -> bool
pattern
)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
)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
)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
)Source§fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> ⓘ
fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> ⓘ
pattern
)§impl<T> Pointable for T
impl<T> Pointable for T
§impl<F, T> Replacer for F
impl<F, T> Replacer for F
§fn replace_append(&mut self, caps: &Captures<'_>, dst: &mut String)
fn replace_append(&mut self, caps: &Captures<'_>, dst: &mut String)
dst
to replace the current match. Read more§fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, str>> ⓘ
fn no_expansion<'r>(&'r mut self) -> Option<Cow<'r, str>> ⓘ
§fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>
fn by_ref<'r>(&'r mut self) -> ReplacerRef<'r, Self>
§impl<T, U> ToSample<U> for Twhere
U: FromSample<T>,
impl<T, U> ToSample<U> for Twhere
U: FromSample<T>,
fn to_sample_(self) -> U
§impl<F> Visit for F
impl<F> Visit for F
§fn record_debug(&mut self, field: &Field, value: &dyn Debug)
fn record_debug(&mut self, field: &Field, value: &dyn Debug)
fmt::Debug
.§fn record_f64(&mut self, field: &Field, value: f64)
fn record_f64(&mut self, field: &Field, value: f64)
§fn record_i64(&mut self, field: &Field, value: i64)
fn record_i64(&mut self, field: &Field, value: i64)
§fn record_u64(&mut self, field: &Field, value: u64)
fn record_u64(&mut self, field: &Field, value: u64)
§fn record_i128(&mut self, field: &Field, value: i128)
fn record_i128(&mut self, field: &Field, value: i128)
§fn record_u128(&mut self, field: &Field, value: u128)
fn record_u128(&mut self, field: &Field, value: u128)
§fn record_bool(&mut self, field: &Field, value: bool)
fn record_bool(&mut self, field: &Field, value: bool)
§fn record_str(&mut self, field: &Field, value: &str)
fn record_str(&mut self, field: &Field, value: &str)
§fn record_bytes(&mut self, field: &Field, value: &[u8])
fn record_bytes(&mut self, field: &Field, value: &[u8])
§fn record_error(&mut self, field: &Field, value: &(dyn Error + 'static))
fn record_error(&mut self, field: &Field, value: &(dyn Error + 'static))
Error
. Read more