use std::sync::Mutex;
struct A {
b: Mutex<B>,
}
struct B {
c: Mutex<C>,
}
struct C {
x: i32,
}
fn main() {
let a = A {
b: Mutex::new(B {
c: Mutex::new(C { x: 1 }),
}),
};
let mut b = a.b.lock().unwrap();
let mut c = b.c.lock().unwrap();
drop(c);
drop(b);
b = a.b.lock().unwrap();
c = b.c.lock().unwrap();
println!("{}", c.x);
}
I expected to see this happen: code compiles fine
Instead, this happened:
error[E0505]: cannot move out of `b` because it is borrowed
--> src/main.rs:26:10
|
23 | let mut c = b.c.lock().unwrap();
| - borrow of `b` occurs here
...
26 | drop(b);
| ^ move out of `b` occurs here
...
29 | c = b.c.lock().unwrap();
| - borrow might be used here, when `c` is dropped and runs the `Drop` code for type `MutexGuard`
error[E0506]: cannot assign to `b` because it is borrowed
--> src/main.rs:28:5
|
23 | let mut c = b.c.lock().unwrap();
| - borrow of `b` occurs here
...
28 | b = a.b.lock().unwrap();
| ^ assignment to borrowed `b` occurs here
29 | c = b.c.lock().unwrap();
| - borrow might be used here, when `c` is dropped and runs the `Drop` code for type `MutexGuard`
|
= note: borrow occurs due to deref coercion to `B`
note: deref defined here
--> /home/slomo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/mutex.rs:470:5
|
470 | type Target = T;
| ^^^^^^^^^^^^^^^^
Removing the usage of c in the very end (the println!) makes the code compile as expected, but that's of course not useful:
I tried this (minimalized) code:
I expected to see this happen: code compiles fine
Instead, this happened:
Removing the usage of
c
in the very end (theprintln!
) makes the code compile as expected, but that's of course not useful:Similarly not dropping
b
and reassigning it later also compiles fine (i.e. the dropping/reassigning ofc
can stay around):The borrow of
b
should've been released by thedrop(c)
but that's apparently not the case for some reason.Meta
rustc --version --verbose
: