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

Viewed 2572

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?

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);
}
Related