Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap key does not live long enough

I'm trying to use a HashMap<String, &Trait> but I have an error message I don't understand. Here's the code (playground):

use std::collections::HashMap;

trait Trait {}

struct Struct;

impl Trait for Struct {}

fn main() {
    let mut map: HashMap<String, &Trait> = HashMap::new();
    let s = Struct;
    map.insert("key".to_string(), &s);
}

Here's the error I'm getting:

error[E0597]: `s` does not live long enough
  --> src/main.rs:12:36
   |
12 |     map.insert("key".to_string(), &s);
   |                                    ^ borrowed value does not live long enough
13 | }
   | - `s` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

What's happening here? Is there a workaround?

like image 921
franza Avatar asked Aug 24 '15 00:08

franza


1 Answers

This issue was solved with non-lexical lifetimes, and should not be a concern from Rust 2018 onwards. The answer below is relevant for people using older versions of Rust.


map outlives s, so at some point in map's life (just before destruction), s will be invalid. This is solvable by switching their order of construction, and thus of destruction:

let s = Struct;
let mut map: HashMap<String, &Trait> = HashMap::new();
map.insert("key".to_string(), &s);

If you instead want the HashMap to own the references, use owned pointers:

let mut map: HashMap<String, Box<Trait>> = HashMap::new();
let s = Struct;
map.insert("key".to_string(), Box::new(s));
like image 71
Veedrac Avatar answered Nov 07 '22 09:11

Veedrac