Open m-ou-se opened 11 months ago
Actually I wanted to write a blog post about this, but I have been procrastinating that for too long...
I think the two biggest problems are that
&mut i32
should be UnwindSafe
, because i32
does not have any invariants that may be broken.For me, the ideal design would have used two safe non-auto marker traits, Consistent
and RefConsistent
(as in database consistency), where Consistent
implies/requires RefConsistent
. These would be implemented where operations by-value/by-ref cannot break the invariants of the type they are implemented on. So all primitives would be Consistent
and RefConsistent
, because they do not have invariants. BinaryHeap
would implement Consistent
(if T
implements it), because it guarantees the heap invariants stay intact with every operation (in particular, PeekMut
cannot be used to break the ordering invariant). But types that allow breaking the invariants (even temporarily) through their API should not implement them, as if a panic or a leak occurs they are left in an inconsistent state. These traits could then have been used in Mutex
and RwLock
instead of lock poisoning, and in catch_unwind
to require that the closure only holds/references types that are Consistent
/RefConsistent
.
I doubt that these could be introduced in exactly that fashion, but maybe lint-traits (as in marker traits that warn instead of generating an error if unimplemented) would allow their introduction in a backwards-compatible way.
These traits could then have been used in Mutex and RwLock instead of lock poisoning, and in catch_unwind to require that the closure only holds/references types that are Consistent/RefConsistent.
That would severely restrict what types could be protected by a mutex. In an ideal would that might work, but there would need to be an escape hatch and get the poisoning behaviour instead. Perhaps via some sort of Mutex<Poisoning<T>>
, but I suspect the mutex would need to know about this inner layer.
It has been suggested many times that
UnwindSafe
andRefUnwindSafe
are more often an annoyance than they are useful, and that it might be time to effectively disable/remove them.Doing so requires some research and the design of a backwards compatible deprecation path.
To do:
AssertUnwindSafe
#[deprecated]
, or by removing theUnwindSafe
bound fromcatch_unwind
, or something else.)Or, if it turns out to be a bad idea to deprecate these traits: