diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2016-07-18 09:28:42 -0400 |
---|---|---|
committer | Ryan Scott <ryan.gl.scott@gmail.com> | 2016-07-18 09:28:42 -0400 |
commit | 3fa3fe8a9a8afa67829e12efa5d25b76e58a185a (patch) | |
tree | 8dc8cc6190c6f8f0b1f05309f780a0e93160f65e | |
parent | d213ab3fa0cc2a39d9f74df11c8a3451ac34411c (diff) | |
download | haskell-3fa3fe8a9a8afa67829e12efa5d25b76e58a185a.tar.gz |
Make DeriveFunctor work with unboxed tuples
Summary:
Unboxed tuples have `RuntimeRep` arguments which `-XDeriveFunctor` was
mistaking for actual data constructor arguments. As a result, a derived
`Functor` instance for a datatype that contained an unboxed tuple would
generate twice as many arguments as it needed for an unboxed tuple pattern
match or expression. The solution is to simply put `dropRuntimeRepArgs` in the
right place.
Fixes #12399.
Test Plan: ./validate
Reviewers: austin, hvr, bgamari
Reviewed By: bgamari
Subscribers: thomie, osa1
Differential Revision: https://phabricator.haskell.org/D2404
GHC Trac Issues: #12399
-rw-r--r-- | compiler/typecheck/TcGenDeriv.hs | 8 | ||||
-rw-r--r-- | testsuite/tests/deriving/should_compile/T12399.hs | 7 | ||||
-rw-r--r-- | testsuite/tests/deriving/should_compile/all.T | 1 |
3 files changed, 14 insertions, 2 deletions
diff --git a/compiler/typecheck/TcGenDeriv.hs b/compiler/typecheck/TcGenDeriv.hs index 53a79f8243..2eb8c07238 100644 --- a/compiler/typecheck/TcGenDeriv.hs +++ b/compiler/typecheck/TcGenDeriv.hs @@ -1701,7 +1701,11 @@ functorLikeTraverse var (FT { ft_triv = caseTrivial, ft_var = caseVar = (caseTyApp fun_ty (last xrs), True) | otherwise = (caseWrongArg, True) -- Non-decomposable (eg type function) where - (xrs,xcs) = unzip (map (go co) args) + -- When folding over an unboxed tuple, we must explicitly drop the + -- runtime rep arguments, or else GHC will generate twice as many + -- variables in a unboxed tuple pattern match and expression as it + -- actually needs. See Trac #12399 + (xrs,xcs) = unzip (map (go co) (dropRuntimeRepArgs args)) go co (ForAllTy (TvBndr v vis) x) | isVisibleArgFlag vis = panic "unexpected visible binder" | v /= var && xc = (caseForAll v xr,True) @@ -2813,7 +2817,7 @@ a is the last type variable in a given datatype): * ft_tup: A tuple type which mentions the last type variable in at least one of its fields. The TyCon argument of ft_tup represents the particular tuple's type constructor. - Examples: (a, Int), (Maybe a, [a], Either a Int) + Examples: (a, Int), (Maybe a, [a], Either a Int), (# Int, a #) * ft_ty_app: A type is being applied to the last type parameter, where the applied type does not mention the last type parameter (if it diff --git a/testsuite/tests/deriving/should_compile/T12399.hs b/testsuite/tests/deriving/should_compile/T12399.hs new file mode 100644 index 0000000000..c3429f89bf --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T12399.hs @@ -0,0 +1,7 @@ +{-# LANGUAGE DeriveFunctor, MagicHash, UnboxedTuples #-} +module T12399 where + +import GHC.Exts + +newtype RmLoopsM a = RmLoopsM { runRmLoops :: Int# -> (# Int#, a #) } + deriving Functor diff --git a/testsuite/tests/deriving/should_compile/all.T b/testsuite/tests/deriving/should_compile/all.T index a81c4ce2d7..e42e34d2d8 100644 --- a/testsuite/tests/deriving/should_compile/all.T +++ b/testsuite/tests/deriving/should_compile/all.T @@ -71,3 +71,4 @@ test('T11732b', normal, compile, ['']) test('T11732c', normal, compile, ['']) test('T11833', normal, compile, ['']) test('T12245', normal, compile, ['']) +test('T12399', normal, compile, ['']) |