diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2018-02-03 11:40:43 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-02-03 11:46:21 -0500 |
commit | d8a0e6d322deaa3743c95a11a6b7272577d1f86e (patch) | |
tree | 90d2b540e06f4d53fe27b298f76c677d64ca8278 | |
parent | 217e4170bdce3df28a667803ce5e619553bfecdd (diff) | |
download | haskell-d8a0e6d322deaa3743c95a11a6b7272577d1f86e.tar.gz |
Don't apply dataToTag's caseRules for data families
Commit 193664d42dbceadaa1e4689dfa17ff1cf5a405a0 added a
special caseRule for `dataToTag`, but this transformation completely
broke when `dataToTag` was applied to somewith with a type headed by
a data family, leading to #14680. For now at least, the simplest
solution is to simply not apply this transformation when the type is
headed by a data family.
Test Plan: make test TEST=T14680
Reviewers: simonpj, bgamari
Reviewed By: bgamari
Subscribers: rwbarton, thomie, carter
GHC Trac Issues: #14680
Differential Revision: https://phabricator.haskell.org/D4371
-rw-r--r-- | compiler/prelude/PrelRules.hs | 12 | ||||
-rw-r--r-- | testsuite/tests/indexed-types/should_compile/T14680.hs | 19 | ||||
-rw-r--r-- | testsuite/tests/indexed-types/should_compile/all.T | 1 |
3 files changed, 30 insertions, 2 deletions
diff --git a/compiler/prelude/PrelRules.hs b/compiler/prelude/PrelRules.hs index db795890c7..49cd9fa153 100644 --- a/compiler/prelude/PrelRules.hs +++ b/compiler/prelude/PrelRules.hs @@ -37,8 +37,8 @@ import CoreOpt ( exprIsLiteral_maybe ) import PrimOp ( PrimOp(..), tagToEnumKey ) import TysWiredIn import TysPrim -import TyCon ( tyConDataCons_maybe, isEnumerationTyCon, isNewTyCon - , unwrapNewTyCon_maybe, tyConDataCons ) +import TyCon ( tyConDataCons_maybe, isAlgTyCon, isEnumerationTyCon + , isNewTyCon, unwrapNewTyCon_maybe, tyConDataCons ) import DataCon ( DataCon, dataConTagZ, dataConTyCon, dataConWorkId ) import CoreUtils ( cheapEqExpr, exprIsHNF, exprType ) import CoreUnfold ( exprIsConApp_maybe ) @@ -1449,6 +1449,8 @@ caseRules dflags (App (App (Var f) type_arg) v) -- See Note [caseRules for dataToTag] caseRules _ (App (App (Var f) (Type ty)) v) -- dataToTag x | Just DataToTagOp <- isPrimOpId_maybe f + , Just (tc, _) <- tcSplitTyConApp_maybe ty + , isAlgTyCon tc = Just (v, tx_con_dtt ty , \v -> App (App (Var f) (Type ty)) (Var v)) @@ -1549,4 +1551,10 @@ into Note the need for some wildcard binders in the 'cons' case. + +For the time, we only apply this transformation when the type of `x` is a type +headed by a normal tycon. In particular, we do not apply this in the case of a +data family tycon, since that would require carefully applying coercion(s) +between the data family and the data family instance's representation type, +which caseRules isn't currently engineered to handle (#14680). -} diff --git a/testsuite/tests/indexed-types/should_compile/T14680.hs b/testsuite/tests/indexed-types/should_compile/T14680.hs new file mode 100644 index 0000000000..9694c0a2ea --- /dev/null +++ b/testsuite/tests/indexed-types/should_compile/T14680.hs @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# OPTIONS_GHC -O1 #-} +module T14680 where + +import GHC.Base (getTag) +import GHC.Exts (Int(..), tagToEnum#) + +data family TyFamilyEnum +data instance TyFamilyEnum = TyFamilyEnum1 | TyFamilyEnum2 | TyFamilyEnum3 + +suc :: TyFamilyEnum -> TyFamilyEnum +suc a_aaf8 + = case getTag a_aaf8 of + a_aaf9 + -> if 2 == I# a_aaf9 + then error "succ{TyFamilyEnum}: tried to take `succ' of last tag in enumeration" + else case I# a_aaf9 + 1 of + I# i_aafa -> tagToEnum# i_aafa :: TyFamilyEnum diff --git a/testsuite/tests/indexed-types/should_compile/all.T b/testsuite/tests/indexed-types/should_compile/all.T index 9250fa2317..8e89ecfd78 100644 --- a/testsuite/tests/indexed-types/should_compile/all.T +++ b/testsuite/tests/indexed-types/should_compile/all.T @@ -272,3 +272,4 @@ test('T14131', normal, compile, ['']) test('T14162', normal, compile, ['']) test('T14237', normal, compile, ['']) test('T14554', normal, compile, ['']) +test('T14680', normal, compile, ['']) |