I am experimenting with Rust and ran into something very unexpected.
If I wrap state in a RwLock, then I cannot combine two statements using this state into a single one. If I remove the RwLock and use state directly, this works.
use parking_lot::{RwLock};
pub struct State {
pub current: u8,
pub history: Vec<u8>,
}
fn main() {
let locked = RwLock::new(
State {
current: 10,
history: Vec::new(),
});
// type: lock_api::rwlock::RwLockWriteGuard<parking_lot::raw_rwlock::RawRwLock, playground::State>
let mut state = locked.write();
// Works as two statements
let old = std::mem::replace(&mut state.current, 5);
state.history.push(old);
// Fails as one statement
// Error: cannot borrow `state` as mutable more than once at a time
state.history.push(std::mem::replace(
&mut state.current,
5,
));
}
Can someone explain what is happening?
EDIT: I have seen answers like Error while trying to borrow 2 fields from a struct wrapped in RefCell. This is not the same question! This is about code that becomes invalid if and only if two statements are nested. Something that I have only seen in Rust and no other language.
This artifaft also only appears when an RwLock is used.