summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDavid Feuer <david.feuer@gmail.com>2018-05-02 23:43:13 -0400
committerDavid Feuer <David.Feuer@gmail.com>2018-05-02 23:48:34 -0400
commit198db048f60f48b420ac4ad9264af57185b4b41a (patch)
treed6b165aceabd7bca733cd5120c370e0086fcd979 /compiler
parent4cb5595e5e800818721a623a5419cad29a528000 (diff)
downloadhaskell-198db048f60f48b420ac4ad9264af57185b4b41a.tar.gz
Set arity for absentError
* The note on how to prevent stable unfoldings from leading to `case` on `absentError` was wrong. Make it reflect reality. * Reviewing the above change, Simon noticed that we didn't set an arity for `absentError`, which definitely has arity 1. It may not matter much, since `absentError` usually vanishes quickly, but we might as well set it properly, so now we do. Reviewers: simonpj, bgamari Reviewed By: simonpj Subscribers: thomie, carter Differential Revision: https://phabricator.haskell.org/D4655
Diffstat (limited to 'compiler')
-rw-r--r--compiler/coreSyn/MkCore.hs43
1 files changed, 23 insertions, 20 deletions
diff --git a/compiler/coreSyn/MkCore.hs b/compiler/coreSyn/MkCore.hs
index f2b940bfd1..8291c01807 100644
--- a/compiler/coreSyn/MkCore.hs
+++ b/compiler/coreSyn/MkCore.hs
@@ -824,40 +824,43 @@ Yikes! That bogusly appears to evaluate the absentError!
This is extremely tiresome. Another way to think of this is that, in
Core, it is an invariant that a strict data contructor, like MkT, must
-be be applied only to an argument in HNF. so (absentError "blah") had
+be applied only to an argument in HNF. So (absentError "blah") had
better be non-bottom.
-So the "solution" is to make absentError behave like a data constructor,
-to respect this invariant. Rather than have a special case in exprIsHNF,
-I eneded up doing this:
+So the "solution" is to add a special case for absentError to exprIsHNFlike.
+This allows Simplify.rebuildCase, in the Note [Case to let transformation]
+branch, to convert the case on absentError into a let. We also make
+absentError *not* be diverging, unlike the other error-ids, so that we
+can be sure not to remove the case branches before converting the case to
+a let.
- * Make absentError claim to be ConLike
-
- * Make exprOkForSpeculation/exprOkForSideEffects
- return True for ConLike things
-
- * In Simplify.rebuildCase, make the
- Note [Case to let transformation]
- branch use exprOkForSpeculation rather than exprIsHNF, so that
- it converts the absentError case to a let.
-
-On the other hand if, by some bug or bizarre happenstance, we ever call
-absentError, we should thow an exception. This should never happen, of
-course, but we definitely can't return anything. e.g. if somehow we had
+If, by some bug or bizarre happenstance, we ever call absentError, we should
+throw an exception. This should never happen, of course, but we definitely
+can't return anything. e.g. if somehow we had
case absentError "foo" of
Nothing -> ...
Just x -> ...
then if we return, the case expression will select a field and continue.
-Seg fault city. Better to throw an exception. (Even though we've said
-it is ConLike :-)
+Seg fault city. Better to throw an exception. (Even though we've said
+it is in HNF :-)
+
+It might seem a bit surprising that seq on absentError is simply erased
+
+ absentError "foo" `seq` x ==> x
+
+but that should be okay; since there's no pattern match we can't really
+be relying on anything from it.
-}
aBSENT_ERROR_ID
- = mkVanillaGlobal absentErrorName absent_ty
+ = mkVanillaGlobalWithInfo absentErrorName absent_ty arity_info
where
absent_ty = mkSpecForAllTys [alphaTyVar] (mkFunTy addrPrimTy alphaTy)
-- Not runtime-rep polymorphic. aBSENT_ERROR_ID is only used for
-- lifted-type things; see Note [Absent errors] in WwLib
+ arity_info = vanillaIdInfo `setArityInfo` 1
+ -- NB: no bottoming strictness info, unlike other error-ids.
+ -- See Note [aBSENT_ERROR_ID]
mkAbsentErrorApp :: Type -- The type to instantiate 'a'
-> String -- The string to print