#[repr(transparent)]pub struct AlwaysSend<T> {
pub inner: T,
/* private fields */
}
Expand description
Transparent wrapper type around some Send
contents.
This type only requires T: Send
on construction, so it cannot
safely be instantiated for non-Send
inner types T
.
This then allows it to implement an unconditional implementation
for AlwaysSend<T>: Send
itself. This can be very useful to work around
certain cases of compiler-limitations where the attempt of tracking
the Send
auto trait fails with surprising error messages such as
error: implementation of `FnOnce` is not general enough
--> src/main.rs:…:…
|
… | tokio::spawn(async move {
| ^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'0 …) -> …` must implement `FnOnce<(&…,)>`, for any lifetime `'0`...
= note: ...but it actually implements `FnOnce<(&…,)>`
appearing when calling tokio::spawn
on an (otherwise functional) future.
Compare for example rust-lang/rust#89976 and some Rust forum threads [(1), (2)] for more conrete examples.
A known possible workaround was to convert a relevant problematic future (or stream)
into a boxed, type-erased version of itself. The future (or stream) that works
is typically one close to where the closure (or other kind of value) – which
the trait bound (e.g. FnOnce
) that the compiler error complained about belongs to – was
wrapped up into a future (or stream).
This workaround is easiest with the extensions traits from the futures
crate,
because you just add a call to .boxed()
in the right place, producing
a Pin<Box<dyn Future<…> + Send>>
(or Stream
) without much additional typing.
It turns out: The only actually relevant property
of these boxed, type-erased futures/streams –
which made them an effective workaround for this compiler bug & error –
is that they implement Send
unconditionally.
This crate offers a similarly convenient API through its own extension traits
FutureExt
and StreamExt
(the latter requires the stream
feature).
So just adding some call(s) to .always_send()
in the right place(s) might solve your issue ;-)
Note that this struct features an invariant type parameter T
,
so that subtyping coercions can not later invalidate the T: Send
check
from when the wrapped value was constructed.
Fields§
§inner: T
The inner value is publicly accessible, and there is no Drop
implementation
so you can have full access to it.
For this reasons, we also don’t provides any getter methods, or .into_inner()
.
Another (private) field in this struct enforces invariance and prevents construction
other than through methods such as AlwaysSend::new
.
Implementations§
Source§impl<T: Send> AlwaysSend<T>
impl<T: Send> AlwaysSend<T>
Sourcepub fn new(inner: T) -> Self
pub fn new(inner: T) -> Self
Wraps sendable type in the AlwaysSend<T>
wrapper.
Sourcepub fn from_ref(r: &T) -> &Self
pub fn from_ref(r: &T) -> &Self
Wrap as AlwaysSend
behind a reference.
To go the other way, from wrapped: &Always<T>
to &T
,
just access &wrapped.inner
.
Sourcepub fn from_mut(r: &mut T) -> &mut Self
pub fn from_mut(r: &mut T) -> &mut Self
Wrap as AlwaysSend
behind a mutable reference.
To go the other way, from wrapped: &mut Always<T>
to &mut T
,
just access &mut wrapped.inner
.
Sourcepub fn from_pin_ref(r: Pin<&T>) -> Pin<&Self>
pub fn from_pin_ref(r: Pin<&T>) -> Pin<&Self>
Wrap as AlwaysSend
behind a pinned immutable reference.
To go the other way, see .inner_pin()
.
Sourcepub fn from_pin_mut(r: Pin<&mut T>) -> Pin<&mut Self>
pub fn from_pin_mut(r: Pin<&mut T>) -> Pin<&mut Self>
Wrap as AlwaysSend
behind a pinned mutable reference.
To go the other way, see .inner_pin_mut()
.
Trait Implementations§
Source§impl<T: Send> From<T> for AlwaysSend<T>
impl<T: Send> From<T> for AlwaysSend<T>
Source§fn from(value: T) -> AlwaysSend<T> ⓘ
fn from(value: T) -> AlwaysSend<T> ⓘ
Wraps sendable type in the AlwaysSend<T>
wrapper,
like AlwaysSend::new
.
Source§impl<F: FusedFuture> FusedFuture for AlwaysSend<F>
Available on crate feature stream
only.
impl<F: FusedFuture> FusedFuture for AlwaysSend<F>
stream
only.Source§fn is_terminated(&self) -> bool
fn is_terminated(&self) -> bool
true
if the underlying future should no longer be polled.Source§impl<S: FusedStream> FusedStream for AlwaysSend<S>
Available on crate feature stream
only.
impl<S: FusedStream> FusedStream for AlwaysSend<S>
stream
only.Source§fn is_terminated(&self) -> bool
fn is_terminated(&self) -> bool
true
if the stream should no longer be polled.Source§impl<F: Future> Future for AlwaysSend<F>
impl<F: Future> Future for AlwaysSend<F>
Source§impl<S: Stream> Stream for AlwaysSend<S>
Available on crate feature stream
only.
impl<S: Stream> Stream for AlwaysSend<S>
stream
only.impl<T> Send for AlwaysSend<T>
This is the main feature, an implementation of Send
without reqiring T: Send
.
impl<T: Unpin> Unpin for AlwaysSend<T>
This wrapper offers structural pinning of the inner
field.
Auto Trait Implementations§
impl<T> Freeze for AlwaysSend<T>where
T: Freeze,
impl<T> RefUnwindSafe for AlwaysSend<T>where
T: RefUnwindSafe,
impl<T> Sync for AlwaysSend<T>where
T: Sync,
impl<T> UnwindSafe for AlwaysSend<T>where
T: UnwindSafe,
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<F> FutureExt for F
impl<F> FutureExt for F
fn always_send(self) -> AlwaysSend<Self> ⓘ
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<S> StreamExt for S
impl<S> StreamExt for S
Source§fn always_send(self) -> AlwaysSend<Self> ⓘ
fn always_send(self) -> AlwaysSend<Self> ⓘ
stream
only.