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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With