I have a crate foo
that has implemented Future
on SendFuture
.
I have another crate bar
that needs to add a thin wrapper around foo::SendFuture
(mostly meant to convert error codes). In bar
's source:
#[repr(transparent)]
pub struct SendFuture<E>(foo::SendFuture<E>);
impl<E> Future for SendFuture<E> {
type Output = Result<(), Error<E>>;
fn poll(
mut self: Pin<&mut Self>,
ctx: &mut Context<'_>
) -> Poll<Self::Output> {
match Pin::new(&mut self.0).poll(ctx) {
Poll::Ready(res) => Poll::Ready(res.map_err(Error::from)),
Poll::Pending => Poll::Pending
}
}
}
Along comes the need for crate baz
, which does mostly the same thing -- but it adds some features that requires another generic, but it is unused in the SendFuture
wrapper. Rust needs the generic to be referenced so a PhantomData
is added. This wrapper has mostly the role of converting bar::Error
to baz::Error
.
In baz
's source:
pub struct SendFuture<R, E> {
inner: bar::SendFuture<E>,
_marker: PhantomData<R>
}
impl<R, E> Future for SendFuture<R, E> {
type Output = Result<(), Error<E>>;
fn poll(
mut self: Pin<&mut Self>,
ctx: &mut Context<'_>
) -> Poll<Self::Output> {
match Pin::new(&mut self.inner).poll(ctx) {
Poll::Ready(res) => Poll::Ready(res.map_err(Error::from)),
Poll::Pending => Poll::Pending
}
}
}
Unlike the wrapper in bar
, the one in baz
does not compile:
error[E0596]: cannot borrow data in dereference of `Pin<&mut SendFuture<E>>` as mutable
--> src/send.rs:177:20
|
177 | match Pin::new(&mut self.inner).poll(ctx) {
| ^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut SendFuture<E>>`
The two are almost identical, except for bar
's SendFuture
having a single member and being repr(transparent)
, while baz
's has multiple members (albeit one is a PhantomData
). I thought I had a vague idea what pinning does, but I need someone to explain why baz
's wrapper doesn't work.
XY: I know I can just stick the the call that returns SendFuture
in baz
in an async
method and not bother doing the manual Future
implementation. This question is just for curiosa.