Reborrow mutably help?


#1

So I am learning Rust by writing a NES emulator. I have implemented a Bus trait which allows all my structs to talk to other structs via read and write methods. Everything was going great until I added a step function which requires a mut ref to self and then will call the step functions of the other parts (cpu, ppu, etc.)

 // step one cycle - for debugging
pub fn step(&mut self) {
    self.cpu.step(&mut self, 1);
                       ^^^^
                       |
                       cannot reborrow mutably
                       try removing `&mut` here

I get a “cannot reborrow mutably try removing ‘&mut’ here” but these objects need to be mutable, when the cpu steps it will change its state. So will the ppu and any other objects.

Here is a link to the file nes

I implemented Bus for Nes and have the proper lifetimes, but how does one group calls to several objects while passing itself mutably?

Should I somehow redesign so the ram and Bus implementation are included with the cpu?

I am using the 1.21 Rust. I have no other errors anywhere else.


#2

self in this function is already a mutable reference (&mut Self). You’re trying to make &mut &mut Self.


#3

If I change to just self I get a ‘second mutable borrow occurs here’ at the call to self.cpu.step.


#4

That’s because self.cpu is the first borrow:

self.cpu.step(arg, 1);

is implemented as:

let tmp = &mut self.cpu;
P65::step(tmp, arg, 1);

So you end up with self borrowed in two places — once for self.cpu, and second time for step argument. That makes one value mutable in two places (via self of step and step's arg.cpu), which is not allowed by the borrow checker.

You’ll have to rethink ownership here to be a tree, without cycles. Unfortunately that’s the part of Rust where you have to design things “the Rust way” in order to fit the borrow checker rather than fight it.

Why does CPU need Nes? Can it be a third “state” object? (you could borrow self.cpu and self.state in one function at the same time).


#5

I can change the design. I just wanted to make sure I wasn’t missing something silly. I’ve never seen reborrow mutably error before.