Note [Which scrutinees may throw precise exceptions]
This is the specification of 'exprMayThrowPreciseExceptions', which is important for Scenario 2 of Note [Precise exceptions and strictness analysis] in GHC.Types.Demand. For an expression @f a1 ... an :: ty@ we determine that 1. False If ty is *not* @State# RealWorld@ or an unboxed tuple thereof. This check is done by 'forcesRealWorld'. (Why not simply unboxed pairs as above? This is motivated by T13380{d,e}.) 2. False If f is a PrimOp, and it is *not* raiseIO# 3. False If f is the PrimOp-like `seq#`, cf. Note [seq# magic]. 4. False If f is an unsafe FFI call ('PlayRisky') _. True Otherwise "give up". It is sound to return False in those cases, because 1. We don't give any guarantees for unsafePerformIO, so no precise exceptions from pure code. 2. raiseIO# is the only primop that may throw a precise exception. 3. `seq#` used to be a primop that did not throw a precise exception. We keep it that way for back-compat. See the implementation bits of Note [seq# magic] in GHC.Types.Id.Make. 4. Unsafe FFI calls may not interact with the RTS (to throw, for example). See haddock on GHC.Types.ForeignCall.PlayRisky. We *need* to return False in those cases, because 1. We would lose too much strictness in pure code, all over the place. 2. We would lose strictness for primops like getMaskingState#, which introduces a substantial regression in GHC.IO.Handle.Internals.wantReadableHandle. 3. `seq#` used to be a PrimOp and we want to stay backwards compatible. 4. We would lose strictness for code like GHC.Fingerprint.fingerprintData, where an intermittent FFI call to c_MD5Init would otherwise lose strictness on the arguments len and buf, leading to regressions in T9203 (2%) and i386's haddock.base (5%). Tested by T13380f. In !3014 we tried a more sophisticated analysis by introducing ConOrDiv (nic) to the Divergence lattice, but in practice it turned out to be hard to untaint from 'topDiv' to 'conDiv', leading to bugs, performance regressions and complexity that didn't justify the single fixed testcase T13380c. You might think that we should check for side-effects rather than just for precise exceptions. Right you are! See Note [Side-effects and strictness] for why we unfortunately do not.
References 3
- Precise exceptions and strictness analysis GHC.Types.Demand
- Side-effects and strictness GHC.Types.Demand
- seq# magic GHC.Types.Id.Make
Referenced by 3
- GHC.Core.Opt.DmdAnal call site
- Precise exceptions and strictness analysis GHC.Types.Demand
- Side-effects and strictness GHC.Types.Demand