summaryrefslogtreecommitdiff
path: root/compiler/GHC/CoreToStg.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/CoreToStg.hs')
-rw-r--r--compiler/GHC/CoreToStg.hs28
1 files changed, 25 insertions, 3 deletions
diff --git a/compiler/GHC/CoreToStg.hs b/compiler/GHC/CoreToStg.hs
index ead7a12da0..a450f342b0 100644
--- a/compiler/GHC/CoreToStg.hs
+++ b/compiler/GHC/CoreToStg.hs
@@ -198,6 +198,26 @@ import Control.Monad (ap)
-- do we set CCCS from it; so we just slam in
-- dontCareCostCentre.
+-- Note [Coercion tokens]
+-- ~~~~~~~~~~~~~~~~~~~~~~
+-- In coreToStgArgs, we drop type arguments completely, but we replace
+-- coercions with a special coercionToken# placeholder. Why? Consider:
+--
+-- f :: forall a. Int ~# Bool -> a
+-- f = /\a. \(co :: Int ~# Bool) -> error "impossible"
+--
+-- If we erased the coercion argument completely, we’d end up with just
+-- f = error "impossible", but then f `seq` () would be ⊥!
+--
+-- This is an artificial example, but back in the day we *did* treat
+-- coercion lambdas like type lambdas, and we had bug reports as a
+-- result. So now we treat coercion lambdas like value lambdas, but we
+-- treat coercions themselves as zero-width arguments — coercionToken#
+-- has representation VoidRep — which gets the best of both worlds.
+--
+-- (For the gory details, see also the (unpublished) paper, “Practical
+-- aspects of evidence-based compilation in System FC.”)
+
-- --------------------------------------------------------------
-- Setting variable info: top-level, binds, RHSs
-- --------------------------------------------------------------
@@ -357,8 +377,10 @@ coreToStgExpr (App (Lit LitRubbish) _some_unlifted_type)
-- We lower 'LitRubbish' to @()@ here, which is much easier than doing it in
-- a STG to Cmm pass.
= coreToStgExpr (Var unitDataConId)
-coreToStgExpr (Var v) = coreToStgApp v [] []
-coreToStgExpr (Coercion _) = coreToStgApp coercionTokenId [] []
+coreToStgExpr (Var v) = coreToStgApp v [] []
+coreToStgExpr (Coercion _)
+ -- See Note [Coercion tokens]
+ = coreToStgApp coercionTokenId [] []
coreToStgExpr expr@(App _ _)
= coreToStgApp f args ticks
@@ -554,7 +576,7 @@ coreToStgArgs (Type _ : args) = do -- Type argument
(args', ts) <- coreToStgArgs args
return (args', ts)
-coreToStgArgs (Coercion _ : args) -- Coercion argument; replace with place holder
+coreToStgArgs (Coercion _ : args) -- Coercion argument; See Note [Coercion tokens]
= do { (args', ts) <- coreToStgArgs args
; return (StgVarArg coercionTokenId : args', ts) }