diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2023-02-10 21:10:36 -0500 |
---|---|---|
committer | Ryan Scott <ryan.gl.scott@gmail.com> | 2023-02-20 20:44:34 -0500 |
commit | 4327d63594f73939a2b8ab015c1cb44eafd4b460 (patch) | |
tree | 0af0a26b4751ac8bd1b82e1617e129f767cdee06 /compiler/GHC/Core | |
parent | 0196cc2ba8f848187be47b5fc53bab89e5026bf6 (diff) | |
download | haskell-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.hs | 38 |
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 |