Search code examples
rustrust-tokio

Why can't I call poll_read() on tokio::fs::File?


I have a struct that encapsulates File struct and I want this struct to implement AsyncRead trait so it could be used instead of File in some other part of the code:

struct TwoWayFile<'a> {
    reader: &'a File,
}

impl<'a> AsyncRead for TwoWayFile<'a> {
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<io::Result<usize>> {
        self.reader.poll_read(cx, buf)
    }
}

According to the docs tokio::fs::File already implements tokio::io::AsyncRead but the compiler says the opposite:

error[E0599]: no method named `poll_read` found for reference `&'a tokio::fs::file::File` in the current scope
  --> src/main.rs:44:21
   |
44 |         self.reader.poll_read(cx, buf)
   |                     ^^^^^^^^^ method not found in `&'a tokio::fs::file::File`

What is missing here? Why I can't call the method that is already defined for File?


Solution

  • Your problem is likely that the poll_read method is implemented on Pin<&mut Self>, not on &self. This means you can only call it on a pinned mutable reference, and not a plain reference.

    You can pin your reference on the heap using Box::pin or on the "async stack" using the pin_mut! macro, and should then be able to call the method.