Вторая изменяемая ошибка заимствования исчезает после введения волшебной строки

#rust #rust-tokio

#Ржавчина #rust-tokio

Вопрос:

Это моя структура (для полноты картины):

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

Затем я реализовал a Future для структуры, но изменил self на me via let me = amp;mut *self; .
Это компилируется нормально:

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

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

        while me.stage == 1 {
            let self_n = me.n;
            let mut rb = ReadBuf::new(amp;mut me.buf[..self_n]);
            let n = ready!(Pin::new(amp;mut me.socket).poll_read(cx, amp;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<amp;mut Self>, cx: amp;mut Context<'_>) -> Poll<Self::Output> {

        // magic line removed
        
        while self.stage == 1 {
            let self_n = self.n;
            let mut rb = ReadBuf::new(amp;mut self.buf[..self_n]);
            let n = ready!(Pin::new(amp;mut self.socket).poll_read(cx, amp;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(amp;mut self.buf[..RES.len() - self_n]);
   |                                            ---- first mutable borrow occurs here
85 |             let n = ready!(Pin::new(amp;mut self.socket).poll_read(cx, amp;mut rb));
   |                                          ^^^^                       ------- first borrow later used here
   |                                          |
   |                                          second mutable borrow occurs here
  

Что это такое, из-за let me = amp;mut *self; чего оно компилируется?

Ответ №1:

Как видно из этого потока, изменяемое заимствование элемента a Pin требует использования его DerefMut реализации, которая изменчиво заимствует все Pin . Таким образом, вы не можете изменчиво заимствовать 2 поля, даже если они не пересекаются. Строка let me = amp;mut *self (или альтернативно let me = amp;mut self ) использует Pin DerefMut реализацию ‘s для генерации a amp;mut Self из Pin<amp;mut Self> . Это происходит только один раз, затем через это изменяемое заимствование заимствуются два непересекающихся поля, что не приводит к ошибкам.