summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Make.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Core/Make.hs')
-rw-r--r--compiler/GHC/Core/Make.hs74
1 files changed, 58 insertions, 16 deletions
diff --git a/compiler/GHC/Core/Make.hs b/compiler/GHC/Core/Make.hs
index 38710f3829..5992bcc4f5 100644
--- a/compiler/GHC/Core/Make.hs
+++ b/compiler/GHC/Core/Make.hs
@@ -735,6 +735,7 @@ errorIds
rEC_CON_ERROR_ID,
rEC_SEL_ERROR_ID,
aBSENT_ERROR_ID,
+ aBSENT_SUM_FIELD_ERROR_ID,
tYPE_ERROR_ID -- Used with Opt_DeferTypeErrors, see #10284
]
@@ -746,8 +747,6 @@ absentSumFieldErrorName :: Name
recSelErrorName = err_nm "recSelError" recSelErrorIdKey rEC_SEL_ERROR_ID
absentErrorName = err_nm "absentError" absentErrorIdKey aBSENT_ERROR_ID
-absentSumFieldErrorName = err_nm "absentSumFieldError" absentSumFieldErrorIdKey
- aBSENT_SUM_FIELD_ERROR_ID
runtimeErrorName = err_nm "runtimeError" runtimeErrorIdKey rUNTIME_ERROR_ID
recConErrorName = err_nm "recConError" recConErrorIdKey rEC_CON_ERROR_ID
patErrorName = err_nm "patError" patErrorIdKey pAT_ERROR_ID
@@ -774,25 +773,68 @@ tYPE_ERROR_ID = mkRuntimeErrorId typeErrorName
-- Note [aBSENT_SUM_FIELD_ERROR_ID]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- Absent argument error for unused unboxed sum fields are different than absent
--- error used in dummy worker functions (see `mkAbsentErrorApp`):
--
--- - `absentSumFieldError` can't take arguments because it's used in unarise for
--- unused pointer fields in unboxed sums, and applying an argument would
--- require allocating a thunk.
+-- Unboxed sums are transformed into unboxed tuples in GHC.Stg.Unarise.mkUbxSum
+-- and fields that can't be reached are filled with rubbish values. It's easy to
+-- come up with rubbish literal values: we use 0 (ints/words) and 0.0
+-- (floats/doubles). Coming up with a rubbish pointer value is more delicate:
--
--- - `absentSumFieldError` can't be CAFFY because that would mean making some
--- non-CAFFY definitions that use unboxed sums CAFFY in unarise.
+-- 1. it needs to be a valid closure pointer for the GC (not a NULL pointer)
--
--- To make `absentSumFieldError` non-CAFFY we get a stable pointer to it in
--- RtsStartup.c and mark it as non-CAFFY here.
+-- 2. it is never used in Core, only in STG; and even then only for filling a
+-- GC-ptr slot in an unboxed sum (see GHC.Stg.Unarise.ubxSumRubbishArg).
+-- So all we need is a pointer, and its levity doesn't matter. Hence we
+-- can safely give it the (lifted) type:
--
--- Getting this wrong causes hard-to-debug runtime issues, see #15038.
+-- absentSumFieldError :: forall a. a
--
--- TODO: Remove stable pointer hack after fixing #9718.
--- However, we should still be careful about not making things CAFFY just
--- because they use unboxed sums. Unboxed objects are supposed to be
--- efficient, and none of the other unboxed literals make things CAFFY.
+-- despite the fact that Unarise might instantiate it at non-lifted
+-- types.
+--
+-- 3. it can't take arguments because it's used in unarise and applying an
+-- argument would require allocating a thunk.
+--
+-- 4. it can't be CAFFY because that would mean making some non-CAFFY
+-- definitions that use unboxed sums CAFFY in unarise.
+--
+-- Getting this wrong causes hard-to-debug runtime issues, see #15038.
+--
+-- 5. it can't be defined in `base` package.
+--
+-- Defining `absentSumFieldError` in `base` package introduces a
+-- dependency on `base` for any code using unboxed sums. It became an
+-- issue when we wanted to use unboxed sums in boot libraries used by
+-- `base`, see #17791.
+--
+--
+-- * Most runtime-error functions throw a proper Haskell exception, which can be
+-- caught in the usual way. But these functions are defined in
+-- `base:Control.Exception.Base`, hence, they cannot be directly invoked in
+-- any library compiled before `base`. Only exceptions that have been wired
+-- in the RTS can be thrown (indirectly, via a call into the RTS) by libraries
+-- compiled before `base`.
+--
+-- However wiring exceptions in the RTS is a bit annoying because we need to
+-- explicitly import exception closures via their mangled symbol name (e.g.
+-- `import CLOSURE base_GHCziIOziException_heapOverflow_closure`) in Cmm files
+-- and every imported symbol must be indicated to the linker in a few files
+-- (`package.conf`, `rts.cabal`, `win32/libHSbase.def`, `Prelude.h`...). It
+-- explains why exceptions are only wired in the RTS when necessary.
+--
+-- * `absentSumFieldError` is defined in ghc-prim:GHC.Prim.Panic, hence, it can
+-- be invoked in libraries compiled before `base`. It does not throw a Haskell
+-- exception; instead, it calls `stg_panic#`, which immediately halts
+-- execution. A runtime invocation of `absentSumFieldError` indicates a GHC
+-- bug. Unlike (say) pattern-match errors, it cannot be caused by a user
+-- error. That's why it is OK for it to be un-catchable.
+--
+
+absentSumFieldErrorName
+ = mkWiredInIdName
+ gHC_PRIM_PANIC
+ (fsLit "absentSumFieldError")
+ absentSumFieldErrorIdKey
+ aBSENT_SUM_FIELD_ERROR_ID
aBSENT_SUM_FIELD_ERROR_ID
= mkVanillaGlobalWithInfo absentSumFieldErrorName