> rust will drop the string l before q
Why?
My thoughts as well. The problem can be alleviated either by making the ownership change an error or "just" invoking the destructors in the correct order.
But I think https://news.ycombinator.com/item?id=50072252 answers it:
A 'static lifetime constraint on T says: types that satisfy T must not contain any borrowed value/content whose lifetime will be shorter than the life of the program.
So the compiler assumes it is guaranteed, that 'l' still exists, so it doesn't consider it in regard of finalizer ordering.
That's incorrect; the compiler drops q before l. Drops happen in LIFO order; and the compiler knows that it can't drop l before q has been dropped, because q contains a reference to l.
The issue is that the destructor of q can observe a reference which is about to be deallocated as having a 'static lifetime (i.e. it will live forever), and can thus stash it away somewhere for other code to access after it's been freed (as in the examples in the issue which demonstrate UB.)