Skip to content

Commit 97f03e2

Browse files
committed
Add support for GHC 9.
Mostly trivial changes, but we now get the `DynFlags` from `installCoreToDos` rather than each application of `BuiltinRule.ru_try`. This continues to work just fine for GHC 8.10, but doesn't quite work on GHC 9.0 for some reason. I don't think it's the `DynFlags` changes (as that's applied to all GHC versions). But running on GHC 9.0 always fails with "isDeadEndId cccV" (this is slightly stricter than `isBottomingId` in earlier GHCs, but removing that `pprPanic` still fails, just with "Oops: toCcc'' called" instead). Fixes compiling-to-categories#98.
1 parent b789900 commit 97f03e2

9 files changed

Lines changed: 177 additions & 64 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
# - "8.6.1"
2020
- "8.8.1"
2121
- "8.10.1"
22+
- "9.0.1"
2223
steps:
2324
- uses: actions/checkout@v2
2425
- uses: haskell/actions/setup@v1

classes/src/ConCat/Category.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,7 +1815,7 @@ class BottomCat k a b where
18151815
-- bottomC = bottomC &&& bottomC
18161816

18171817
instance (BottomCat k a b, ClosedCat k, Ok4 k z b a (z -> b)) => BottomCat k a (z -> b) where
1818-
bottomC = curry (bottomC . exl) <+ okProd @k @a @ z
1818+
bottomC = curry (bottomC . exl) <+ okProd @k @a @z
18191819

18201820
instance BottomCat (->) a b where bottomC = error "bottomC for (->) evaluated"
18211821

@@ -2075,7 +2075,7 @@ class ({- Pointed h, -} OkFunctor k h, Ok k a) => PointedCat k h a where
20752075
-- class (Ok k a, Num a) => SumCat k h a where
20762076
-- sumC :: h a `k` a
20772077

2078-
class (Ok k a, Additive a) => AddCat k h a where
2078+
class Ok k a => AddCat k h a where
20792079
sumAC :: h a `k` a
20802080

20812081
-- class IxSummable n => IxSummableCat k n where

