diff options
| author | David Feuer <david.feuer@gmail.com> | 2018-05-02 23:43:13 -0400 |
|---|---|---|
| committer | David Feuer <David.Feuer@gmail.com> | 2018-05-02 23:48:34 -0400 |
| commit | 198db048f60f48b420ac4ad9264af57185b4b41a (patch) | |
| tree | d6b165aceabd7bca733cd5120c370e0086fcd979 /compiler | |
| parent | 4cb5595e5e800818721a623a5419cad29a528000 (diff) | |
| download | haskell-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.hs | 43 |
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 |
