引入魔术线后第二个可变借用错误消失

Second mutable borrow error disapears after introducing a magic line

这是我的结构(为了完整起见):

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

然后我为该结构实现了一个 Future,但通过 let me = &mut *self;self 更改为 me。 这编译得很好:

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
    }
}

但是,如果我删除该转换,它将触发借用检查器错误:

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

编译它的 let me = &mut *self; 是什么?

this thread 所示,可变地借用 Pin 的一个元素需要使用它的 DerefMut 实现,它可变地借用整个 Pin。因此,您不能可变地借用 2 个字段,即使它们是不相交的。行 let me = &mut *self(或者 let me = &mut self)使用 PinDerefMut 实现从 Pin<&mut Self> 生成 &mut Self。它只执行一次,then 通过 that 可变借用借用两个不相交的字段,这不会导致错误。