Struct AlwaysSend

Source
#[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>

Source

pub fn new(inner: T) -> Self

Wraps sendable type in the AlwaysSend<T> wrapper.

Source

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.

Source

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.

Source

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().

Source

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().

Source§

impl<T> AlwaysSend<T>

Source

pub fn inner_pin(self: Pin<&Self>) -> Pin<&T>

Pinned access to self.inner.

Source

pub fn inner_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>

Pinned mutable access to self.inner.

Trait Implementations§

Source§

impl<T: Send> From<T> for AlwaysSend<T>

Source§

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.
Source§

fn is_terminated(&self) -> bool

Returns true if the underlying future should no longer be polled.
Source§

impl<S: FusedStream> FusedStream for AlwaysSend<S>

Available on crate feature stream only.
Source§

fn is_terminated(&self) -> bool

Returns true if the stream should no longer be polled.
Source§

impl<F: Future> Future for AlwaysSend<F>

Source§

type Output = <F as Future>::Output

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more
Source§

impl<S: Stream> Stream for AlwaysSend<S>

Available on crate feature stream only.
Source§

type Item = <S as Stream>::Item

Values yielded by the stream.
Source§

fn poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the current task for wakeup if the value is not yet available, and returning None if the stream is exhausted. Read more
Source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
Source§

impl<T> Send for AlwaysSend<T>

This is the main feature, an implementation of Send without reqiring T: Send.

Source§

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<!> for T

Source§

fn from(t: !) -> T

Converts to this type from the input type.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<F> FutureExt for F
where F: Future + Send,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F> IntoFuture for F
where F: Future,

Source§

type Output = <F as Future>::Output

The output that the future will produce on completion.
Source§

type IntoFuture = F

Which kind of future are we turning this into?
Source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
Source§

impl<S> StreamExt for S
where S: Stream + Send,

Source§

fn always_send(self) -> AlwaysSend<Self>

Available on crate feature stream only.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<F, T, E> TryFuture for F
where F: Future<Output = Result<T, E>> + ?Sized,

Source§

type Ok = T

The type of successful values yielded by this future
Source§

type Error = E

The type of failures yielded by this future
Source§

fn try_poll( self: Pin<&mut F>, cx: &mut Context<'_>, ) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T, E> TryStream for S
where S: Stream<Item = Result<T, E>> + ?Sized,

Source§

type Ok = T

The type of successful values yielded by this future
Source§

type Error = E

The type of failures yielded by this future
Source§

fn try_poll_next( self: Pin<&mut S>, cx: &mut Context<'_>, ) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more