error[E0597]: `cloned` does not live long enough
--> src/noc3.rs:185:9
|
185 | cloned.push(e);
| ^^^^^^ does not live long enough
...
189 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 170:1...
--> src/noc3.rs:170:1
|
170 | / impl<'a, Element: Nameable + Clone> Clone for NamedObjectsContainer<Element, &'a Element> {
171 | |
172 | | fn clone(&self) -> NamedObjectsContainer<Element, &'a Element> {
173 | | let cloned = NamedObjectsContainer::<Element, &Element>::new();
... |
189 | | }
190 | | }
| |_^
for this:
impl<'a, Element: Nameable + Clone> Clone for S<Element, &'a Element> {
fn clone(&self) -> S<Element, &'a Element> {
let cloned = S::<Element, &Element>::new();
let e = self.list.get(0).unwrap().clone();
cloned.push(e);
cloned
}
}
I don't understand why cloned object is living for the whole impl (that's the hint the error is giving) and borrow is not ending at the end of clone(). S is a container structure like a Vec:
pub struct S<Element, Collection> {
/// List of ELement structs
pub list: Vec<Element>,
/// Hashmap keeping track of the name vs. index of the structure in the previous list
pub hmap: HashMap<String, Collection>,
}
cloned lives for the whole impl, and beyond, because you're returning it. But your new is using an anonymous &Element lifetime. Does it work if you change that to &'a Element to match the return type?
If push takes &'a mut self, then this becomes kind of a permanent borrow, for the remaining 'a life of the type.
Your type looks like you're trying to create something self-referential, which is not generally supported. If hmap wants to hold references into list, any change to the list like pushing a new item will invalidate all those references. One option might be to map to indexes instead.
But if I use the hashmap to store indexes, I can't use the Index trait as I would like. I'd like the Index to return a reference on a vector of references or a reference.
A linked list would solve the specific problem of reallocation, but the borrow checker isn't analyzing that deeply. That signature of push will cause the same problem no matter what the underlying types and code are actually doing.
Yes but my struct is meant to be used with a reference or a vector of references. And in that case, I can't return a reference on a vector of references by if I use only indexes.
Actually, I decided to only use Vec and a HashMap of indexes, giving up the idea of implementing the Index trait with a &str, and implementing it only for an index.