examples/src/ConCat/Dual.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ instance (PointedCat k h a, Additive a) => AddCat (Dual k) h a where
224224
sumAC = abst pointC
225225
{-# INLINE sumAC #-}
226226

227-
instance (AddCat k h a, OkF k h) => PointedCat (Dual k) h a where
227+
instance (AddCat k h a, Additive a, OkF k h) => PointedCat (Dual k) h a where
228228
pointC = abst sumAC
229229
{-# INLINE pointC #-}
230230

examples/src/ConCat/StackVM.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ evalStackFun (SF f) = rcounit . f . runit
5858

5959
instance Category StackFun where
6060
id = stackFun id
61-
-- SF g . SF f = SF (g . f)
62-
(.) = inSF2 (.)
61+
SF g . SF f = SF (g . f)
62+
-- (.) = inSF2 (.)
6363
{-# INLINE id #-}
6464
{-# INLINE (.) #-}
6565

@@ -70,9 +70,9 @@ instance AssociativePCat StackFun where
7070
{-# INLINE rassocP #-}
7171

7272
instance MonoidalPCat StackFun where
73-
first = inSF inRassocP -- okay
73+
-- first = inSF inRassocP -- okay
7474
-- first (SF f) = SF (inRassocP f)
75-
-- first (SF f) = SF (lassocP . f . rassocP)
75+
first (SF f) = SF (lassocP . f . rassocP)
7676
-- first (SF f) = SF lassocP . SF f . SF rassocP -- doesn't type-check
7777
second = secondFirst
7878
f *** g = second g . first f

inline/src/ConCat/Inline/Plugin.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,17 @@ import qualified ConCat.Inline.ClassOp as CO
1212
import Data.List (elemIndex)
1313

1414
-- GHC API
15+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
16+
import GHC.Core.Class (classAllSelIds)
17+
import GHC.Plugins
18+
import GHC.Types.Id.Make (mkDictSelRhs)
19+
import GHC.Runtime.Loader
20+
#else
1521
import GhcPlugins
1622
import Class (classAllSelIds)
1723
import MkId (mkDictSelRhs)
1824
import DynamicLoading
25+
#endif
1926

2027
plugin :: Plugin
2128
plugin = defaultPlugin { installCoreToDos = install

plugin/src/ConCat/Plugin.hs

Lines changed: 87 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,32 @@ import qualified Data.Sequence as Seq
3636
import qualified Data.Set as OrdSet
3737
--import qualified Data.Map (Map) as OrdMap
3838
import qualified Data.Map as OrdMap
39-
#if MIN_VERSION_GLASGOW_HASKELL(8,2,0,0)
40-
import qualified UniqDFM as DFMap
41-
#endif
4239
import Text.Printf (printf)
4340
import System.IO.Unsafe (unsafePerformIO)
4441
import Data.IORef
4542

43+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
44+
import GHC.Builtin.Names (leftDataConName,rightDataConName
45+
,floatTyConKey,doubleTyConKey,integerTyConKey
46+
,intTyConKey,boolTyConKey)
47+
import GHC.Builtin.Types.Prim (intPrimTyCon)
48+
import GHC.Core.Class (classAllSelIds)
49+
-- For normaliseType etc
50+
import GHC.Core.FamInstEnv
51+
import GHC.Core.Lint (lintExpr)
52+
import GHC.Core.Opt.Arity (etaExpand)
53+
import GHC.Core.SimpleOpt (simpleOptExpr)
54+
import GHC.Core.TyCo.Rep
55+
import GHC.Core.Type (coreView)
56+
import GHC.Data.Pair (Pair(..))
57+
import GHC.Plugins as GHC hiding (substTy,cat)
58+
import GHC.Runtime.Loader
59+
import GHC.Tc.Utils.TcType (isFloatTy,isDoubleTy,isIntegerTy,isIntTy,isBoolTy,isUnitTy
60+
,tcSplitTyConApp_maybe)
61+
import GHC.Types.Id.Make (mkDictSelRhs,coerceId)
62+
import GHC.Types.Unique (mkBuiltinUnique)
63+
import qualified GHC.Types.Unique.DFM as DFMap
64+
#else
4665
import GhcPlugins as GHC hiding (substTy,cat)
4766
import Class (classAllSelIds)
4867
import CoreArity (etaExpand)
@@ -57,32 +76,55 @@ import Type (coreView)
5776
import TcType (isFloatTy,isDoubleTy,isIntegerTy,isIntTy,isBoolTy,isUnitTy
5877
,tcSplitTyConApp_maybe)
5978
import TysPrim (intPrimTyCon)
60-
import FamInstEnv (normaliseType)
79+
-- For normaliseType etc
80+
import FamInstEnv
6181
#if MIN_VERSION_GLASGOW_HASKELL(8,2,0,0)
6282
import CoreOpt (simpleOptExpr)
83+
import qualified UniqDFM as DFMap
6384
#endif
6485
import TyCoRep
65-
import GHC.Classes
6686
import Unique (mkBuiltinUnique)
67-
-- For normaliseType etc
68-
import FamInstEnv
87+
#endif
88+
import GHC.Classes
6989

7090
import ConCat.Misc (Unop,Binop,Ternop,PseudoFun(..),(~>))
7191
import ConCat.BuildDictionary
7292
-- import ConCat.Simplify
7393

74-
-- GHC 8.10 FunTy as an extra operand
75-
#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0)
76-
pattern FunTy' a r <-
77-
FunTy _ a r
78-
94+
pattern FunCo' :: Role -> Coercion -> Coercion -> Coercion
95+
mkFunCo' :: Role -> Coercion -> Coercion -> Coercion
96+
pattern FunTy' :: Type -> Type -> Type
7997
mkFunTy' :: Type -> Type -> Type
80-
mkFunTy' a b = FunTy VisArg a b
81-
#else
98+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
99+
pattern FunCo' r a b <- FunCo r _ a b
100+
mkFunCo' r = FunCo r (multToCo One)
101+
pattern FunTy' a r <- FunTy _ _ a r
102+
mkFunTy' = FunTy VisArg One
103+
-- GHC 8.10 FunTy as an extra operand
104+
#elif MIN_VERSION_GLASGOW_HASKELL(8,10,0,0)
105+
pattern FunCo' r a b = FunCo r a b
106+
mkFunCo' = FunCo
107+
pattern FunTy' a r <- FunTy _ a r
108+
mkFunTy' = FunTy VisArg
109+
#elif MIN_VERSION_GLASGOW_HASKELL(8,2,0,0)
110+
pattern FunCo' r a b = FunCo r a b
111+
mkFunCo' = FunCo
82112
pattern FunTy' a r = FunTy a r
113+
mkFunTy' = FunTy
114+
#else
115+
pattern FunCo' r dom ran <- TyConAppCo r (isFunTyCon -> True) [dom,ran]
116+
where FunCo' = mkFunCo
117+
pattern FunTy' dom ran <- (splitFunTy_maybe -> Just (dom,ran))
118+
where FunTy' = mkFunTy
119+
-- TODO: Replace explicit uses of splitFunTy_maybe
120+
-- TODO: Look for other useful pattern synonyms
121+
#endif
83122

84-
mkFunTy' :: Type -> Type -> Type
85-
mkFunTy' a b = FunTy a b
123+
splitFunTy_maybe' :: Type -> Maybe (Type, Type)
124+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
125+
splitFunTy_maybe' = fmap (\(_, a, b) -> (a, b)) . splitFunTy_maybe
126+
#else
127+
splitFunTy_maybe' = splitFunTy_maybe
86128
#endif
87129

88130
-- Information needed for reification. We construct this info in
@@ -121,8 +163,10 @@ data CccEnv = CccEnv { dtrace :: forall a. String -> SDoc -> a -> a
121163
-- , hasRepFromAbstCo :: Coercion -> CoreExpr
122164
, prePostV :: Id
123165
-- , lazyV :: Id
124-
#if MIN_VERSION_GLASGOW_HASKELL(8,2,0,0)
125-
, boxers :: DFMap.UniqDFM {- TyCo-} Id -- to remove
166+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
167+
, boxers :: DFMap.UniqDFM TyCon Id -- to remove
168+
#elif MIN_VERSION_GLASGOW_HASKELL(8,2,0,0)
169+
, boxers :: DFMap.UniqDFM Id -- to remove
126170
#else
127171
, boxers :: OrdMap.Map TyCon Id
128172
#endif
@@ -191,7 +235,7 @@ ccc (CccEnv {..}) (Ops {..}) cat =
191235
Trying("top flipForkT")
192236
-- f | pprTrace "flipForkT tests"
193237
-- (ppr ( splitFunTy (exprType f)
194-
-- , second splitFunTy_maybe (splitFunTy (exprType f))
238+
-- , second splitFunTy_maybe' (splitFunTy (exprType f))
195239
-- , not catClosed)) False = undefined
196240
f | z `FunTy` (a `FunTy` b) <- exprType f
197241
, not catClosed
@@ -269,7 +313,7 @@ ccc (CccEnv {..}) (Ops {..}) cat =
269313
-- I think GHC is undoing this transformation, so continue eagerly
270314
-- (`Cast` co') <$> go e
271315
Trying("top const cast")
272-
Cast (Lam v e) (FunCo _r _ co'@(coercionKind -> Pair b b'))
316+
Cast (Lam v e) (FunCo' _r _ co'@(coercionKind -> Pair b b'))
273317
| not (v `isFreeIn` e)
274318
-- , dtrace "top const cast" (ppr (varWithType castConstTV)) True
275319
, Just mk <- onDictMaybe <=< onDictMaybe $
@@ -327,7 +371,7 @@ ccc (CccEnv {..}) (Ops {..}) cat =
327371
-- dtrace "top App result" (ppr (mkCompose cat uncU' (mkFork cat v' (mkId cat dom)))) $
328372
return (mkCompose cat uncU' (mkFork cat v' (mkId cat dom)))
329373
where
330-
Just (dom,_) = splitFunTy_maybe (exprType e)
374+
Just (dom,_) = splitFunTy_maybe' (exprType e)
331375
Tick t e -> Doing("top tick")
332376
return $ Tick t (mkCcc e)
333377
_e -> Doing("top Unhandled")
@@ -590,7 +634,7 @@ ccc (CccEnv {..}) (Ops {..}) cat =
590634
co'' = downgradeRole r r' co' -- same as co?
591635
in
592636
-- pprTrace "lam nominal Cast" (ppr co $$ text "-->" $$ ppr co'') $
593-
return (mkCcc (Cast (Lam x body') (FunCo r (mkReflCo r xty) co'')))
637+
return (mkCcc (Cast (Lam x body') (mkFunCo' r (mkReflCo r xty) co'')))
594638
Trying("lam representational cast")
595639
e@(Cast e' _) ->
596640
Doing("lam representational cast")
@@ -839,7 +883,7 @@ mkOps (CccEnv {..}) guts annotations famEnvs dflags inScope evTy ev cat = Ops {.
839883
catTy (tyArgs2 -> (a,b)) = mkAppTys cat [a,b]
840884
reCatCo :: Rewrite Coercion
841885
-- reCatCo co | dtrace "reCatCo" (ppr co) False = undefined
842-
reCatCo (FunCo r a b) = Just (mkAppCos (mkReflCo r cat) [a,b])
886+
reCatCo (FunCo' r a b) = Just (mkAppCos (mkReflCo r cat) [a,b])
843887
reCatCo (splitAppCo_maybe -> Just
844888
(splitAppCo_maybe -> Just
845889
#if MIN_VERSION_GLASGOW_HASKELL(8,8,0,0)
@@ -890,7 +934,7 @@ mkOps (CccEnv {..}) guts annotations famEnvs dflags inScope evTy ev cat = Ops {.
890934
noDictErr doc =
891935
either (\ msg -> pprPanic "ccc - couldn't build dictionary for" (doc GHC.<> colon $$ msg)) id
892936
onDictTry :: CoreExpr -> Either SDoc CoreExpr
893-
onDictTry e | Just (ty,_) <- splitFunTy_maybe (exprType e)
937+
onDictTry e | Just (ty,_) <- splitFunTy_maybe' (exprType e)
894938
, isPredTy' ty = App e <$> buildDictMaybe ty
895939
| otherwise = return e
896940
-- pprPanic "ccc / onDictTy: not a function from pred" (pprWithType e)
@@ -907,7 +951,7 @@ mkOps (CccEnv {..}) guts annotations famEnvs dflags inScope evTy ev cat = Ops {.
907951
-- Yet another variant: keep applying to dictionaries as long as we have
908952
-- a predicate type. TODO: reassess and refactor these variants.
909953
onDicts :: Unop CoreExpr
910-
onDicts e | Just (ty,_) <- splitFunTy_maybe (exprType e)
954+
onDicts e | Just (ty,_) <- splitFunTy_maybe' (exprType e)
911955
, isPredTy' ty = onDicts (onDict e)
912956
| otherwise = e
913957
buildDictMaybe :: Type -> Either SDoc CoreExpr
@@ -926,7 +970,7 @@ mkOps (CccEnv {..}) guts annotations famEnvs dflags inScope evTy ev cat = Ops {.
926970
mkCcc' e = varApps cccPV [cat,a,b,evTy] [ev,e]
927971
where
928972
(a,b) = fromMaybe (pprPanic "mkCcc non-function:" (pprWithType e)) $
929-
splitFunTy_maybe (exprType e)
973+
splitFunTy_maybe' (exprType e)
930974
mkCcc :: Unop CoreExpr -- Any reason to parametrize over Cat?
931975
mkCcc e = -- dtrace "mkCcc" (ppr (cat, e)) $
932976
mkCcc' e
@@ -1330,12 +1374,12 @@ composeRuleName = fsLit "compose/coerce"
13301374
evidenceRuleName :: FastString
13311375
evidenceRuleName = fsLit "evidence annotation"
13321376

1333-
cccRules :: Maybe (IORef Int) -> FamInstEnvs -> CccEnv -> ModGuts -> AnnEnv -> [CoreRule]
1334-
cccRules steps famEnvs env@(CccEnv {..}) guts annotations =
1377+
cccRules :: Maybe (IORef Int) -> FamInstEnvs -> CccEnv -> ModGuts -> AnnEnv -> DynFlags -> [CoreRule]
1378+
cccRules steps famEnvs env@(CccEnv {..}) guts annotations dflags =
13351379
[ BuiltinRule { ru_name = cccRuleName
13361380
, ru_fn = varName cccPV
13371381
, ru_nargs = 6 -- including type args
1338-
, ru_try = \ dflags inScope _fn ->
1382+
, ru_try = \ _rOpts inScope _fn ->
13391383
\ case
13401384
-- _args | pprTrace "ccc ru_try args" (ppr _args) False -> undefined
13411385
_es@(Type k : Type _a : Type _b : Type evType : ev : arg : _) ->
@@ -1405,7 +1449,7 @@ install opts todos =
14051449
let famEnvs = (pkgFamEnv, mg_fam_inst_env guts)
14061450
maxSteps = (unsafePerformIO . newIORef) <$>
14071451
parseOpt "maxSteps" opts
1408-
return (on_mg_rules (++ cccRules maxSteps famEnvs env guts allAnns) guts)
1452+
return (on_mg_rules (++ cccRules maxSteps famEnvs env guts allAnns dflags) guts)
14091453
delCccRule guts = return (on_mg_rules (filter (not . isCccRule)) guts)
14101454
isCccRule r = isBuiltinRule r && ru_name r `elem` [cccRuleName,composeRuleName]
14111455
-- isCCC r | is = pprTrace "delRule" (ppr cccRuleName) is
@@ -1561,8 +1605,13 @@ mkCccEnv opts = do
15611605
let boxers = OrdMap.fromList [(intTyCon,boxIV),(doubleTyCon,boxDV),(floatTyCon,boxFV)]
15621606
#endif
15631607
-- _ <- findId "GHC.Num" "subtract" -- help the plugin find instances for Float and Double
1608+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
1609+
when (isDeadEndId cccV) $
1610+
pprPanic "isDeadEndId cccV" empty
1611+
#else
15641612
when (isBottomingId cccV) $
15651613
pprPanic "isBottomingId cccV" empty
1614+
#endif
15661615
return (CccEnv { .. })
15671616

15681617
-- Variables that have associated ccc rewrite rules in AltCat. If we have
@@ -1698,7 +1747,11 @@ qualifiedName nm =
16981747
-- binders, which is handy as dead binders can appear with live binders of the
16991748
-- same variable.
17001749
subst :: [(Id,CoreExpr)] -> Unop CoreExpr
1750+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
1751+
subst ps = substExpr (foldr add emptySubst ps')
1752+
#else
17011753
subst ps = substExpr "subst" (foldr add emptySubst ps')
1754+
#endif
17021755
where
17031756
add (v,new) sub = extendIdSubst sub v new
17041757
ps' = filter (not . isDeadBinder . fst) ps
@@ -1756,22 +1809,6 @@ stringExpr = Lit . mkMachString
17561809
varNameExpr :: Id -> CoreExpr
17571810
varNameExpr = stringExpr . uniqVarName
17581811

1759-
#if ! MIN_VERSION_GLASGOW_HASKELL(8,2,0,0)
1760-
1761-
pattern FunTy :: Type -> Type -> Type
1762-
pattern FunTy dom ran <- (splitFunTy_maybe -> Just (dom,ran))
1763-
where FunTy = mkFunTy
1764-
1765-
-- TODO: Replace explicit uses of splitFunTy_maybe
1766-
1767-
-- TODO: Look for other useful pattern synonyms
1768-
1769-
pattern FunCo :: Role -> Coercion -> Coercion -> Coercion
1770-
pattern FunCo r dom ran <- TyConAppCo r (isFunTyCon -> True) [dom,ran]
1771-
where FunCo = mkFunCo
1772-
1773-
#endif
1774-
17751812
onCaseRhs :: Type -> Unop (Unop CoreExpr)
17761813
onCaseRhs altsTy' f (Case scrut v _ alts) =
17771814
Case scrut v altsTy' (onAltRhs f <$> alts)
@@ -1858,7 +1895,11 @@ onExprHead _dflags h = (fmap.fmap) simpleOptExpr' $
18581895
freshId :: VarSet -> String -> Type -> Id
18591896
freshId used nm ty =
18601897
uniqAway (mkInScopeSet used) $
1898+
#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
1899+
mkSysLocal (fsLit nm) (mkBuiltinUnique 17) One ty
1900+
#else
18611901
mkSysLocal (fsLit nm) (mkBuiltinUnique 17) ty
1902+
#endif
18621903

18631904
freshDeadId :: VarSet -> String -> Type -> Id
18641905
freshDeadId used nm ty = setIdOccInfo (freshId used nm ty) IAmDead

0 commit comments

Comments
 (0)