Reputation: 5732
I am getting this issue, as the variables I am deconstructing are borrowed(?) and can't be used in another method. This sounds like a very typical use case but I am not sure how to solve it.
`➜ hello_cargo git:(master) ✗ cargo build
Compiling hello_cargo v0.1.0 (/Users/johnny/Projects/hello_cargo)
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:24:39
|
24 | let DBAndCFs { db: _, cfs } = self.db.lock().as_ref().unwrap();
| ^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
25 | cfs.len()
| --------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
`
Here is the code that generates this issue:
use parking_lot::Mutex;
struct CF {
inner: *mut i32,
}
struct DBAndCFs {
db: i32,
cfs: Vec<CF>,
}
struct DB {
db: Mutex<Option<DBAndCFs>>,
}
impl DB {
pub fn open() -> DB {
DB {
db: Mutex::new(Some(DBAndCFs{ db: 0, cfs: Vec::new() } )),
}
}
pub fn get(&self) -> usize {
let DBAndCFs { db: _, cfs } = self.db.lock().as_ref().unwrap();
cfs.len()
}
}
fn main() {
let db = DB::open();
print!("{}", db.get());
}
Upvotes: 0
Views: 9096
Reputation: 8544
temporary value is freed at the end of this statement
consider using a let binding to create a longer lived value
So the compiler is telling you that self.db.lock()
is a temporary that gets dropped too early, and that you can extend its lifetime with a let
binding. The advice is so precise that you could even follow it without knowing what's going on:
let db = self.db.lock();
let DBAndCFs { db: _, cfs } = db.as_ref().unwrap();
cfs.len()
The reason here is that self.db.lock()
creates a mutex guard, that keeps the mutex locked until it is dropped. If you give it a variable to live in, that variable will exist to the end of the scope (the next }
), and the guard won't be dropped long enough for you to call cfs.len()
. If you don't give it a variable to live in, it will live as a temporary, until the next ;
. Since you're trying to keep a reference to cfs
beyond that ;
, you'd have a reference to something protected by a mutex without the mutex being locked, which can't be allowed.
The other way to do what you want to call len
before your temporary lock guard is dropped:
self.db.lock().as_ref().unwrap().cfs.len()
Upvotes: 7