3 ms·
Yes, allowing this to execute would be very unsound: let lock = RwLock::new(Box::new(111)); let r: &i32 = &**lock.read().unwrap(); // points to 111
by anderskaseorg 2y ago
Yes, allowing this to execute would be very unsound:
let lock = RwLock::new(Box::new(111));
let r: &i32 = &**lock.read().unwrap(); // points to 111
*lock.write().unwrap() = Box::new(222); // allocates a new Box and deallocates 111
println!("{}", *r); // use after free
- NobodyNada 2y agoIt can be done safely with an upgrade method that requires an owned read guard. The RwLock implementation provided by the parking_lot crate supports this safely: let lock = RwLock::new(Box::new(111)); let read = lock.upgradable_read(); let r: &i32 = &**read; // points to 111 *RwLockUpgradableReadGuard::upgrade(read) = Box::new(222); // error[E0505]: cannot move out of `read` because it is borrowed println!("{}", *r);
- anderskaseorg 2y agoOf course (but that’s not relevant to the original scenario, where the programmer is hypothetically not aware that the read lock is still being held, let alone that they could manually upgrade it after changing to a different lock library).
- kelnos 2y agoThe problem is that in the 'if let' case, the 'else' block has no access to the read guard. It's out of scope, except that the compiler hasn't dropped it yet.