Commit 84bb8541 authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

Fix Trac #7237; mixup with empty tuples

When converting from Core to STG, we swith pattern matching on
on a *nullary* unboxed tuple into matching using a PrimAlt on RealWorld#
   case e (RealWorld#) of { DEFAULT -> ... }
This semms messy to me, but it works.  There was a bug in that we were
changing to PrimAlt, but not using a DEFAULT AltCon.
parent cf02909e
...@@ -36,6 +36,7 @@ import Maybes ( maybeToBool ) ...@@ -36,6 +36,7 @@ import Maybes ( maybeToBool )
import Name ( getOccName, isExternalName, nameOccName ) import Name ( getOccName, isExternalName, nameOccName )
import OccName ( occNameString, occNameFS ) import OccName ( occNameString, occNameFS )
import BasicTypes ( Arity ) import BasicTypes ( Arity )
import TysWiredIn ( unboxedUnitDataCon )
import Literal import Literal
import Outputable import Outputable
import MonadUtils import MonadUtils
...@@ -420,6 +421,14 @@ coreToStgExpr (Case scrut bndr _ alts) = do ...@@ -420,6 +421,14 @@ coreToStgExpr (Case scrut bndr _ alts) = do
) )
where where
vars_alt (con, binders, rhs) vars_alt (con, binders, rhs)
| DataAlt c <- con, c == unboxedUnitDataCon
= -- This case is a bit smelly.
-- See Note [Nullary unboxed tuple] in Type.lhs
-- where a nullary tuple is mapped to (State# World#)
ASSERT( null binders )
do { (rhs2, rhs_fvs, rhs_escs) <- coreToStgExpr rhs
; return ((DEFAULT, [], [], rhs2), rhs_fvs, rhs_escs) }
| otherwise
= let -- Remove type variables = let -- Remove type variables
binders' = filterStgBinders binders binders' = filterStgBinders binders
in in
...@@ -463,7 +472,7 @@ mkStgAltType bndr alts = case repType (idType bndr) of ...@@ -463,7 +472,7 @@ mkStgAltType bndr alts = case repType (idType bndr) of
PolyAlt PolyAlt
Nothing -> PolyAlt Nothing -> PolyAlt
UbxTupleRep rep_tys -> UbxTupAlt (length rep_tys) UbxTupleRep rep_tys -> UbxTupAlt (length rep_tys)
-- NB Nullary unboxed tuples have UnaryRep, and generate a PrimAlt
where where
_is_poly_alt_tycon tc _is_poly_alt_tycon tc
= isFunTyCon tc = isFunTyCon tc
......
...@@ -612,14 +612,14 @@ newtype at outermost level; and bale out if we see it again. ...@@ -612,14 +612,14 @@ newtype at outermost level; and bale out if we see it again.
Note [Nullary unboxed tuple] Note [Nullary unboxed tuple]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We represent the nullary unboxed tuple as the unary (but void) type
We represent the nullary unboxed tuple as the unary (but void) type State# RealWorld. State# RealWorld. The reason for this is that the ReprArity is never
The reason for this is that the ReprArity is never less than the Arity (as it would less than the Arity (as it would otherwise be for a function type like
otherwise be for a function type like (# #) -> Int). (# #) -> Int).
As a result, ReprArity is always strictly positive if Arity is. This is important As a result, ReprArity is always strictly positive if Arity is. This
because it allows us to distinguish at runtime between a thunk and a function is important because it allows us to distinguish at runtime between a
takes a nullary unboxed tuple as an argument! thunk and a function takes a nullary unboxed tuple as an argument!
\begin{code} \begin{code}
type UnaryType = Type type UnaryType = Type
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment