Skip to content

unsafePerformIO makes bottoming actions appear non-bottoming

In general GHC avoids inlining bottoming expressions since they are typically in cold-paths. However, while working on making runRW# simplify (#15127 (closed)) I noticed that PlainPanic.panic tends to be inlined often. For instance, in GHC.CmmToAsm.PPC.Regs we alone inlined PlainPanic.panic six times, each of which generating a 20-something term binding, each differing only in the error message string. For instance,

-- RHS size: {terms: 17, types: 41, coercions: 0, joins: 0/0}
GHC.CmmToAsm.PPC.Regs.regDotColor2
  :: GHC.Prim.State# GHC.Prim.RealWorld -> Outputable.SDoc
[GblId, Arity=1, Str=<L,U>, Cpr=b, Unf=OtherCon []]
GHC.CmmToAsm.PPC.Regs.regDotColor2
  = \ (eta_s8Vu [Occ=Once] :: GHC.Prim.State# GHC.Prim.RealWorld) ->
      case GHC.Prim.getCurrentCCS#
             @GHC.Base.String @GHC.Prim.RealWorld x1_r7VT eta_s8Vu
      of
      { (# s'_s8Vw [Occ=Once], addr_s8Vx [Occ=Once] #) ->
      case GHC.Stack.CCS.$wgo
             addr_s8Vx (GHC.Types.[] @[GHC.Types.Char]) s'_s8Vw
      of
      { (# ipv_s8Vz [Occ=Once], ipv1_s8VA [Occ=Once] #) ->
      case PlainPanic.panic1
             @GHC.Platform.Reg.Class.RegClass ipv_s8Vz ipv1_s8VA x1_r7VT
      of {
      }
      }
      }

The reason for this is likely that panic uses unsafeDupablePerformIO, which hides the bottoming nature of the IO action which it runs.

See comments on !3126 (closed)

Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information