I am about to convert some code from futures-0.1 to futures-0.3 where the poll()
methods require pinned data now. Some of my structs are unpinnable which complicates the porting. But there seems to exist an easy way by adding an impl Unpin
for these classes. Is this safe? What are the alternatives?
Example code:
extern crate futures;
use std::future::Future;
use std::pin::Pin;
use std::task::{ Poll, Context };
struct InnerData {
_pin: std::marker::PhantomPinned,
}
struct Stream {
}
struct Poller {
_data: InnerData,
file: Stream,
}
impl futures::stream::Stream for Stream {
type Item = ();
fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Option<Self::Item>> {
Poll::Pending
}
}
impl Future for Poller {
type Output = Result<(), ()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>
{
use crate::futures::Stream;
// here, rust fails with
// error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `Poller`
Pin::new(&mut self.get_mut().file).poll_next(cx).is_ready();
Poll::Pending
}
}
// Activating this seems to be an easy workaround...
// impl std::marker::Unpin for Poller {}
fn main() {
}
I use futures-0.3.1
and rust-1.40.0
.
unsafe
, asSend
orSync
are, but I also struggle to understand all thisPin
business. – Zlatoust