Rohit kumar
Rohit kumar

Reputation: 23

Temporary value dropped while borrowed in rust program

In module db.rs , while reading the value from the DataBase, i got the Error temporary value dropped while borrowed consider using a let binding to create a longer lived value

use bytes::Bytes;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[derive(Clone, Debug)]
pub struct Db {
    // pub entries: Arc<bool>,
    pub entries: Arc<Mutex<HashMap<String, Bytes>>>,
}
impl Db {
    pub fn new() -> Db {
        Db {
            entries: Arc::new(Mutex::new(HashMap::new())),
        }
    }
    /// Reads data from the database
    pub fn read(&mut self, arr: &[String]) -> Result<Bytes, &'static str> {
        let key = &arr[1];
        let query_result = self.entries.lock().unwrap().get(key);// Error in this Line.

        if let Some(value) = query_result {
            return Ok(Bytes::from("hello"));
        } else {
            return Err("no such key found");
        }
    }
}

but when i modify the code and trying to get the value in the next line, it didn't give any error.

let query_result = self.entries.lock().unwrap();
let result =  query_result.get(key);

can anyone help me understand what's going on under the hood?

Upvotes: 1

Views: 674

Answers (1)

isaactfa
isaactfa

Reputation: 6651

We can see why Rust thinks this is an error by checking how Mutex::lock works. If successful, it doesn't return a reference directly, it returns a MutexGuard struct that can deref into the type it wraps, a HashMap in your case.

The signature of Deref::deref<Target = T> is (with the elided lifetimes added):

fn deref<'a>(&'a self) -> &'a T

This means that the MutexGuard can only give us a reference to the HashMap inside for as long as it is itself alive (the lifetime 'a). But because you never store it anywhere, instead dereferencing it directly, Rust thinks that it gets dropped right after the call to get. But you keep the result of get around, which can only live for as long as the reference to the HashMap passed into it, which in turn only lives as long as the MutexGuard which gets dropped immediately.

If you store the MutexGuard, on the other hand, like

let guard = self.entries.lock().unwrap();
let query_result = guard.get(key);

it only gets dropped at the end of the scope, so any references it gave out are also valid until the end of the scope.

Upvotes: 2

Related Questions