summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2023-02-10 21:10:36 -0500
committerRyan Scott <ryan.gl.scott@gmail.com>2023-02-20 20:44:34 -0500
commit4327d63594f73939a2b8ab015c1cb44eafd4b460 (patch)
tree0af0a26b4751ac8bd1b82e1617e129f767cdee06 /compiler/GHC/Core
parent0196cc2ba8f848187be47b5fc53bab89e5026bf6 (diff)
downloadhaskell-4327d63594f73939a2b8ab015c1cb44eafd4b460.tar.gz
Don't generate datacon wrappers for `type data` declarations
Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948.
Diffstat (limited to 'compiler/GHC/Core')
-rw-r--r--compiler/GHC/Core/Utils.hs38
1 files changed, 35 insertions, 3 deletions
diff --git a/compiler/GHC/Core/Utils.hs b/compiler/GHC/Core/Utils.hs
index d36f0a14f2..89824889ef 100644
--- a/compiler/GHC/Core/Utils.hs
+++ b/compiler/GHC/Core/Utils.hs
@@ -728,9 +728,8 @@ refineDefaultAlt :: [Unique] -- ^ Uniques for constructing new binders
refineDefaultAlt us mult tycon tys imposs_deflt_cons all_alts
| Alt DEFAULT _ rhs : rest_alts <- all_alts
, isAlgTyCon tycon -- It's a data type, tuple, or unboxed tuples.
- , not (isNewTyCon tycon) -- We can have a newtype, if we are just doing an eval:
- -- case x of { DEFAULT -> e }
- -- and we don't want to fill in a default for them!
+ , not (isNewTyCon tycon) -- Exception 1 in Note [Refine DEFAULT case alternatives]
+ , not (isTypeDataTyCon tycon) -- Exception 2 in Note [Refine DEFAULT case alternatives]
, Just all_cons <- tyConDataCons_maybe tycon
, let imposs_data_cons = mkUniqSet [con | DataAlt con <- imposs_deflt_cons]
-- We now know it's a data type, so we can use
@@ -815,6 +814,39 @@ with a specific constructor is desirable.
`imposs_deflt_cons` argument is populated with constructors which
are matched elsewhere.
+There are two exceptions where we avoid refining a DEFAULT case:
+
+* Exception 1: Newtypes
+
+ We can have a newtype, if we are just doing an eval:
+
+ case x of { DEFAULT -> e }
+
+ And we don't want to fill in a default for them!
+
+* Exception 2: `type data` declarations
+
+ The data constructors for a `type data` declaration (see
+ Note [Type data declarations] in GHC.Rename.Module) do not exist at the
+ value level. Nevertheless, it is possible to strictly evaluate a value
+ whose type is a `type data` declaration. Test case
+ type-data/should_compile/T2294b.hs contains an example:
+
+ type data T a where
+ A :: T Int
+
+ f :: T a -> ()
+ f !x = ()
+
+ We want to generate the following Core for f:
+
+ f = \(@a) (x :: T a) ->
+ case x of
+ __DEFAULT -> ()
+
+ Namely, we do _not_ want to match on `A`, as it doesn't exist at the value
+ level!
+
Note [Combine identical alternatives]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If several alternatives are identical, merge them into a single