Today I got pissed with Rust’s infamous borrow checker. I know that it’s always the developers’s fault and that the borrow checker is always right. But I got a bit emotional with this one.
This is valid (1):
match opcode {
0x01 => {
let bytes = self.read_next_16bits(); // Requires mutable, since it changes internal state
self.ld(RegCode::BC, bytes); // Also requires mutable
},
// ... other cases
}
This is not valid (2):
match opcode {
0x01 => self.ld(RegCode::BC, self.read_next_16bits()),
}
The borrow checker is complaining with the following message: cannot borrow *self as mutable more than once at a time second mutable borrow occurs here
After searching around and asking members of the community, I got to this issue on GitHub that explains the issue pretty well. You cannot reference a second mutable
after the first lexically. But my problem is that the first reference should be resolved completely before the second is needed, and therefore shouldn’t be a problem to deference once you can the second method.
Here’s a poorly drawn stack:
STACK =>
1. main
1. read_next_16bits() <- Has mutable reference
2. main
1. main <- Receives mutable reference
1. ld() <- Has mutable reference
2. main
Theoretically, the call stack should be exactly the same on both scenarios. But when Rust desugars the code, &mut self
parameters are requested directly on the parameter list. Therefore the first call to the &mut self
happens for the second method to be called, and this is the main reason why this fails. Which is a bit frustrating in my opinion, because my code will not look as tidy as it was before.
If you hated this post, and can't keep it to yourself, consider sending me an e-mail at fred.rbittencourt@gmail.com or complain with me at Twitter X @derfrb. I'm also occasionally responsive to positive comments.