2

This Rust code works:

let a = self.stack.pop_or_err()?;
let b = self.stack.pop_or_err()?;
self.stack.push(a * b);

(The ?s are unimportant, just an application detail.)

If i turn it into:

self.stack.push(self.stack.pop_or_err()? * self.stack.pop_or_err()?);

the I see:

error[E0499]: cannot borrow `self.stack` as mutable more than once at a time
   --> src/question2.rs:121:33
    |
121 |                 self.stack.push(self.stack.pop_or_err()? + self.stack.pop_or_err()?);
    |                 ----------------^^^^^^^^^^^^^^^^^^^^^^^-----------------------------
    |                 |          |    |
    |                 |          |    second mutable borrow occurs here
    |                 |          first borrow later used by call
    |                 first mutable borrow occurs here

error[E0499]: cannot borrow `self.stack` as mutable more than once at a time
   --> src/question2.rs:121:60
    |
121 |                 self.stack.push(self.stack.pop_or_err()? + self.stack.pop_or_err()?);
    |                 -------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^--
    |                 |          |                               |
    |                 |          |                               second mutable borrow occurs here
    |                 |          first borrow later used by call
    |                 first mutable borrow occurs here

Is there a one-line form of calling a method on a mut reference which uses the reference in arguments in the method call?

fadedbee
  • 42,671
  • 44
  • 178
  • 308

1 Answers1

1

As @Netwave mentioned, I don't think there's a clean way to do this, but I have the following gibberish which does the trick:

(|x: i32, v: &mut Vec<i32>| v.push(x))(v.pop()? * v.pop()?, &mut v);

Each call to pop takes a mutable reference, but then drops it, so we can do the product in one expression. However, passing the mutable reference to v will hold on to it, so we must pass that to the closure second. This is also why we have to pass &mut v to the closure explicitly rather than capturing it. I believe the reason for using the push method directly not working is that it takes &mut self as the first argument.

I by no means recommend this! But it is possible.

Cruz Jean
  • 2,761
  • 12
  • 16