What is the proper understanding of the restriction T : 'static ?
As I understand it means "anything implementing T should not have a reference / pointer either directly or indirectly". I am asking because I used to think that it means anything implementing T should exist during the whole lifetime of the application, but such interpretation looks wrong for me now.
I have found an interesting article about most common misconception related lifetimes. Maybe it will become useful for anyone else too.
Or the type T itself should not reference anything either directly or indirectly.
That's a common misconception. The more correct way to think is not that it should exist during the whole lifetime of the program, but that it is allowed to exist that long - i.e., there won't be any dangling references if someone holds it forever.
The bound T: 'a means that all lifetimes annotated on the type are larger or equal to 'a. So for example, an &'short u32 is : 'short, but not : 'long. On the other hand, a &'long u32 is both : 'short and : 'long.
In the case of : 'static, it means that all lifetimes annotated on it are 'static, so you can have types with no lifetimes annotated on it, and you can have stuff like &'static str, but nothing else.
T can have pointer parts directly as well as indirectly (it could be tree structure with heap-allocated nodes, for example). But it needs to be owned by the T. So T may contain a Box<Inner>, Vec<Inner> or an Arc<Inner>, but not an &'a Inner unless 'a: 'static.
The key is to understand that is that lifetime bounds only mean something for types that contain references.
If the type T does not contain any references, then : 'static is ignored. It doesn't apply to it, it doesn't mean anything. Specifically, it won't make T live for some static lifetime. A non-reference/self-contained type like i32 or String can live for as long or as short as it needs to, regardless of lifetime annotations.
Lifetimes are only for references and types with lifetimes attached (which is usually from references inside them).
I don't think this is quite the best way to explain it. How I think of it is that a T: 'a bound specifies a maximum upper bound on the lifetime of any individual T object. Objects can be dropped at any point before 'a ends, but cannot live any longer than 'a. For instance, a struct containing a &'short str cannot possibly be held after 'short ends. But a struct with no references at all (or only 'static references) can be held for any length of time at all, since 'static lasts all the way to the end of the program.
EDIT: I mixed up the notation in this explanation; it describes lifetime parameters T<'a>, not lifetime bounds T: 'a.
I find your explanation more difficult to understand, because I think it'd be correct only if by "objects can be dropped" you mean ceasing use of T in a generic context, rather than dropping of the actual object (such as releasing its heap allocation or unwinding its stack space).
And when you're talking about shortening of lifetimes, that's not quite accurate for &mut lifetimes that are invariant and can't be shortened. You can use &'a mut in a smaller scope than 'a, but you can't shorten 'a at all.
Ah, my apologies, I completely mixed up the terminology. I was thinking about types with lifetime parameters, i.e., MyType<'a>, which is nearly the exact opposite of MyType: 'a. The latter is only relevant to generics, as you say.