Hello. So before I start explaining the problem I would like to let you know that I am lost here
I suppose I have a problem with lifetimes within the same struct but I am also wondering if this is not simply a bad design I did which cause the problem.
The ComponontLink forces me to have static lifetime and the WebRenderContext wants to have lifetimes too, so this is the only way I see to have them both here. I read it could help if I split this struct into peaces but alls structs look like to need the same lifetime.
When I reuse the UiState later I've got conflicts with lifetimes. The main problem is in the AppModel::paint function in src/app/main.rs.
Again, to be honest I have the feeling I doing something wrong, but I can't find what and/or how to solve it. If you need access to the whole code, it is accessible here: https://github.com/cedeber/fluss/tree/cedeber/issue4
Struct with borrowed references in its fields are definitely advanced topic in Rust. You should not write such code until the whole lifetime system feels natural to you.
I checked your code a bit, specifically the line which initializes Option<&'static mut WebRenderContext<'static>>. But honestly, does it compiles? The only safe way to get &'static mut T is to leak the Box<T> via Box::leak() function. This is safe as nobody can reclaim that allocation in safe way. But in your code
The WebRenderContext value is created at this line, but nobody has taken its ownership. So it will be dropped at the end of the enclosing statement. It means the field context would contains dangling reference after this line. But the Rust is a safe language as it never allows dangling reference so the compiler rejects to compile it.
Conclusion? As I stated at the top, do not store references within your struct. References are borrowing of values which are owned by someone else. The compiler check your code with the lifetime system, and throws compile error if it finds some chance of dangling reference, even ones seems too tiny for human eyes. But believe me, it's infinitely better than the weeks or months of micro-debugging on moderate sized C++ project to fix memory error which only crashes your server on midnight Friday.
Haha, of course it doesn't compile At least you confirm that the self.context assignment is wrong.
Looks like I have to think differently about how to share the canvas context between widgets. (and AppModel/UiState then too)
'static is a very special lifetime in Rust. In practice it means something is either built-in into the program at compile time (like string literals or global constants) or it's a leaked memory.
When the compiler tells you something has to live for a static lifetime, you should not follow its advice literally and add 'static annotation, because it's very unlikely to help: you can't make complex objects into built-in constants, and you don't want to leak memory!
So when you see compiler demanding 'static, read it as "DO NOT USE REFERENCES". Things that are marked 'static in practice forbid use of any kind of temporary reference. In that case you must abandon code that uses &something, and change it to owned objects, e.g. WebRenderContext or Arc<WebRenderContext> instead.
Looks like I need to do Option<WebRenderContext<'static>> because then it complains that a normal lifetime won't outlive the static lifetime of ComponentLink, in the same AppModel struct.
Then I face the problem that I can't have access to the WebRenderContext as a mutable ref because it doesn't have been declared as mutable. And, in addition, the WebRenderContext does not implement the Copy trait.
I got access to it here:
let context = match self.context {
Some(it) => it,
None => return,
};