The documentation for Control.Exception
describes which operations can have async exceptions thrown, even within a mask
ed block, saying: "The following operations are guaranteed not to be interruptible"
takeMVar if the MVar is definitely full, and conversely putMVar if the MVar is definitely empty
In what cases is an MVar
"definitely" full or empty from the compiler's point of view? Is that even well-enough defined to enable reasoning about whether my code will break without handling async exceptions on every MVar
operation?