You are creating a temporary reference in the function &SimpleNode{...} which is freed once you leave the function. Instead, you should receive an external &SimpleNode and set it. This way the lifetime of val's reference will live at least as long as &self.
That is because the node is a compile time constant, so it's a reference into the compiled executable with a static lifetime. It's the same deal as string literals.
The implications of that lifetime subtyping thing is that as a "not advanced" user I could write a ton of code with all kind of structs perhaps all kind of relations between them. Everything might compile just fine. Then when I come to use it things fail in incomprehensible ways because I have used the wrong life time ticks.
This is the situation described in chapter 19.
Then I have to become a "advanced user" and read chapter 19 to find out how to fix my code.
That rather means there is no escape, one has to read and understand everything in the book from the get go. You have to start out advanced!
The lifetime subtyping is not necessary. A &'b T will automatically convert to a &'a T if 'a is smaller than 'b. In fact, that's what happens inside the body of their set. It would be just as valid (and imo more idiomatic) to use
and let the shortening of the lifetime happen at the call site. I don't think it is necessary to know about except in very rare cases such as &mut T<'a> with a lifetime tick on the type behind the mutable reference (i.e. not the lifetime on the reference itself), as you can otherwise just shorten the lifetime.
Note that their example does not compile, because the extra lifetime <'b> has to go on the set function instead of the impl block.
Huh, I guess I'm wrong about that part. I assumed it would give an analogous error to
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:7:10
|
7 | impl<'a, T: 'a> SimpleNode<'a> {
| ^ unconstrained type parameter
Regardless, it semantically belongs to set, not to the impl block.
I got it because defined lifetime 'a is derived from lifetime 'static so everything which belongs to lifetime 'static belongs to 'a as well, but not vice versa.
This is missing point.