Full code at: https://github.com/brunoczim/lcalc
Consider this code (it is a beta-reduction function):
pub fn replace(&mut self, name: &Rc<str>, val: &Self) {
let mut stack = Vec::with_capacity(8);
stack.push(self);
while let Some(refer) = stack.pop() {
match refer {
Var(sym) => match sym {
Dyn(s) => {
if &**s == &**name {
*refer = val.clone();
}
},
Static(s) => {
if Rc::ptr_eq(s, name) {
*refer = val.clone();
}
},
},
App(fun, arg) => {
stack.reserve(2);
stack.push(fun);
stack.push(arg);
},
Lambda(_, body) => {
stack.push(body);
},
}
}
}
I first wrote this code in April, and it did use to compile. However, if a try to compile it with a recent compiler, I get this error:
error[E0506]: cannot assign to `*refer` because it is borrowed
--> src/eval.rs:108:29
|
105 | Var(sym) => match sym {
| --- borrow of `*refer` occurs here
...
108 | *refer = val.clone();
| ^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `*refer` occurs here
error[E0506]: cannot assign to `*refer` because it is borrowed
--> src/eval.rs:113:29
|
105 | Var(sym) => match sym {
| --- borrow of `*refer` occurs here
...
113 | *refer = val.clone();
| ^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `*refer` occurs here
error: aborting due to 2 previous errors
I found that weird, so I tried to compile it with a April built Rust compiler.
cargo +nightly-2018-04-30 build
And it works!
Why is this happening? Isn't this a bad breaking change? And how can I fix my nowadays code? It seems impossible.