Avoiding multiple mutable borrows

Hello there!
I might have run into an rather uncomfortable problem here

Let me show you my code first:

pub struct StackMachine<'a> {
    values: u128,
    operations: &'a Vec<Code>,
    stack: Vec<bool>,
}

impl<'a> StackMachine<'a> {
    ...
    fn push(&mut self, value: bool) {
        self.stack.push(value);
    }

    fn pop(&mut self) -> bool {
        self.stack.pop().expect("Failed to pop from empty stack")
    }

    fn evaluate(mut self) -> bool {
        use Code::*;
        for op in self.operations.into_iter() {
            match *op {
                And => self.push(self.pop() && self.pop()),
                ....
            }
        }
        ...

the important part is

self.push(self.pop() && self.pop())

because here I get the error message:

error[E0499]: cannot borrow `self` as mutable more than once at a time
  --> src/stack_machine.rs:30:34
   |
30 |                 And => self.push(self.pop() && self.pop()),
   |                        ---- ---- ^^^^ second mutable borrow occurs here
   |                        |    |
   |                        |    first borrow later used by call
   |                        first mutable borrow occurs here

what a pity. I seem to have pushed the rules a little too much, I really thought that this was an elegent way to solve this though.

I am not exacly sure what prevents me from doing this, since the executed code never seems to have mutable asses from to places at any given time.

Lets briefly summarize, what I want to do:

I have push and pop implemented as mutable methods.
I have mut self and want to call
push(pop && pop)

but the borrow checker sees that as severel mutable borrows at the same time.

Thank you for taking the precious time and reading trough this.
Have a nice and enjoyable day!

1 Like

This is a known shortcoming of current borrow checker. To workaround, simply splitting it to two statements will work. And yes, this is more like bug not feature, and I hope it will be fixed when the Polonius, a MIR-based borrow checker arrives.

2 Likes

Thank you for pointing me to polonius, who would have guessed that the solution is so simple after all :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.