Hi,
it's my first post in this forum and I'm also very new to Rust. While fiddling around to become familiar with the language I've come across a lifetime problem that I can't get my head around.
The program is very simple. I have a Node and and Element struct, the Element is supposed to store a reference to a Node. I also have a generator element which creates a Node and and Element (which references the created node) and returns (moves) both in a tuple.
struct Node {
x: f64,
y: f64
}
struct Element<'a> {
node: &'a Node
}
fn generate_element() -> (Element, Node) {
let n = Node { x: 10.0, y: 42.0 };
(Element { node: &n }, n)
}
fn main() {
let (n, e) = generate_element();
}
However, when I try to compile this I get the following error message:
error[E0106]: missing lifetime specifier
--> src/main.rs:10:27
|
10 | fn generate_element() -> (Element, Node) {
| ^^^^^^^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
If I try to add a lifetime parameter
fn generate_element<'a>() -> (Element<'a>, Node) {
let n = Node { x: 10.0, y: 42.0 };
(Element { node: &n }, n)
}
I get the following error
error[E0597]: `n` does not live long enough
--> src/main.rs:12:23
|
12 | (Element { node: &n }, n)
| ^ does not live long enough
13 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 10:1...
--> src/main.rs:10:1
|
10 | / fn generate_element<'a>() -> (Element<'a>, Node) {
11 | | let n = Node { x: 10.0, y: 42.0 };
12 | | (Element { node: &n }, n)
13 | | }
| |_^
Fair enough, it somehow makes sense for me that I should inform the compiler that the returned Node lives as long as Element, so I tried to annotate Node as well
fn generate_element<'a>() -> (Element<'a>, Node<'a>) {
let n = Node { x: 10.0, y: 42.0 };
(Element { node: &n }, n)
}
but then I get
error[E0107]: wrong number of lifetime parameters: expected 0, found 1
--> src/main.rs:10:44
|
10 | fn generate_element<'a>() -> (Element<'a>, Node<'a>) {
| ^^^^^^^^ unexpected lifetime parameter
This is somehow confusing for me. I may not have a good understanding of the lifetime parameters, but for me the lifetime of both the Element and the Node should be the same since I move both of them out of the function. The only thing that might be an issue is the destruction of the tuple when it goes out of scope (after the main function returns), since I believe that Node must outlive the Element. I tried to permute the returned tuple so that Node comes first etc. but it didn't solve the compiler error.
I also tried
fn generate_element<'a, 'b: 'a>() -> (Element<'a>, Node<'b>) {
let n = Node { x: 10.0, y: 42.0 };
(Element { node: &n }, n)
}
which, to my understanding, should assure the compiler that Node lives at least as long as Element, but it tells me that Node has an unexpected lifetime parameter.
I'm out of ideas and I would really appreciate if someone could help me with this issue or atleast clarify what the actual issue is here