[GHC] #16141: StrictData and TypeFamilies regression
GHC
ghc-devs at haskell.org
Mon Jan 7 18:00:06 UTC 2019
#16141: StrictData and TypeFamilies regression
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: (none)
Type: bug | Status: new
Priority: highest | Milestone: 8.8.1
Component: Compiler (Type | Version: 8.6.3
checker) |
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: GHC rejects | Unknown/Multiple
valid program | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by RyanGlScott):
My hunch appears to be correct. The
[https://gitlab.haskell.org/ghc/ghc/blob/master/compiler/basicTypes/MkId.hs#L784-798
dataConSrcToImplBang] function is what is responsible for making decisions
about strictness/unpacking w.r.t. `StrictData`:
{{{#!hs
-- | Unpack/Strictness decisions from source module
dataConSrcToImplBang
:: DynFlags
-> FamInstEnvs
-> Type
-> HsSrcBang
-> HsImplBang
dataConSrcToImplBang dflags fam_envs arg_ty
(HsSrcBang ann unpk NoSrcStrict)
| xopt LangExt.StrictData dflags -- StrictData => strict field
= dataConSrcToImplBang dflags fam_envs arg_ty
(HsSrcBang ann unpk SrcStrict)
| otherwise -- no StrictData => lazy field
= HsLazy
}}}
Notice that this does not take into account whether the `Type` of the
field belongs to a newtype or not, so this will indeed unpack the field of
a newtype with `StrictData` + `-O` enabled. Yikes.
One could fix this by propagating information about whether we're in a
newtype or not to `dataConSrcToImplBang`. But then again, should we really
even need to call `dataConSrcToImplBang` if we're dealing with a newtype?
`dataConSrcToImplBang` is internal to `MkId` and only has one call site,
so I'm inclined to just avoid invoking it at its call site, like so:
{{{#!diff
diff --git a/compiler/basicTypes/MkId.hs b/compiler/basicTypes/MkId.hs
index 5a6f1fbf96..fa3d6785b7 100644
--- a/compiler/basicTypes/MkId.hs
+++ b/compiler/basicTypes/MkId.hs
@@ -637,11 +637,15 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs
data_con
-- Because we are going to apply the eq_spec args manually
in the
-- wrapper
- arg_ibangs =
- case mb_bangs of
- Nothing -> zipWith (dataConSrcToImplBang dflags fam_envs)
- orig_arg_tys orig_bangs
- Just bangs -> bangs
+ new_tycon = isNewTyCon tycon
+ arg_ibangs
+ | new_tycon
+ = nOfThem (length orig_arg_tys) HsLazy
+ | otherwise
+ = case mb_bangs of
+ Nothing -> zipWith (dataConSrcToImplBang dflags fam_envs)
+ orig_arg_tys orig_bangs
+ Just bangs -> bangs
(rep_tys_w_strs, wrappers)
= unzip (zipWith dataConArgRep all_arg_tys (ev_ibangs ++
arg_ibangs))
@@ -650,7 +654,7 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs
data_con
(rep_tys, rep_strs) = unzip (concat rep_tys_w_strs)
wrapper_reqd =
- (not (isNewTyCon tycon)
+ (not new_tycon
-- (Most) newtypes have only a worker, with the
exception
-- of some newtypes written with GADT syntax. See
below.
&& (any isBanged (ev_ibangs ++ arg_ibangs)
}}}
This certainly fixes the two programs in this ticket, and it passes the
rest of the testsuite. Does this sound like the right approach?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/16141#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list