summaryrefslogtreecommitdiff
path: root/compiler/GHC/CoreToStg.hs
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-06-02 17:09:43 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-06-14 15:35:23 -0400
commit9a7462fb6b8bdd6326a607bbd7b9453eb588193b (patch)
tree8300a7c5da0b49c63b81946bf94b3f8c4efc3d59 /compiler/GHC/CoreToStg.hs
parentc0e6dee99242eff08420176a36d77b715972f1f2 (diff)
downloadhaskell-9a7462fb6b8bdd6326a607bbd7b9453eb588193b.tar.gz
codeGen: Don't discard live case binders in unsafeEqualityProof logic
Previously CoreToStg would unconditionally discard cases of the form: case unsafeEqualityProof of wild { _ -> rhs } and rather replace the whole thing with `rhs`. However, in some cases (see #18227) the case binder is still live, resulting in unbound occurrences in `rhs`. Fix this by only discarding the case if the case binder is dead. Fixes #18227.
Diffstat (limited to 'compiler/GHC/CoreToStg.hs')
-rw-r--r--compiler/GHC/CoreToStg.hs5
1 files changed, 4 insertions, 1 deletions
diff --git a/compiler/GHC/CoreToStg.hs b/compiler/GHC/CoreToStg.hs
index 8657b5a84c..42369fe45b 100644
--- a/compiler/GHC/CoreToStg.hs
+++ b/compiler/GHC/CoreToStg.hs
@@ -435,7 +435,10 @@ coreToStgExpr e0@(Case scrut bndr _ alts) = do
let stg = StgCase scrut2 bndr (mkStgAltType bndr alts) alts2
-- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce
case scrut2 of
- StgApp id [] | idName id == unsafeEqualityProofName ->
+ StgApp id [] | idName id == unsafeEqualityProofName
+ , isDeadBinder bndr ->
+ -- We can only discard the case if the case-binder is dead
+ -- It usually is, but see #18227
case alts2 of
[(_, [_co], rhs)] ->
return rhs