Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I solve "lifetime of reference outlives lifetime of borrowed content" in the following context?

I have the following struct in my lib.rs

pub enum ConfigurationSource {
    StringContent(String),
    FileContent(PathBuf)    
}

pub struct ConfigurationBuilder<'a> {
    config: Value,
    bundles: HashMap<&'a str, &'a Vec<ConfigurationSource>>    
}

impl<'a> ConfigurationBuilder<'a>{
    pub fn new(base_source: &ConfigurationSource) -> ConfigurationBuilder{
        let base_config: Value = from_str("{}").unwrap();

        let mut config_builder = ConfigurationBuilder{
            config: base_config,
            bundles: HashMap::new()
        };

        config_builder.merge_source(&base_source);

        return config_builder;
    }

    //more code here

    pub fn define_bundle(&mut self, bundle_key: &str, sources: &Vec<ConfigurationSource>){
        self.bundles.insert(bundle_key, sources);
    }
}

I do not want the bundles Hashmap in the ConfigurationBuilder instances to own the bundle_keys or sources passed into the define_bundle method.

I get the following two compile errors at build time

error[E0312]: lifetime of reference outlives lifetime of borrowed content...
  --> src\lib.rs:67:41
   |
67 |         self.bundles.insert(bundle_key, sources);
   |                                         ^^^^^^^
   |
note: ...the reference is valid for the lifetime 'a as defined on the impl at 27:1...
  --> src\lib.rs:27:1
   |
27 | / impl<'a> ConfigurationBuilder<'a>{
28 | |
29 | |     pub fn new(base_source: &ConfigurationSource) -> ConfigurationBuilder{
30 | |         let base_config: Value = from_str("{}").unwrap();
...  |
89 | |     }
90 | | }
   | |_^
note: ...but the borrowed content is only valid for the anonymous lifetime #3 defined on the method
 body at 66:5
  --> src\lib.rs:66:5
   |
66 | /     pub fn define_bundle(&mut self, bundle_key: &str, sources: &Vec<ConfigurationSource>){
67 | |         self.bundles.insert(bundle_key, sources);
68 | |     }
   | |_____^

error[E0312]: lifetime of reference outlives lifetime of borrowed content...
  --> src\lib.rs:67:29
   |
67 |         self.bundles.insert(bundle_key, sources);
   |                             ^^^^^^^^^^
   |
note: ...the reference is valid for the lifetime 'a as defined on the impl at 27:1...
  --> src\lib.rs:27:1
   |
27 | / impl<'a> ConfigurationBuilder<'a>{
28 | |
29 | |     pub fn new(base_source: &ConfigurationSource) -> ConfigurationBuilder{
30 | |         let base_config: Value = from_str("{}").unwrap();
...  |
89 | |     }
90 | | }
   | |_^
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method
 body at 66:5
  --> src\lib.rs:66:5
   |
66 | /     pub fn define_bundle(&mut self, bundle_key: &str, sources: &Vec<ConfigurationSource>){
67 | |         self.bundles.insert(bundle_key, sources);
68 | |     }
   | |_____^

What am I doing wrong?

like image 495
Harindaka Avatar asked Nov 12 '17 11:11

Harindaka


1 Answers

Your input parameters for define_bundle have lifetimes that the compiler does not know either meet, or outlive the ones defined for the struct.

Telling the compiler they expect the same lifetimes will do the trick:

pub fn define_bundle(&mut self, bundle_key: &'a str, sources: &'a Vec<ConfigurationSource>) {
    //                                       ^^----------------^^ same lifetimes as the struct fields expect
    self.bundles.insert(bundle_key, sources);
}
like image 125
Simon Whitehead Avatar answered Oct 16 '22 10:10

Simon Whitehead