Here is a situation I imagine comes up often, and I haven't been able to get lifetime annotations consistent with it:
- A
Parent
struct has aVec
ofChild
struct-instances - Each
Child
has a reference to some other data fromParent
- Each
Parent
s children-vector is initially empty, thenChild
ren are created and added to it
Simplified version, in which the sole Child
member is a string-reference to its Parent
's (string) name
. (Real cases of course have many more members.)
struct Child<'a> {
parents_name: &'a str,
}
impl<'a> Child<'a> {
fn new(p: &'a Parent) -> Self {
Child {parents_name: &p.name}
}
}
struct Parent<'a> {
name: String,
children: Vec<Child<'a>>,
}
impl<'a> Parent<'a> {
fn new() -> Self {
Parent {
name: "something".to_string(),
children: vec![],
}
}
fn add(&mut self) {
let c = Child::new(self);
self.children.push(c);
}
}
fn main() {
let mut p = Parent::new();
p.add();
}
Generates these errors:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:22:17
|
22 | let c = Child::new(self);
| ^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 21:5...
--> src/main.rs:21:5
|
21 | / fn add(&mut self) {
22 | | let c = Child::new(self);
23 | | self.children.push(c);
24 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:22:28
|
22 | let c = Child::new(self);
| ^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 14:6...
--> src/main.rs:14:6
|
14 | impl<'a> Parent<'a> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:23:28
|
23 | self.children.push(c);
| ^
= note: expected `Child<'a>`
found `Child<'_>`
error: aborting due to previous error
Playground: Rust Playground
Each Child
clearly does not live "as long as" (perhaps more accurately "as early as") its Parent
. But the references to parents_name
of course life exactly as long as the Parent
.
Nonetheless it doesn't seem a single lifetime specifier 'a
for both Parent
and Child
covers this.
What would make this work? Some combination of separate lifetimes for Parent
and Child
, and constraints between them?