Fredrb's Blog

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.

#rust

⇦ Back Home | ⇧ Top |

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.