Search code examples
rustrust-tokio

Second mutable borrow error disapears after introducing a magic line


This is my struct (for completeness sake):

struct Client<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin
{
    socket: T,
    stage: u8,
    n: usize,
    buf: &'a mut [u8],
}

I then implemented a Future for the struct, but changed self to me via let me = &mut *self;. This compiles fine:

impl<'a, T> Future for Client<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin
{
    type Output = io::Result<()>;
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

        let me = &mut *self; // <<<<<<<<<< this fixes it, how?!

        while me.stage == 1 {
            let self_n = me.n;
            let mut rb = ReadBuf::new(&mut me.buf[..self_n]);
            let n = ready!(Pin::new(&mut me.socket).poll_read(cx, &mut rb));
        }
        Poll::Pending
    }
}

however, if I remove that conversion, it will trigger a borrow checker error:

impl<'a, T> Future for Client<'a, T>
where
    T: AsyncRead + AsyncWrite + Unpin
{
    type Output = io::Result<()>;
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

        // magic line removed
        
        while self.stage == 1 {
            let self_n = self.n;
            let mut rb = ReadBuf::new(&mut self.buf[..self_n]);
            let n = ready!(Pin::new(&mut self.socket).poll_read(cx, &mut rb));
        }
        Poll::Pending
    }
}
error[E0499]: cannot borrow `self` as mutable more than once at a time
  --> z.rs:y:x
   |
84 |             let mut rb = ReadBuf::new(&mut self.buf[..RES.len() - self_n]);
   |                                            ---- first mutable borrow occurs here
85 |             let n = ready!(Pin::new(&mut self.socket).poll_read(cx, &mut rb));
   |                                          ^^^^                       ------- first borrow later used here
   |                                          |
   |                                          second mutable borrow occurs here

What is it about let me = &mut *self; that gets it compiled?


Solution

  • As seen in this thread, mutably borrowing an element of a Pin requires using its DerefMut implementation, which mutably borrows the entire Pin. Thus, you cannot mutably borrow 2 fields, even if they are disjoint. The line let me = &mut *self (or alternatively let me = &mut self) uses Pin's DerefMut implementation to generate a &mut Self from the Pin<&mut Self>. It only does this once, then two disjoint fields are borrowed through that mutable borrow, which leads to no errors.