How do I call a method that requires a pinned self from another method that has a pinned self?

740 Views Asked by At

I am implementing Tokio's AsyncRead for a struct, but the implementation is just a pass through to a contained struct. The implementation that I finally got to compile is:

use std::pin::Pin;

// A simplified version of Tokio's AsyncRead
trait Async {
    fn poll_read(self: Pin<&mut Self>);
}

struct Inner {}

impl Async for Inner {
    fn poll_read(self: Pin<&mut Self>) {
        // Actual implementation would be here
    }
}

struct Outer {
    inner: Inner,
}

impl Async for Outer {
    fn poll_read(self: Pin<&mut Self>) {
        // This is a wrapper implementation, just deferring to inner
        Pin::new(&mut self.get_mut().inner).poll_read()
    }
}

fn main() {
    let mut outer = Outer { inner: Inner {} };
    Pin::new(&mut outer).poll_read()
}

Rust Playground

There are libraries that hide some details of these pin handling issues (e.g. see the answer in No method named `poll` found for a type that implements `Future`), but I am trying to understand what is actually going on 'under the hood'. I have two related questions:

  1. Is there a cleaner way of doing Pin::new(&mut self.get_mut().io).? That seems a particularly convoluted way of showing the compiler that the struct inside a pinned struct is also Pin.

  2. This implementation is only possible because my struct is Unpin (otherwise I couldn't call get_mut()). How would I achieve this otherwise?

0

There are 0 best solutions below