{-# LANGUAGE GHCForeignImportPrim #-} {-# LANGUAGE UnliftedFFITypes #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE EmptyCase #-} -- | Primitive panics. module GHC.Prim.Panic ( absentSumFieldError , panicError , absentError ) where import GHC.Prim import GHC.Magic default () -- Double and Integer aren't available yet {- Note [Compiler error functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Most error functions (such as pattern match failure) are defined in base:Control.Exception.Base. But absentError# and absentSumFieldError# are defined here in the ghc-prim package for two reasons: * GHC itself generates calls to these functions as a result of strictness analysis, over which the programmer has no control. So it is hard to ensure that no such calls exist in the modules compiled "before" Control.Base.Exception. (E.g. when compiling with -fdicts-strict.) * A consequence of defining them in ghc-prim is that the libraries defining exceptions have not yet been built, so we can't make them into proper Haskell exceptions. However, if these functions are ever called, it's a /compiler/ error, not a user error, so it seems acceptable that they cannot be caught. One might wonder why absentError doesn't just call panic#. For absent error we want to combine two parts, one static, one call site dependent into one error message. While for absentSumFieldError it's a static string. The easiest way to combine the two parts for absentError is to use a format string with `barf` in the RTS passing the *dynamic* part of the error as argument. There is no need to do any of this for absentSumFieldError as it's a static string there. The alternatives would be to: * Drop the call site specific information from absentError. The call site specific information is at times very helpful for debugging so I don't consider this an option. * Remove the common prefix. We would then need to include the prefix in the call site specific string we pass to absentError. Increasing code size for no good reason. Both of which seem worse than having an stg_absentError function specific to absentError to me. -} -- `stg_panic#` never returns but it can't just return `State# RealWorld` so we -- indicate that it returns `(# #)` too to make the compiler happy. -- See Note [Compiler error functions] foreign import prim "stg_paniczh" panic# :: Addr# -> State# RealWorld -> (# State# RealWorld, (# #) #) -- See Note [Compiler error functions] foreign import prim "stg_absentErrorzh" stg_absentError# :: Addr# -> State# RealWorld -> (# State# RealWorld, (# #) #) -- | Display the CString whose address is given as an argument and exit. panicError :: Addr# -> a panicError :: forall a. Addr# -> a panicError Addr# errmsg = (State# RealWorld -> a) -> a forall o. (State# RealWorld -> o) -> o runRW# (\State# RealWorld s -> case Addr# -> State# RealWorld -> (# State# RealWorld, (# #) #) panic# Addr# errmsg State# RealWorld s of (# State# RealWorld _, (# #) _ #) -> -- This bottom is unreachable but we can't -- use an empty case lest the pattern match -- checker squawks. let x :: t x = t x in a forall {t}. t x) -- | Closure introduced by GHC.Stg.Unarise for unused unboxed sum fields. -- -- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make absentSumFieldError :: a absentSumFieldError :: forall {t}. t absentSumFieldError = Addr# -> a forall a. Addr# -> a panicError Addr# "entered absent sum field!"# -- GHC.Core.Make.aBSENT_SUM_FIELD_ERROR_ID gives absentSumFieldError a bottoming -- demand signature. But if we ever inlined it (to a call to panicError) we'd -- lose that information. Should not happen because absentSumFieldError is only -- introduced in Stg.Unarise, long after inlining has stopped, but it seems -- more direct simply to give it a NOINLINE pragma {-# NOINLINE absentSumFieldError #-} -- | Displays "Oops! Entered absent arg" ++ errormsg and exits the program. {-# NOINLINE absentError #-} absentError :: Addr# -> a absentError :: forall a. Addr# -> a absentError Addr# errmsg = (State# RealWorld -> a) -> a forall o. (State# RealWorld -> o) -> o runRW# (\State# RealWorld s -> case Addr# -> State# RealWorld -> (# State# RealWorld, (# #) #) stg_absentError# Addr# errmsg State# RealWorld s of (# State# RealWorld _, (# #) _ #) -> -- This bottom is unreachable but we can't -- use an empty case lest the pattern match -- checker squawks. let x :: t x = t x in a forall {t}. t x)