I need Database to outlive Watcher and it looks by the meaning of code that it indeed should. Strangely enough compiler proposes me to induce reverse lifetime dependency (that Watcher lives at least as long as Database). As for reason, it gives me message "requirement occurs because of the type `RwLock<Database<'_>>`, which makes the generic argument `Database<'_>` invariant" which I cannot understand in this context.
How can I fix the following code so the Database will correctly outlive Watcher?
In the live app the Watcher, living shorter than Database, will notify Database about changes that occurred in other threads.
You should not be putting temporary references in structs. The struct …<'a> syntax is a special case for temporary views of data stored elsewhere, and it's a design mistake to use it for structs that are supposed to hold some data.
&'a is not for storing data by reference. It's for not storing the data at all, and having it tied to some local variable or content of some other struct stored elsewhere.
It's not possible to extend an existing temporary lifetime, even if you put the struct in a longer-lived container.
So the best solution is to remove all the lifetimes. If you want to store something "by reference", the correct type for it is Box (or Arc).
What happens here with 'b: 'a is that the lifetime in RwLock ends up being invariant, i.e. it cannot be shortened. This is because RwLock is mutable (equivalent of &mut), and shortening of a mutable lifetime has edge cases that can lead to use-after-free. Shared & is flexible, but exclusive lifetimes are not. There are cases where &mut appears to be shortened, but it's the compiler "reborrowing" it and implicitly creating a new inflexible lifetime, while forbidding access to the longer original. Simple assignments don't get the reborrowing.