Cannot borrow as immutable because it is also borrowed as mutable in function arguments

This line:

n.set(n.get() + 1);

is desugared into

Number::set(&mut n, n.get() + 1);

The error message might be a bit more clear now:

error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable
  --> <anon>:18:25
   |
18 |     Number::set(&mut n, n.get() + 1);
   |                      -  ^          - mutable borrow ends here
   |                      |  |
   |                      |  immutable borrow occurs here
   |                      mutable borrow occurs here

As Rust evaluates arguments left to right, that code is equivalent to this:

let arg1 = &mut n;
let arg2 = n.get() + 1;
Number::set(arg1, arg2);

Editor's note: This code example gives an intuitive sense of the underlying problem, but isn't completely accurate. The expanded code still fails even with non-lexical lifetimes, but the original code compiles. For the full description of the problem, review the comments in the original implementation of the borrow checker

It should now be obvious what is wrong. Swapping those first two lines fixes this, but Rust does not do that kind of control-flow analysis.

This was first created as bug #6268, now it is integrated into RFC 2094, non-lexical-lifetimes. If you use Rust 1.36 or newer, NLL is enabled automatically and your code will now compile without an error.

See also:

  • Why is a mutable borrow in an argument disallowed for a mutable method call?