summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitrios Vytiniotis <dimitris@microsoft.com>2011-11-15 15:44:56 +0000
committerDimitrios Vytiniotis <dimitris@microsoft.com>2011-11-15 15:44:56 +0000
commit6145e69a604c942ae5513ff5edd0a2fc44978a1b (patch)
treefe937f5a465e4cdcbdc7ae5f20fb0fb46a20a7d3
parent1d0ad7b8a59cfeca9f5df7f58726607bfd2e920f (diff)
parent1d47564e9f8761c5ea6c5b42720ceea7d4bda2af (diff)
downloadhaskell-6145e69a604c942ae5513ff5edd0a2fc44978a1b.tar.gz
Merge branch 'master' of http://darcs.haskell.org/ghc into ghc-constraint-solver
Conflicts: compiler/coreSyn/CoreLint.lhs compiler/iface/BinIface.hs compiler/prelude/TysPrim.lhs compiler/simplCore/Simplify.lhs compiler/typecheck/TcCanonical.lhs compiler/typecheck/TcInteract.lhs compiler/typecheck/TcMType.lhs compiler/typecheck/TcSMonad.lhs
-rw-r--r--compiler/basicTypes/BasicTypes.lhs2
-rw-r--r--compiler/basicTypes/DataCon.lhs1
-rw-r--r--compiler/basicTypes/Literal.lhs4
-rw-r--r--compiler/basicTypes/MkId.lhs2
-rw-r--r--compiler/basicTypes/OccName.lhs35
-rw-r--r--compiler/basicTypes/RdrName.lhs10
-rw-r--r--compiler/basicTypes/Var.lhs49
-rw-r--r--compiler/codeGen/CgPrimOp.hs2
-rw-r--r--compiler/codeGen/StgCmmPrim.hs2
-rw-r--r--compiler/coreSyn/CoreArity.lhs27
-rw-r--r--compiler/coreSyn/CoreLint.lhs224
-rw-r--r--compiler/coreSyn/CoreUtils.lhs43
-rw-r--r--compiler/coreSyn/MkCore.lhs4
-rw-r--r--compiler/coreSyn/MkExternalCore.lhs1
-rw-r--r--compiler/coreSyn/PprCore.lhs1
-rw-r--r--compiler/deSugar/Coverage.lhs3
-rw-r--r--compiler/deSugar/Desugar.lhs2
-rw-r--r--compiler/deSugar/DsExpr.lhs6
-rw-r--r--compiler/deSugar/DsListComp.lhs16
-rw-r--r--compiler/deSugar/DsMeta.hs16
-rw-r--r--compiler/deSugar/DsMonad.lhs207
-rw-r--r--compiler/deSugar/DsUtils.lhs4
-rwxr-xr-xcompiler/ghc.cabal.in1
-rw-r--r--compiler/ghci/RtClosureInspect.hs3
-rw-r--r--compiler/hsSyn/Convert.lhs22
-rw-r--r--compiler/hsSyn/HsBinds.lhs7
-rw-r--r--compiler/hsSyn/HsDecls.lhs33
-rw-r--r--compiler/hsSyn/HsExpr.lhs10
-rw-r--r--compiler/hsSyn/HsExpr.lhs-boot12
-rw-r--r--compiler/hsSyn/HsLit.lhs23
-rw-r--r--compiler/hsSyn/HsPat.lhs-boot5
-rw-r--r--compiler/hsSyn/HsTypes.lhs177
-rw-r--r--compiler/iface/BinIface.hs1739
-rw-r--r--compiler/iface/BuildTyCl.lhs26
-rw-r--r--compiler/iface/FlagChecker.hs47
-rw-r--r--compiler/iface/IfaceSyn.lhs12
-rw-r--r--compiler/iface/IfaceType.lhs97
-rw-r--r--compiler/iface/LoadIface.lhs3
-rw-r--r--compiler/iface/MkIface.lhs793
-rw-r--r--compiler/iface/TcIface.lhs101
-rw-r--r--compiler/iface/TcIface.lhs-boot4
-rw-r--r--compiler/main/DriverPipeline.hs8
-rw-r--r--compiler/main/DynFlags.hs48
-rw-r--r--compiler/main/GHC.hs4
-rw-r--r--compiler/main/HscMain.hs6
-rw-r--r--compiler/main/HscTypes.lhs453
-rw-r--r--compiler/main/Packages.lhs8
-rw-r--r--compiler/main/TidyPgm.lhs12
-rw-r--r--compiler/parser/Lexer.x17
-rw-r--r--compiler/parser/Parser.y.pp109
-rw-r--r--compiler/parser/ParserCore.y16
-rw-r--r--compiler/parser/RdrHsSyn.lhs38
-rw-r--r--compiler/prelude/PrelNames.lhs90
-rw-r--r--compiler/prelude/TysPrim.lhs128
-rw-r--r--compiler/prelude/TysWiredIn.lhs17
-rw-r--r--compiler/prelude/primops.txt.pp9
-rw-r--r--compiler/rename/RnBinds.lhs2
-rw-r--r--compiler/rename/RnEnv.lhs154
-rw-r--r--compiler/rename/RnExpr.lhs25
-rw-r--r--compiler/rename/RnExpr.lhs-boot34
-rw-r--r--compiler/rename/RnHsSyn.lhs31
-rw-r--r--compiler/rename/RnPat.lhs5
-rw-r--r--compiler/rename/RnSource.lhs109
-rw-r--r--compiler/rename/RnTypes.lhs187
-rw-r--r--compiler/simplCore/FloatOut.lhs14
-rw-r--r--compiler/simplCore/SetLevels.lhs22
-rw-r--r--compiler/simplCore/SimplEnv.lhs11
-rw-r--r--compiler/simplCore/SimplUtils.lhs32
-rw-r--r--compiler/simplCore/Simplify.lhs66
-rw-r--r--compiler/typecheck/FamInst.lhs1
-rw-r--r--compiler/typecheck/TcArrows.lhs9
-rw-r--r--compiler/typecheck/TcBinds.lhs1
-rw-r--r--compiler/typecheck/TcCanonical.lhs47
-rw-r--r--compiler/typecheck/TcClassDcl.lhs4
-rwxr-xr-xcompiler/typecheck/TcDeriv.lhs11
-rw-r--r--compiler/typecheck/TcEnv.lhs60
-rw-r--r--compiler/typecheck/TcExpr.lhs33
-rw-r--r--compiler/typecheck/TcHsSyn.lhs252
-rw-r--r--compiler/typecheck/TcHsType.lhs565
-rw-r--r--compiler/typecheck/TcInstDcls.lhs84
-rw-r--r--compiler/typecheck/TcInteract.lhs36
-rw-r--r--compiler/typecheck/TcMType.lhs476
-rw-r--r--compiler/typecheck/TcPat.lhs5
-rw-r--r--compiler/typecheck/TcRnDriver.lhs24
-rw-r--r--compiler/typecheck/TcRnMonad.lhs1
-rw-r--r--compiler/typecheck/TcRnTypes.lhs35
-rw-r--r--compiler/typecheck/TcRules.lhs13
-rw-r--r--compiler/typecheck/TcSMonad.lhs20
-rw-r--r--compiler/typecheck/TcSimplify.lhs32
-rw-r--r--compiler/typecheck/TcSplice.lhs23
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs922
-rw-r--r--compiler/typecheck/TcType.lhs59
-rw-r--r--compiler/typecheck/TcUnify.lhs387
-rw-r--r--compiler/typecheck/TcUnify.lhs-boot12
-rw-r--r--compiler/types/Class.lhs28
-rw-r--r--compiler/types/Coercion.lhs81
-rw-r--r--compiler/types/FamInstEnv.lhs88
-rw-r--r--compiler/types/Kind.lhs241
-rw-r--r--compiler/types/TyCon.lhs125
-rw-r--r--compiler/types/Type.lhs151
-rw-r--r--compiler/types/Type.lhs-boot3
-rw-r--r--compiler/types/TypeRep.lhs65
-rw-r--r--compiler/types/TypeRep.lhs-boot1
-rw-r--r--compiler/types/Unify.lhs57
-rw-r--r--compiler/utils/Binary.hs32
-rw-r--r--compiler/utils/Outputable.lhs5
-rw-r--r--compiler/utils/Pretty.lhs9
-rw-r--r--compiler/vectorise/Vectorise/Builtins/Initialise.hs14
-rw-r--r--compiler/vectorise/Vectorise/Env.hs34
-rw-r--r--compiler/vectorise/Vectorise/Exp.hs10
-rw-r--r--compiler/vectorise/Vectorise/Monad.hs5
-rw-r--r--compiler/vectorise/Vectorise/Monad/Naming.hs4
-rw-r--r--compiler/vectorise/Vectorise/Type/Classify.hs22
-rw-r--r--compiler/vectorise/Vectorise/Type/Env.hs14
-rw-r--r--compiler/vectorise/Vectorise/Type/TyConDecl.hs33
-rwxr-xr-xdocs/users_guide/glasgow_exts.xml20
-rw-r--r--docs/users_guide/using.xml7
-rw-r--r--ghc.mk11
-rw-r--r--libffi/package.conf.in35
-rw-r--r--mk/validate-settings.mk5
-rw-r--r--rts/Exception.cmm4
-rw-r--r--rts/Profiling.c24
-rw-r--r--rts/Profiling.h2
-rw-r--r--rts/RaiseAsync.c2
-rw-r--r--rts/package.conf.in2
-rw-r--r--rts/win32/Ticker.c3
126 files changed, 5815 insertions, 3865 deletions
diff --git a/compiler/basicTypes/BasicTypes.lhs b/compiler/basicTypes/BasicTypes.lhs
index 1f42d252ce..c6226cac67 100644
--- a/compiler/basicTypes/BasicTypes.lhs
+++ b/compiler/basicTypes/BasicTypes.lhs
@@ -588,6 +588,7 @@ data HsBang = HsNoBang
| HsUnpackFailed -- An UNPACK pragma that we could not make
-- use of, because the type isn't unboxable;
-- equivalant to HsStrict except for checkValidDataCon
+ | HsNoUnpack -- {-# NOUNPACK #-} ! (GHC extension, meaning "strict but not unboxed")
deriving (Eq, Data, Typeable)
instance Outputable HsBang where
@@ -595,6 +596,7 @@ instance Outputable HsBang where
ppr HsStrict = char '!'
ppr HsUnpack = ptext (sLit "{-# UNPACK #-} !")
ppr HsUnpackFailed = ptext (sLit "{-# UNPACK (failed) #-} !")
+ ppr HsNoUnpack = ptext (sLit "{-# NOUNPACK #-} !")
isBanged :: HsBang -> Bool
isBanged HsNoBang = False
diff --git a/compiler/basicTypes/DataCon.lhs b/compiler/basicTypes/DataCon.lhs
index cd7a2e1df3..c2cf0bfcdd 100644
--- a/compiler/basicTypes/DataCon.lhs
+++ b/compiler/basicTypes/DataCon.lhs
@@ -953,6 +953,7 @@ computeRep stricts tys
where
unbox HsNoBang ty = [(NotMarkedStrict, ty)]
unbox HsStrict ty = [(MarkedStrict, ty)]
+ unbox HsNoUnpack ty = [(MarkedStrict, ty)]
unbox HsUnpackFailed ty = [(MarkedStrict, ty)]
unbox HsUnpack ty = zipEqual "computeRep" (dataConRepStrictness arg_dc) arg_tys
where
diff --git a/compiler/basicTypes/Literal.lhs b/compiler/basicTypes/Literal.lhs
index 7fef7c7f5e..417444542a 100644
--- a/compiler/basicTypes/Literal.lhs
+++ b/compiler/basicTypes/Literal.lhs
@@ -143,7 +143,9 @@ easier to write RULEs for them.
in TcIface.
* When looking for CAF-hood (in TidyPgm), we must take account of the
- CAF-hood of the mk_integer field in LitInteger; see TidyPgm.cafRefsL
+ CAF-hood of the mk_integer field in LitInteger; see TidyPgm.cafRefsL.
+ Indeed this is the only reason we put the mk_integer field in the
+ literal -- otherwise we could just look it up in CorePrep.
Binary instance
diff --git a/compiler/basicTypes/MkId.lhs b/compiler/basicTypes/MkId.lhs
index 07ecc85ba7..a40d46f8a9 100644
--- a/compiler/basicTypes/MkId.lhs
+++ b/compiler/basicTypes/MkId.lhs
@@ -1024,7 +1024,7 @@ voidArgId -- :: State# RealWorld
coercionTokenId :: Id -- :: () ~ ()
coercionTokenId -- Used to replace Coercion terms when we go to STG
= pcMiscPrelId coercionTokenName
- (mkTyConApp eqPrimTyCon [unitTy, unitTy])
+ (mkTyConApp eqPrimTyCon [liftedTypeKind, unitTy, unitTy])
noCafIdInfo
\end{code}
diff --git a/compiler/basicTypes/OccName.lhs b/compiler/basicTypes/OccName.lhs
index a48a7d44bd..fa8635091d 100644
--- a/compiler/basicTypes/OccName.lhs
+++ b/compiler/basicTypes/OccName.lhs
@@ -53,6 +53,7 @@ module OccName (
mkDFunOcc,
mkTupleOcc,
setOccNameSpace,
+ demoteOccName,
-- ** Derived 'OccName's
isDerivedOccName,
@@ -204,8 +205,35 @@ pprNameSpaceBrief DataName = char 'd'
pprNameSpaceBrief VarName = char 'v'
pprNameSpaceBrief TvName = ptext (sLit "tv")
pprNameSpaceBrief TcClsName = ptext (sLit "tc")
+
+-- demoteNameSpace lowers the NameSpace if possible. We can not know
+-- in advance, since a TvName can appear in an HsTyVar.
+-- see Note [Demotion]
+demoteNameSpace :: NameSpace -> Maybe NameSpace
+demoteNameSpace VarName = Nothing
+demoteNameSpace DataName = Nothing
+demoteNameSpace TvName = Nothing
+demoteNameSpace TcClsName = Just DataName
\end{code}
+Note [Demotion]
+~~~~~~~~~~~~~~~
+
+When the user writes:
+ data Nat = Zero | Succ Nat
+ foo :: f Zero -> Int
+
+'Zero' in the type signature of 'foo' is parsed as:
+ HsTyVar ("Zero", TcClsName)
+
+When the renamer hits this occurence of 'Zero' it's going to realise
+that it's not in scope. But because it is renaming a type, it knows
+that 'Zero' might be a promoted data constructor, so it will demote
+its namespace to DataName and do a second lookup.
+
+The final result (after the renamer) will be:
+ HsTyVar ("Zero", DataName)
+
%************************************************************************
%* *
@@ -316,6 +344,13 @@ mkClsOcc = mkOccName clsName
mkClsOccFS :: FastString -> OccName
mkClsOccFS = mkOccNameFS clsName
+
+-- demoteOccName lowers the Namespace of OccName.
+-- see Note [Demotion]
+demoteOccName :: OccName -> Maybe OccName
+demoteOccName (OccName space name) = do
+ space' <- demoteNameSpace space
+ return $ OccName space' name
\end{code}
diff --git a/compiler/basicTypes/RdrName.lhs b/compiler/basicTypes/RdrName.lhs
index ba09d923b8..0353e65d04 100644
--- a/compiler/basicTypes/RdrName.lhs
+++ b/compiler/basicTypes/RdrName.lhs
@@ -40,7 +40,7 @@ module RdrName (
nameRdrName, getRdrName,
-- ** Destruction
- rdrNameOcc, rdrNameSpace, setRdrNameSpace,
+ rdrNameOcc, rdrNameSpace, setRdrNameSpace, demoteRdrName,
isRdrDataCon, isRdrTyVar, isRdrTc, isQual, isQual_maybe, isUnqual,
isOrig, isOrig_maybe, isExact, isExact_maybe, isSrcRdrName,
@@ -159,6 +159,14 @@ setRdrNameSpace (Orig m occ) ns = Orig m (setOccNameSpace ns occ)
setRdrNameSpace (Exact n) ns = ASSERT( isExternalName n )
Orig (nameModule n)
(setOccNameSpace ns (nameOccName n))
+
+-- demoteRdrName lowers the NameSpace of RdrName.
+-- see Note [Demotion] in OccName
+demoteRdrName :: RdrName -> Maybe RdrName
+demoteRdrName (Unqual occ) = fmap Unqual (demoteOccName occ)
+demoteRdrName (Qual m occ) = fmap (Qual m) (demoteOccName occ)
+demoteRdrName (Orig _ _) = panic "demoteRdrName"
+demoteRdrName (Exact _) = panic "demoteRdrName"
\end{code}
\begin{code}
diff --git a/compiler/basicTypes/Var.lhs b/compiler/basicTypes/Var.lhs
index a923f4d9dd..1692520858 100644
--- a/compiler/basicTypes/Var.lhs
+++ b/compiler/basicTypes/Var.lhs
@@ -39,7 +39,7 @@
module Var (
-- * The main data type and synonyms
- Var, TyVar, CoVar, Id, DictId, DFunId, EvVar, EqVar, EvId, IpId,
+ Var, TyVar, CoVar, Id, KindVar, DictId, DFunId, EvVar, EqVar, EvId, IpId,
-- ** Taking 'Var's apart
varName, varUnique, varType,
@@ -60,20 +60,21 @@ module Var (
mustHaveLocalBinding,
-- ** Constructing 'TyVar's
- mkTyVar, mkTcTyVar,
+ mkTyVar, mkTcTyVar, mkKindVar,
-- ** Taking 'TyVar's apart
tyVarName, tyVarKind, tcTyVarDetails, setTcTyVarDetails,
-- ** Modifying 'TyVar's
- setTyVarName, setTyVarUnique, setTyVarKind
+ setTyVarName, setTyVarUnique, setTyVarKind, updateTyVarKind,
+ updateTyVarKindM
) where
#include "HsVersions.h"
#include "Typeable.h"
-import {-# SOURCE #-} TypeRep( Type, Kind )
+import {-# SOURCE #-} TypeRep( Type, Kind, SuperKind )
import {-# SOURCE #-} TcType( TcTyVarDetails, pprTcTyVarDetails )
import {-# SOURCE #-} IdInfo( IdDetails, IdInfo, coVarDetails, vanillaIdInfo, pprIdDetails )
@@ -98,7 +99,10 @@ import Data.Data
\begin{code}
type Id = Var -- A term-level identifier
-type TyVar = Var
+
+type TyVar = Var -- Type *or* kind variable
+type KindVar = Var -- Definitely a kind variable
+ -- See Note [Kind and type variables]
-- See Note [Evidence: EvIds and CoVars]
type EvId = Id -- Term-level evidence: DictId, IpId, or EqVar
@@ -125,6 +129,16 @@ Note [Evidence: EvIds and CoVars]
* Only CoVars can occur in Coercions (but NB the LCoercion hack; see
Note [LCoercions] in Coercion).
+Note [Kind and type variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Before kind polymorphism, TyVar were used to mean type variables. Now
+they are use to mean kind *or* type variables. KindVar is used when we
+know for sure that it is a kind variable. In future, we might want to
+go over the whole compiler code to use:
+ - KiTyVar to mean kind or type variables
+ - TyVar to mean type variables only
+ - KindVar to mean kind variables
+
%************************************************************************
%* *
@@ -142,7 +156,8 @@ in its @VarDetails@.
-- | Essentially a typed 'Name', that may also contain some additional information
-- about the 'Var' and it's use sites.
data Var
- = TyVar {
+ = TyVar { -- type and kind variables
+ -- see Note [Kind and type variables]
varName :: !Name,
realUnique :: FastInt, -- Key for fast comparison
-- Identical to the Unique in the name,
@@ -195,7 +210,8 @@ After CoreTidy, top-level LocalIds are turned into GlobalIds
\begin{code}
instance Outputable Var where
- ppr var = ppr (varName var) <+> ifPprDebug (brackets (ppr_debug var))
+ ppr var = ifPprDebug (text "(") <+> ppr (varName var) <+> ifPprDebug (brackets (ppr_debug var))
+ <+> ifPprDebug (text "::" <+> ppr (tyVarKind var) <+> text ")")
ppr_debug :: Var -> SDoc
ppr_debug (TyVar {}) = ptext (sLit "tv")
@@ -255,7 +271,7 @@ setVarType id ty = id { varType = ty }
%************************************************************************
%* *
-\subsection{Type variables}
+\subsection{Type and kind variables}
%* *
%************************************************************************
@@ -274,6 +290,14 @@ setTyVarName = setVarName
setTyVarKind :: TyVar -> Kind -> TyVar
setTyVarKind tv k = tv {varType = k}
+
+updateTyVarKind :: (Kind -> Kind) -> TyVar -> TyVar
+updateTyVarKind update tv = tv {varType = update (tyVarKind tv)}
+
+updateTyVarKindM :: (Monad m) => (Kind -> m Kind) -> TyVar -> m TyVar
+updateTyVarKindM update tv
+ = do { k' <- update (tyVarKind tv)
+ ; return $ tv {varType = k'} }
\end{code}
\begin{code}
@@ -298,6 +322,15 @@ tcTyVarDetails var = pprPanic "tcTyVarDetails" (ppr var)
setTcTyVarDetails :: TyVar -> TcTyVarDetails -> TyVar
setTcTyVarDetails tv details = tv { tc_tv_details = details }
+
+mkKindVar :: Name -> SuperKind -> KindVar
+-- mkKindVar take a SuperKind as argument because we don't have access
+-- to tySuperKind here.
+mkKindVar name kind = TyVar
+ { varName = name
+ , realUnique = getKeyFastInt (nameUnique name)
+ , varType = kind }
+
\end{code}
%************************************************************************
diff --git a/compiler/codeGen/CgPrimOp.hs b/compiler/codeGen/CgPrimOp.hs
index 23708fe568..6fe934b54c 100644
--- a/compiler/codeGen/CgPrimOp.hs
+++ b/compiler/codeGen/CgPrimOp.hs
@@ -811,7 +811,7 @@ emitCloneArray info_p res_r src0 src_off0 n0 live = do
(CmmLit $ mkIntCLit 0)
let arr = CmmReg (CmmLocal arr_r)
- emitSetDynHdr arr (CmmLit (CmmLabel info_p)) curCCSAddr
+ emitSetDynHdr arr (CmmLit (CmmLabel info_p)) curCCS
stmtC $ CmmStore (cmmOffsetB arr (fixedHdrSize * wORD_SIZE +
oFFSET_StgMutArrPtrs_ptrs)) n
stmtC $ CmmStore (cmmOffsetB arr (fixedHdrSize * wORD_SIZE +
diff --git a/compiler/codeGen/StgCmmPrim.hs b/compiler/codeGen/StgCmmPrim.hs
index 8935d56537..f8cc4256f4 100644
--- a/compiler/codeGen/StgCmmPrim.hs
+++ b/compiler/codeGen/StgCmmPrim.hs
@@ -877,7 +877,7 @@ emitCloneArray info_p res_r src0 src_off0 n0 = do
(CmmLit $ mkIntCLit 0)
let arr = CmmReg (CmmLocal arr_r)
- emitSetDynHdr arr (CmmLit (CmmLabel info_p)) curCCSAddr
+ emitSetDynHdr arr (CmmLit (CmmLabel info_p)) curCCS
emit $ mkStore (cmmOffsetB arr (fixedHdrSize * wORD_SIZE +
oFFSET_StgMutArrPtrs_ptrs)) n
emit $ mkStore (cmmOffsetB arr (fixedHdrSize * wORD_SIZE +
diff --git a/compiler/coreSyn/CoreArity.lhs b/compiler/coreSyn/CoreArity.lhs
index 63661ec081..f8565cb4c8 100644
--- a/compiler/coreSyn/CoreArity.lhs
+++ b/compiler/coreSyn/CoreArity.lhs
@@ -139,18 +139,18 @@ Note [exprArity invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~
exprArity has the following invariant:
- * If typeArity (exprType e) = n,
- then manifestArity (etaExpand e n) = n
+ (1) If typeArity (exprType e) = n,
+ then manifestArity (etaExpand e n) = n
- That is, etaExpand can always expand as much as typeArity says
- So the case analysis in etaExpand and in typeArity must match
+ That is, etaExpand can always expand as much as typeArity says
+ So the case analysis in etaExpand and in typeArity must match
- * exprArity e <= typeArity (exprType e)
+ (2) exprArity e <= typeArity (exprType e)
- * Hence if (exprArity e) = n, then manifestArity (etaExpand e n) = n
+ (3) Hence if (exprArity e) = n, then manifestArity (etaExpand e n) = n
- That is, if exprArity says "the arity is n" then etaExpand really
- can get "n" manifest lambdas to the top.
+ That is, if exprArity says "the arity is n" then etaExpand really
+ can get "n" manifest lambdas to the top.
Why is this important? Because
- In TidyPgm we use exprArity to fix the *final arity* of
@@ -561,12 +561,17 @@ type CheapFun = CoreExpr -> Maybe Type -> Bool
arityType :: CheapFun -> CoreExpr -> ArityType
arityType cheap_fn (Cast e co)
- = arityType cheap_fn e
- `andArityType` ATop (typeArity (pSnd (coercionKind co)))
- -- See Note [exprArity invariant]; must be true of
+ = case arityType cheap_fn e of
+ ATop os -> ATop (take co_arity os)
+ ABot n -> ABot (n `min` co_arity)
+ where
+ co_arity = length (typeArity (pSnd (coercionKind co)))
+ -- See Note [exprArity invariant] (2); must be true of
-- arityType too, since that is how we compute the arity
-- of variables, and they in turn affect result of exprArity
-- Trac #5441 is a nice demo
+ -- However, do make sure that ATop -> ATop and ABot -> ABot!
+ -- Casts don't affect that part. Getting this wrong provoked #5475
arityType _ (Var v)
| Just strict_sig <- idStrictness_maybe v
diff --git a/compiler/coreSyn/CoreLint.lhs b/compiler/coreSyn/CoreLint.lhs
index d8b26da1c1..7bd61fa351 100644
--- a/compiler/coreSyn/CoreLint.lhs
+++ b/compiler/coreSyn/CoreLint.lhs
@@ -218,11 +218,13 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs)
%************************************************************************
\begin{code}
-type InType = Type -- Substitution not yet applied
+--type InKind = Kind -- Substitution not yet applied
+type InType = Type
type InCoercion = Coercion
type InVar = Var
type InTyVar = TyVar
+type OutKind = Kind -- Substitution has been applied to this
type OutType = Type -- Substitution has been applied to this
type OutCoercion = Coercion
type OutVar = Var
@@ -296,6 +298,7 @@ lintCoreExpr (Let (Rec pairs) body)
(_, dups) = removeDups compare bndrs
lintCoreExpr e@(App _ _)
+{- DV: This grievous hack (from ghc-constraint-solver should not be needed:
| Var x <- fun -- Greivous hack for Eq# construction: Eq# may have type arguments
-- of kind (* -> *) but its type insists on *. When we have polymorphic kinds,
-- we should do this properly
@@ -309,6 +312,7 @@ lintCoreExpr e@(App _ _)
lintCoreArg (mkCoercionType arg_ty1' arg_ty2' `mkFunTy` mkEqPred (arg_ty1', arg_ty2')) co_e
| otherwise
+-}
= do { fun_ty <- lintCoreExpr fun
; addLoc (AnExpr e) $ foldM lintCoreArg fun_ty args }
where
@@ -370,6 +374,27 @@ lintCoreExpr (Coercion co)
; return (mkCoercionType ty1 ty2) }
\end{code}
+Note [Kind instantiation in coercions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider the following coercion axiom:
+ ax_co [(k_ag :: BOX), (f_aa :: k_ag -> Constraint)] :: T k_ag f_aa ~ f_aa
+
+Consider the following instantiation:
+ ax_co <* -> *> <Monad>
+
+We need to split the co_ax_tvs into kind and type variables in order
+to find out the coercion kind instantiations. Those can only be Refl
+since we don't have kind coercions. This is just a way to represent
+kind instantiation.
+
+We use the number of kind variables to know how to split the coercions
+instantiations between kind coercions and type coercions. We lint the
+kind coercions and produce the following substitution which is to be
+applied in the type variables:
+ k_ag ~~> * -> *
+
+
%************************************************************************
%* *
\subsection[lintCoreArgs]{lintCoreArgs}
@@ -432,10 +457,14 @@ lintValApp arg fun_ty arg_ty
checkTyKind :: OutTyVar -> OutType -> LintM ()
-- Both args have had substitution applied
checkTyKind tyvar arg_ty
+ | isSuperKind tyvar_kind -- kind forall
+ -- IA0_NOTE: I added this case to handle kind foralls
+ = lintKind arg_ty
-- Arg type might be boxed for a function with an uncommitted
-- tyvar; notably this is used so that we can give
-- error :: forall a:*. String -> a
-- and then apply it to both boxed and unboxed types.
+ | otherwise -- type forall
= do { arg_kind <- lintType arg_ty
; unless (arg_kind `isSubKind` tyvar_kind)
(addErrL (mkKindErrMsg tyvar arg_ty)) }
@@ -455,6 +484,16 @@ checkTyCoKind tv co
checkTyCoKinds :: [TyVar] -> [OutCoercion] -> LintM [(OutType, OutType)]
checkTyCoKinds = zipWithM checkTyCoKind
+checkKiCoKind :: KindVar -> OutCoercion -> LintM Kind
+-- see lintCoercion (AxiomInstCo {}) and Note [Kind instantiation in coercions]
+checkKiCoKind kv co
+ = do { ki <- lintKindCoercion co
+ ; unless (isSuperKind (tyVarKind kv)) (addErrL (mkTyCoAppErrMsg kv co))
+ ; return ki }
+
+checkKiCoKinds :: [KindVar] -> [OutCoercion] -> LintM [Kind]
+checkKiCoKinds = zipWithM checkKiCoKind
+
checkDeadIdOcc :: Id -> LintM ()
-- Occurrences of an Id should never be dead....
-- except when we are checking a case pattern
@@ -619,11 +658,11 @@ lintAndScopeId id linterF
lintInTy :: InType -> LintM OutType
-- Check the type, and apply the substitution to it
-- See Note [Linting type lets]
--- ToDo: check the kind structure of the type
lintInTy ty
= addLoc (InType ty) $
do { ty' <- applySubstTy ty
- ; _ <- lintType ty'
+ ; k <- lintType ty'
+ ; lintKind k
; return ty' }
lintInCo :: InCoercion -> LintM OutCoercion
@@ -636,21 +675,33 @@ lintInCo co
; return co' }
-------------------
-lintKind :: Kind -> LintM ()
--- Check well-formedness of kinds: *, *->*, etc
-lintKind (TyConApp tc [])
- | tyConKind tc `eqKind` tySuperKind
- = return ()
+lintKind :: OutKind -> LintM ()
+-- Check well-formedness of kinds: *, *->*, Either * (* -> *), etc
lintKind (FunTy k1 k2)
= lintKind k1 >> lintKind k2
-lintKind kind
+
+lintKind kind@(TyConApp tc kis)
+ = do { unless (tyConArity tc == length kis || isSuperKindTyCon tc)
+ (addErrL malformed_kind)
+ ; mapM_ lintKind kis }
+ where
+ malformed_kind = hang (ptext (sLit "Malformed kind:")) 2 (quotes (ppr kind))
+
+lintKind (TyVarTy kv) = checkTyCoVarInScope kv
+lintKind kind
= addErrL (hang (ptext (sLit "Malformed kind:")) 2 (quotes (ppr kind)))
-------------------
lintTyBndrKind :: OutTyVar -> LintM ()
-lintTyBndrKind tv = lintKind (tyVarKind tv)
+-- Handles both type and kind foralls.
+lintTyBndrKind tv =
+ let ki = tyVarKind tv in
+ if isSuperKind ki
+ then return () -- kind forall
+ else lintKind ki -- type forall
-------------------
+{-
lint_prim_eq_co :: TyCon -> OutCoercion -> [OutCoercion] -> LintM (OutType,OutType)
lint_prim_eq_co tc co arg_cos = case arg_cos of
[co1,co2] -> do { (t1,s1) <- lintCoercion co1
@@ -671,7 +722,17 @@ lint_eq_co tc co arg_cos = case arg_cos of
; return (mkTyConApp tc [t1], mkTyConApp tc [s1]) }
[] -> return (mkTyConApp tc [], mkTyConApp tc [])
_ -> failWithL (ptext (sLit "Oversaturated ~ coercion") <+> ppr co)
+-}
+lintKindCoercion :: OutCoercion -> LintM OutKind
+-- Kind coercions are only reflexivity because they mean kind
+-- instantiation. See Note [Kind coercions] in Coercion
+lintKindCoercion co
+ = do { (k1,k2) <- lintCoercion co
+ ; checkL (k1 `eqKind` k2)
+ (hang (ptext (sLit "Non-refl kind coercion"))
+ 2 (ppr co))
+ ; return k1 }
lintCoercion :: OutCoercion -> LintM (OutType, OutType)
-- Check the kind of a coercion term, returning the kind
@@ -682,6 +743,7 @@ lintCoercion (Refl ty)
; return (ty, ty) }
lintCoercion co@(TyConAppCo tc cos)
+{- DV: This grievous hack (from ghc-constraint-solver) should not be needed any more:
| tc `hasKey` eqPrimTyConKey -- Just as in lintType, treat applications of (~) and (~#)
= lint_prim_eq_co tc co cos -- specially to allow for polymorphism. This hack will
-- hopefully go away when we merge in kind polymorphism.
@@ -695,6 +757,23 @@ lintCoercion co@(TyConAppCo tc cos)
else tyConKind tc -- TODO: Fix this when kind polymorphism is in!
; check_co_app co kind_to_check ss
; return (mkTyConApp tc ss, mkTyConApp tc ts) }
+-}
+ = do -- We use the kind of the type constructor to know how many
+ -- kind coercions we have (one kind coercion for one kind
+ -- instantiation).
+ { let ki | tc `hasKey` funTyConKey && length cos == 2
+ = mkArrowKinds [argTypeKind, openTypeKind] liftedTypeKind
+ -- It's a fully applied function, so we must use the
+ -- most permissive type for the arrow constructor
+ | otherwise = tyConKind tc
+ (kvs, _) = splitForAllTys ki
+ (cokis, cotys) = splitAt (length kvs) cos
+ -- kis are the kind instantiations of tc
+ ; kis <- mapM lintKindCoercion cokis
+ ; (ss,ts) <- mapAndUnzipM lintCoercion cotys
+ ; check_co_app co ki (kis ++ ss)
+ ; return (mkTyConApp tc (kis ++ ss), mkTyConApp tc (kis ++ ts)) }
+
lintCoercion co@(AppCo co1 co2)
= do { (s1,t1) <- lintCoercion co1
@@ -703,7 +782,9 @@ lintCoercion co@(AppCo co1 co2)
; return (mkAppTy s1 s2, mkAppTy t1 t2) }
lintCoercion (ForAllCo v co)
- = do { lintKind (tyVarKind v)
+ = do { let kind = tyVarKind v
+ -- lintKind when type forall, otherwise we are a kind forall
+ ; unless (isSuperKind kind) (lintKind kind)
; (s,t) <- addInScopeVar v (lintCoercion co)
; return (ForAllTy v s, ForAllTy v t) }
@@ -716,13 +797,21 @@ lintCoercion (CoVarCo cv)
; cv' <- lookupIdInScope cv
; return (coVarKind cv') }
-lintCoercion (AxiomInstCo (CoAxiom { co_ax_tvs = tvs
+lintCoercion (AxiomInstCo (CoAxiom { co_ax_tvs = ktvs
, co_ax_lhs = lhs
- , co_ax_rhs = rhs })
+ , co_ax_rhs = rhs })
cos)
- = do { (tys1, tys2) <- liftM unzip (checkTyCoKinds tvs cos)
- ; return (substTyWith tvs tys1 lhs,
- substTyWith tvs tys2 rhs) }
+ = ASSERT2 (not (any isKiVar tvs), ppr ktvs)
+ do -- see Note [Kind instantiation in coercions]
+ { kis <- checkKiCoKinds kvs kcos
+ ; let tvs' = map (updateTyVarKind (Type.substTy subst)) tvs
+ subst = zipOpenTvSubst kvs kis
+ ; (tys1, tys2) <- liftM unzip (checkTyCoKinds tvs' tcos)
+ ; return (substTyWith ktvs (kis ++ tys1) lhs,
+ substTyWith ktvs (kis ++ tys2) rhs) }
+ where
+ (kvs, tvs) = splitKiTyVars ktvs
+ (kcos, tcos) = splitAt (length kvs) cos
lintCoercion (UnsafeCo ty1 ty2)
= do { _ <- lintType ty1
@@ -773,7 +862,12 @@ checkTcApp co n ty
lintType :: OutType -> LintM Kind
lintType (TyVarTy tv)
= do { checkTyCoVarInScope tv
- ; return (tyVarKind tv) }
+ ; let kind = tyVarKind tv
+ ; lintKind kind
+ ; if (isSuperKind kind) then failWithL msg
+ else return kind }
+ where msg = hang (ptext (sLit "Expecting a type, but got a kind"))
+ 2 (ptext (sLit "Offending kind:") <+> ppr tv)
lintType ty@(AppTy t1 t2)
= do { k1 <- lintType t1
@@ -783,10 +877,6 @@ lintType ty@(FunTy t1 t2)
= lint_ty_app ty (mkArrowKinds [argTypeKind, openTypeKind] liftedTypeKind) [t1,t2]
lintType ty@(TyConApp tc tys)
- | tc `hasKey` eqPrimTyConKey -- See Note [The ~# TyCon] in TysPrim
- = lint_prim_eq_pred ty tys
- | tc `hasKey` eqTyConKey
- = lint_eq_pred ty tys
| tyConHasKind tc
= lint_ty_app ty (tyConKind tc) tys
| otherwise
@@ -797,62 +887,44 @@ lintType (ForAllTy tv ty)
; addInScopeVar tv (lintType ty) }
----------------
-lint_ty_app :: OutType -> Kind -> [OutType] -> LintM Kind
-lint_ty_app ty k tys
- = do { ks <- mapM lintType tys
- ; lint_kind_app (ptext (sLit "type") <+> quotes (ppr ty)) k ks }
-
-lint_eq_pred :: OutType -> [OutType] -> LintM Kind
-lint_eq_pred ty arg_tys = case arg_tys of
- [ty1, ty2] -> do { k1 <- lintType ty1
- ; k2 <- lintType ty2
- ; unless (k1 `eqKind` k2)
- (addErrL (sep [ ptext (sLit "Kind mis-match in equality predicate:")
- , nest 2 (ppr ty)
- , nest 2 $ text "kind of left type is: " <+> ppr k1
- , nest 2 $ text "kind or right type is:" <+> ppr k2
- ]))
- ; return constraintKind }
- [ty1] -> do { k1 <- lintType ty1;
- return (k1 `mkFunTy` constraintKind) }
- [] -> do { return (typeKind ty) }
- _ -> failWithL (ptext (sLit "Oversaturated (~) type") <+> ppr ty)
-
-
-lint_prim_eq_pred :: OutType -> [OutType] -> LintM Kind
-lint_prim_eq_pred ty arg_tys
- | [ty1,ty2] <- arg_tys
- = do { k1 <- lintType ty1
- ; k2 <- lintType ty2
- ; checkL (k1 `eqKind` k2)
- (ptext (sLit "Mismatched arg kinds:") <+> ppr ty)
- ; return unliftedTypeKind }
- | otherwise
- = failWithL (ptext (sLit "Unsaturated ~# type") <+> ppr ty)
+lint_ty_app :: Type -> Kind -> [OutType] -> LintM Kind
+lint_ty_app ty k tys = lint_kind_app (ptext (sLit "type") <+> quotes (ppr ty)) k tys
----------------
-check_co_app :: OutCoercion -> Kind -> [OutType] -> LintM ()
-check_co_app ty k tys
- = do { _ <- lint_kind_app (ptext (sLit "coercion") <+> quotes (ppr ty))
- k (map typeKind tys)
- ; return () }
-
+check_co_app :: Coercion -> Kind -> [OutType] -> LintM ()
+check_co_app ty k tys = lint_kind_app (ptext (sLit "coercion") <+> quotes (ppr ty)) k tys >> return ()
+
----------------
-lint_kind_app :: SDoc -> Kind -> [Kind] -> LintM Kind
-lint_kind_app doc kfn ks = go kfn ks
+lint_kind_app :: SDoc -> Kind -> [OutType] -> LintM Kind
+-- Takes care of linting the OutTypes
+lint_kind_app doc kfn tys = go kfn tys
where
- fail_msg = vcat [hang (ptext (sLit "Kind application error in")) 2 doc,
- nest 2 (ptext (sLit "Function kind =") <+> ppr kfn),
- nest 2 (ptext (sLit "Arg kinds =") <+> ppr ks)]
-
- go kfn [] = return kfn
- go kfn (k:ks) = case splitKindFunTy_maybe kfn of
- Nothing -> failWithL fail_msg
- Just (kfa, kfb) -> do { unless (k `isSubKind` kfa)
- (addErrL fail_msg)
- ; go kfb ks }
+ fail_msg = vcat [ hang (ptext (sLit "Kind application error in")) 2 doc
+ , nest 2 (ptext (sLit "Function kind =") <+> ppr kfn)
+ , nest 2 (ptext (sLit "Arg types =") <+> ppr tys) ]
+
+ go kfn [] = return kfn
+ go kfn (ty:tys) =
+ case splitKindFunTy_maybe kfn of
+ { Nothing ->
+ case splitForAllTy_maybe kfn of
+ { Nothing -> failWithL fail_msg
+ ; Just (kv, body) -> do
+ -- Something of kind (forall kv. body) gets instantiated
+ -- with ty. 'kv' is a kind variable and 'ty' is a kind.
+ { unless (isSuperKind (tyVarKind kv)) (addErrL fail_msg)
+ ; lintKind ty
+ ; go (substKiWith [kv] [ty] body) tys } }
+ ; Just (kfa, kfb) -> do
+ -- Something of kind (kfa -> kfb) is applied to ty. 'ty' is
+ -- a type accepting kind 'kfa'.
+ { k <- lintType ty
+ ; lintKind kfa
+ ; unless (k `isSubKind` kfa) (addErrL fail_msg)
+ ; go kfb tys } }
+
\end{code}
-
+
%************************************************************************
%* *
\subsection[lint-monad]{The Lint monad}
@@ -1203,14 +1275,6 @@ mkStrictMsg binder
]
-mkEqBoxKindErrMsg :: Type -> Type -> Message
-mkEqBoxKindErrMsg ty1 ty2
- = vcat [ptext (sLit "Kinds don't match in type arguments of Eq#:"),
- hang (ptext (sLit "Arg type 1:"))
- 4 (ppr ty1 <+> dcolon <+> ppr (typeKind ty1)),
- hang (ptext (sLit "Arg type 2:"))
- 4 (ppr ty2 <+> dcolon <+> ppr (typeKind ty2))]
-
mkKindErrMsg :: TyVar -> Type -> Message
mkKindErrMsg tyvar arg_ty
= vcat [ptext (sLit "Kinds don't match in type application:"),
diff --git a/compiler/coreSyn/CoreUtils.lhs b/compiler/coreSyn/CoreUtils.lhs
index 400aad8142..b1d8a3febd 100644
--- a/compiler/coreSyn/CoreUtils.lhs
+++ b/compiler/coreSyn/CoreUtils.lhs
@@ -68,6 +68,7 @@ import Util
import Pair
import Data.Word
import Data.Bits
+import Data.List ( mapAccumL )
\end{code}
@@ -194,9 +195,15 @@ mkCast :: CoreExpr -> Coercion -> CoreExpr
mkCast e co | isReflCo co = e
mkCast (Coercion e_co) co
- = Coercion (mkSymCo g0 `mkTransCo` e_co `mkTransCo` g1)
+ = Coercion new_co
where
- [g0, g1] = decomposeCo 2 co
+ -- g :: (s1 ~# s2) ~# (t1 ~# t2)
+ -- g1 :: s1 ~# t1
+ -- g2 :: s2 ~# t2
+ new_co = mkSymCo g1 `mkTransCo` co `mkTransCo` g2
+ [_reflk, g1, g2] = decomposeCo 3 g
+ -- Remember, (~#) :: forall k. k -> k -> *
+ -- so it takes *three* arguments, not two
mkCast (Cast expr co2) co
= ASSERT(let { Pair from_ty _to_ty = coercionKind co;
@@ -230,7 +237,8 @@ mkTick t (Var x)
mkTick t (Cast e co)
= Cast (mkTick t e) co -- Move tick inside cast
-mkTick _ (Lit l) = Lit l
+mkTick t (Lit l)
+ | not (tickishCounts t) = Lit l
mkTick t expr@(App f arg)
| not (isRuntimeArg arg) = App (mkTick t f) arg
@@ -1071,9 +1079,10 @@ dataConInstPat :: [FastString] -- A long enough list of FSs to use for
--
-- where the double-primed variables are created with the FastStrings and
-- Uniques given as fss and us
-dataConInstPat fss uniqs con inst_tys
- = (ex_bndrs, arg_ids)
- where
+dataConInstPat fss uniqs con inst_tys
+ = ASSERT( univ_tvs `equalLength` inst_tys )
+ (ex_bndrs, arg_ids)
+ where
univ_tvs = dataConUnivTyVars con
ex_tvs = dataConExTyVars con
arg_tys = dataConRepArgTys con
@@ -1084,19 +1093,25 @@ dataConInstPat fss uniqs con inst_tys
(ex_uniqs, id_uniqs) = splitAt n_ex uniqs
(ex_fss, id_fss) = splitAt n_ex fss
- -- Make existential type variables
- ex_bndrs = zipWith3 mk_ex_var ex_uniqs ex_fss ex_tvs
- mk_ex_var uniq fs var = mkTyVar new_name kind
+ -- Make the instantiating substitution for universals
+ univ_subst = zipOpenTvSubst univ_tvs inst_tys
+
+ -- Make existential type variables, applyingn and extending the substitution
+ (full_subst, ex_bndrs) = mapAccumL mk_ex_var univ_subst
+ (zip3 ex_tvs ex_fss ex_uniqs)
+
+ mk_ex_var :: TvSubst -> (TyVar, FastString, Unique) -> (TvSubst, TyVar)
+ mk_ex_var subst (tv, fs, uniq) = (Type.extendTvSubst subst tv (mkTyVarTy new_tv)
+ , new_tv)
where
+ new_tv = mkTyVar new_name kind
new_name = mkSysTvName uniq fs
- kind = tyVarKind var
-
- -- Make the instantiating substitution
- subst = zipOpenTvSubst (univ_tvs ++ ex_tvs) (inst_tys ++ map mkTyVarTy ex_bndrs)
+ kind = Type.substTy subst (tyVarKind tv)
-- Make value vars, instantiating types
- mk_id_var uniq fs ty = mkUserLocal (mkVarOccFS fs) uniq (Type.substTy subst ty) noSrcSpan
arg_ids = zipWith3 mk_id_var id_uniqs id_fss arg_tys
+ mk_id_var uniq fs ty = mkUserLocal (mkVarOccFS fs) uniq
+ (Type.substTy full_subst ty) noSrcSpan
\end{code}
%************************************************************************
diff --git a/compiler/coreSyn/MkCore.lhs b/compiler/coreSyn/MkCore.lhs
index d941b0a4b1..dd41184994 100644
--- a/compiler/coreSyn/MkCore.lhs
+++ b/compiler/coreSyn/MkCore.lhs
@@ -288,8 +288,10 @@ mkIPUnbox ipx = Var x `Cast` mkAxInstCo (ipCoAxiom ip) [ty]
\begin{code}
mkEqBox :: Coercion -> CoreExpr
-mkEqBox co = Var (dataConWorkId eqBoxDataCon) `mkTyApps` [ty1, ty2] `App` Coercion co
+mkEqBox co = ASSERT( typeKind ty2 `eqKind` k )
+ Var (dataConWorkId eqBoxDataCon) `mkTyApps` [k, ty1, ty2] `App` Coercion co
where Pair ty1 ty2 = coercionKind co
+ k = typeKind ty1
\end{code}
diff --git a/compiler/coreSyn/MkExternalCore.lhs b/compiler/coreSyn/MkExternalCore.lhs
index e38885ba54..cb12973a60 100644
--- a/compiler/coreSyn/MkExternalCore.lhs
+++ b/compiler/coreSyn/MkExternalCore.lhs
@@ -23,6 +23,7 @@ import TyCon
-- import Class
import TypeRep
import Type
+import Kind
import PprExternalCore () -- Instances
import DataCon
import Coercion
diff --git a/compiler/coreSyn/PprCore.lhs b/compiler/coreSyn/PprCore.lhs
index 2ba8a23120..c575b68857 100644
--- a/compiler/coreSyn/PprCore.lhs
+++ b/compiler/coreSyn/PprCore.lhs
@@ -28,6 +28,7 @@ import Demand
import DataCon
import TyCon
import Type
+import Kind
import Coercion
import StaticFlags
import BasicTypes
diff --git a/compiler/deSugar/Coverage.lhs b/compiler/deSugar/Coverage.lhs
index 5e5534748d..fd2895d072 100644
--- a/compiler/deSugar/Coverage.lhs
+++ b/compiler/deSugar/Coverage.lhs
@@ -550,9 +550,6 @@ addTickGRHSBody isOneOfMany isLambda expr@(L pos e0) = do
addPathEntry "\\" $
allocTickBox (ExpBox False) True{-count-} False{-not top-} pos $
addTickHsExpr e0
- TickTopFunctions ->
- allocTickBox (ExpBox False) False{-no count-} True{-top-} pos $
- addTickHsExpr e0
_otherwise ->
addTickLHsExprAlways expr
diff --git a/compiler/deSugar/Desugar.lhs b/compiler/deSugar/Desugar.lhs
index fcea3b14bc..e88b57e835 100644
--- a/compiler/deSugar/Desugar.lhs
+++ b/compiler/deSugar/Desugar.lhs
@@ -86,7 +86,6 @@ deSugar hsc_env
tcg_rules = rules,
tcg_vects = vects,
tcg_tcs = tcs,
- tcg_clss = clss,
tcg_insts = insts,
tcg_fam_insts = fam_insts,
tcg_hpc = other_hpc_info })
@@ -189,7 +188,6 @@ deSugar hsc_env
mg_warns = warns,
mg_anns = anns,
mg_tcs = tcs,
- mg_clss = clss,
mg_insts = insts,
mg_fam_insts = fam_insts,
mg_inst_env = inst_env,
diff --git a/compiler/deSugar/DsExpr.lhs b/compiler/deSugar/DsExpr.lhs
index 9e6c1ee814..8b41d3a2af 100644
--- a/compiler/deSugar/DsExpr.lhs
+++ b/compiler/deSugar/DsExpr.lhs
@@ -365,11 +365,11 @@ dsExpr (ExplicitList elt_ty xs)
-- singletonP x1 +:+ ... +:+ singletonP xn
--
dsExpr (ExplicitPArr ty []) = do
- emptyP <- dsLookupDPHId emptyPName
+ emptyP <- dsDPHBuiltin emptyPVar
return (Var emptyP `App` Type ty)
dsExpr (ExplicitPArr ty xs) = do
- singletonP <- dsLookupDPHId singletonPName
- appP <- dsLookupDPHId appPName
+ singletonP <- dsDPHBuiltin singletonPVar
+ appP <- dsDPHBuiltin appPVar
xs' <- mapM dsLExpr xs
return . foldr1 (binary appP) $ map (unary singletonP) xs'
where
diff --git a/compiler/deSugar/DsListComp.lhs b/compiler/deSugar/DsListComp.lhs
index 335fb1fdda..63d96fd465 100644
--- a/compiler/deSugar/DsListComp.lhs
+++ b/compiler/deSugar/DsListComp.lhs
@@ -484,7 +484,7 @@ dsPArrComp (ParStmt qss _ _ _ : quals) = dePArrParComp qss quals
-- <<[:e' | qs:]>> p (filterP (\x -> case x of {p -> True; _ -> False}) e)
--
dsPArrComp (BindStmt p e _ _ : qs) = do
- filterP <- dsLookupDPHId filterPName
+ filterP <- dsDPHBuiltin filterPVar
ce <- dsLExpr e
let ety'ce = parrElemType ce
false = Var falseDataConId
@@ -496,7 +496,7 @@ dsPArrComp (BindStmt p e _ _ : qs) = do
dePArrComp qs p gen
dsPArrComp qs = do -- no ParStmt in `qs'
- sglP <- dsLookupDPHId singletonPName
+ sglP <- dsDPHBuiltin singletonPVar
let unitArray = mkApps (Var sglP) [Type unitTy, mkCoreTup []]
dePArrComp qs (noLoc $ WildPat unitTy) unitArray
@@ -516,7 +516,7 @@ dePArrComp [] _ _ = panic "dePArrComp"
--
dePArrComp (LastStmt e' _ : quals) pa cea
= ASSERT( null quals )
- do { mapP <- dsLookupDPHId mapPName
+ do { mapP <- dsDPHBuiltin mapPVar
; let ty = parrElemType cea
; (clam, ty'e') <- deLambda ty pa e'
; return $ mkApps (Var mapP) [Type ty, Type ty'e', clam, cea] }
@@ -524,7 +524,7 @@ dePArrComp (LastStmt e' _ : quals) pa cea
-- <<[:e' | b, qs:]>> pa ea = <<[:e' | qs:]>> pa (filterP (\pa -> b) ea)
--
dePArrComp (ExprStmt b _ _ _ : qs) pa cea = do
- filterP <- dsLookupDPHId filterPName
+ filterP <- dsDPHBuiltin filterPVar
let ty = parrElemType cea
(clam,_) <- deLambda ty pa b
dePArrComp qs pa (mkApps (Var filterP) [Type ty, clam, cea])
@@ -543,8 +543,8 @@ dePArrComp (ExprStmt b _ _ _ : qs) pa cea = do
-- <<[:e' | qs:]>> (pa, p) (crossMapP ea ef)
--
dePArrComp (BindStmt p e _ _ : qs) pa cea = do
- filterP <- dsLookupDPHId filterPName
- crossMapP <- dsLookupDPHId crossMapPName
+ filterP <- dsDPHBuiltin filterPVar
+ crossMapP <- dsDPHBuiltin crossMapPVar
ce <- dsLExpr e
let ety'cea = parrElemType cea
ety'ce = parrElemType ce
@@ -568,7 +568,7 @@ dePArrComp (BindStmt p e _ _ : qs) pa cea = do
-- {x_1, ..., x_n} = DV (ds) -- Defined Variables
--
dePArrComp (LetStmt ds : qs) pa cea = do
- mapP <- dsLookupDPHId mapPName
+ mapP <- dsDPHBuiltin mapPVar
let xs = collectLocalBinders ds
ty'cea = parrElemType cea
v <- newSysLocalDs ty'cea
@@ -615,7 +615,7 @@ dePArrParComp qss quals = do
---
parStmts [] pa cea = return (pa, cea)
parStmts ((qs, xs):qss) pa cea = do -- subsequent statements (zip'ed)
- zipP <- dsLookupDPHId zipPName
+ zipP <- dsDPHBuiltin zipPVar
let pa' = mkLHsPatTup [pa, mkLHsVarPatTup xs]
ty'cea = parrElemType cea
res_expr = mkLHsVarTuple xs
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index 628f911308..4b710f67cc 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -53,6 +53,7 @@ import NameEnv
import TcType
import TyCon
import TysWiredIn
+import TysPrim ( liftedTypeKindTyConName )
import CoreSyn
import MkCore
import CoreUtils
@@ -81,7 +82,7 @@ dsBracket brack splices
where
new_bit = mkNameEnv [(n, Splice (unLoc e)) | (n,e) <- splices]
- do_brack (VarBr n) = do { MkC e1 <- lookupOcc n ; return e1 }
+ do_brack (VarBr _ n) = do { MkC e1 <- lookupOcc n ; return e1 }
do_brack (ExpBr e) = do { MkC e1 <- repLE e ; return e1 }
do_brack (PatBr p) = do { MkC p1 <- repTopP p ; return p1 }
do_brack (TypBr t) = do { MkC t1 <- repLTy t ; return t1 }
@@ -598,7 +599,7 @@ repTyVarBndrWithKind :: LHsTyVarBndr Name
-> Core TH.Name -> DsM (Core TH.TyVarBndr)
repTyVarBndrWithKind (L _ (UserTyVar {})) nm
= repPlainTV nm
-repTyVarBndrWithKind (L _ (KindedTyVar _ ki)) nm
+repTyVarBndrWithKind (L _ (KindedTyVar _ ki _)) nm
= repKind ki >>= repKindedTV nm
-- represent a type context
@@ -684,7 +685,7 @@ repTy (HsTupleTy HsUnboxedTuple tys) = do
tys1 <- repLTys tys
tcon <- repUnboxedTupleTyCon (length tys)
repTapps tcon tys1
-repTy (HsOpTy ty1 n ty2) = repLTy ((nlHsTyVar (unLoc n) `nlHsAppTy` ty1)
+repTy (HsOpTy ty1 (_, n) ty2) = repLTy ((nlHsTyVar (unLoc n) `nlHsAppTy` ty1)
`nlHsAppTy` ty2)
repTy (HsParTy t) = repLTy t
repTy (HsKindSig t k) = do
@@ -696,17 +697,16 @@ repTy ty = notHandled "Exotic form of type" (ppr ty)
-- represent a kind
--
-repKind :: Kind -> DsM (Core TH.Kind)
+repKind :: LHsKind Name -> DsM (Core TH.Kind)
repKind ki
- = do { let (kis, ki') = splitKindFunTys ki
+ = do { let (kis, ki') = splitHsFunType ki
; kis_rep <- mapM repKind kis
; ki'_rep <- repNonArrowKind ki'
; foldrM repArrowK ki'_rep kis_rep
}
where
- repNonArrowKind k | isLiftedTypeKind k = repStarK
- | otherwise = notHandled "Exotic form of kind"
- (ppr k)
+ repNonArrowKind (L _ (HsTyVar name)) | name == liftedTypeKindTyConName = repStarK
+ repNonArrowKind k = notHandled "Exotic form of kind" (ppr k)
-----------------------------------------------------------------------------
-- Splices
diff --git a/compiler/deSugar/DsMonad.lhs b/compiler/deSugar/DsMonad.lhs
index 9403317ceb..8ea94efef3 100644
--- a/compiler/deSugar/DsMonad.lhs
+++ b/compiler/deSugar/DsMonad.lhs
@@ -21,9 +21,9 @@ module DsMonad (
newUnique,
UniqSupply, newUniqueSupply,
getDOptsDs, getGhcModeDs, doptDs, woptDs,
- dsLookupGlobal, dsLookupGlobalId, dsLookupDPHId, dsLookupTyCon, dsLookupDataCon,
+ dsLookupGlobal, dsLookupGlobalId, dsDPHBuiltin, dsLookupTyCon, dsLookupDataCon,
- assertDAPPLoaded, lookupDAPPRdrEnv,
+ PArrBuiltin(..), dsLookupDPHRdrEnv, dsInitPArrBuiltin,
DsMetaEnv, DsMetaVal(..), dsLookupMetaEnv, dsExtendMetaEnv,
@@ -41,6 +41,7 @@ import CoreSyn
import HsSyn
import TcIface
import LoadIface
+import Finder
import PrelNames
import Avail
import RdrName
@@ -60,7 +61,6 @@ import DynFlags
import ErrUtils
import FastString
import Maybes
-import Control.Monad
import Data.IORef
\end{code}
@@ -131,16 +131,38 @@ type DsWarning = (SrcSpan, SDoc)
-- and we'll do the print_unqual stuff later on to turn it
-- into a Doc.
-data DsGblEnv = DsGblEnv {
- ds_mod :: Module, -- For SCC profiling
- ds_unqual :: PrintUnqualified,
- ds_msgs :: IORef Messages, -- Warning messages
- ds_if_env :: (IfGblEnv, IfLclEnv), -- Used for looking up global,
+-- If '-XParallelArrays' is given, the desugarer populates this table with the corresponding
+-- variables found in 'Data.Array.Parallel'.
+--
+data PArrBuiltin
+ = PArrBuiltin
+ { lengthPVar :: Var -- ^ lengthP
+ , replicatePVar :: Var -- ^ replicateP
+ , singletonPVar :: Var -- ^ singletonP
+ , mapPVar :: Var -- ^ mapP
+ , filterPVar :: Var -- ^ filterP
+ , zipPVar :: Var -- ^ zipP
+ , crossMapPVar :: Var -- ^ crossMapP
+ , indexPVar :: Var -- ^ (!:)
+ , emptyPVar :: Var -- ^ emptyP
+ , appPVar :: Var -- ^ (+:+)
+ , enumFromToPVar :: Var -- ^ enumFromToP
+ , enumFromThenToPVar :: Var -- ^ enumFromThenToP
+ }
+
+data DsGblEnv
+ = DsGblEnv
+ { ds_mod :: Module -- For SCC profiling
+ , ds_unqual :: PrintUnqualified
+ , ds_msgs :: IORef Messages -- Warning messages
+ , ds_if_env :: (IfGblEnv, IfLclEnv) -- Used for looking up global,
-- possibly-imported things
- ds_dph_env :: GlobalRdrEnv -- exported entities of 'Data.Array.Parallel.Prim' iff
- -- '-fdph-*' flag was given (i.e., 'DynFlags.DPHBackend /=
- -- DPHNone'); otherwise, empty
- }
+ , ds_dph_env :: GlobalRdrEnv -- exported entities of 'Data.Array.Parallel.Prim'
+ -- iff '-fvectorise' flag was given as well as
+ -- exported entities of 'Data.Array.Parallel' iff
+ -- '-XParallelArrays' was given; otherwise, empty
+ , ds_parr_bi :: PArrBuiltin -- desugarar names for '-XParallelArrays'
+ }
data DsLclEnv = DsLclEnv {
ds_meta :: DsMetaEnv, -- Template Haskell bindings
@@ -171,8 +193,9 @@ initDs hsc_env mod rdr_env type_env thing_inside
(ds_gbl_env, ds_lcl_env) = mkDsEnvs dflags mod rdr_env type_env msg_var
; either_res <- initTcRnIf 'd' hsc_env ds_gbl_env ds_lcl_env $
- loadDAPP dflags $
- tryM thing_inside -- Catch exceptions (= errors during desugaring)
+ loadDAP $
+ initDPHBuiltins $
+ tryM thing_inside -- Catch exceptions (= errors during desugaring)
-- Display any errors and warnings
-- Note: if -Werror is used, we don't signal an error here.
@@ -190,22 +213,51 @@ initDs hsc_env mod rdr_env type_env thing_inside
}
where
-- Extend the global environment with a 'GlobalRdrEnv' containing the exported entities of
- -- 'Data.Array.Parallel.Prim' if '-fdph-*' specified.
- loadDAPP dflags thing_inside
- | Just pkg <- dphPackageMaybe dflags
- = do { rdr_env <- loadModule sdoc (dATA_ARRAY_PARALLEL_PRIM pkg)
- ; updGblEnv (\env -> env {ds_dph_env = rdr_env}) thing_inside
+ -- * 'Data.Array.Parallel' iff '-XParallalArrays' specified (see also 'checkLoadDAP').
+ -- * 'Data.Array.Parallel.Prim' iff '-fvectorise' specified.
+ loadDAP thing_inside
+ = do { dapEnv <- loadOneModule dATA_ARRAY_PARALLEL_NAME checkLoadDAP paErr
+ ; dappEnv <- loadOneModule dATA_ARRAY_PARALLEL_PRIM_NAME (doptM Opt_Vectorise) veErr
+ ; updGblEnv (\env -> env {ds_dph_env = dapEnv `plusOccEnv` dappEnv }) thing_inside
}
- | otherwise
- = do { ifXOptM Opt_ParallelArrays (liftIO $ fatalErrorMsg dflags $ ptext selectBackendErrPA)
- ; ifDOptM Opt_Vectorise (liftIO $ fatalErrorMsg dflags $ ptext selectBackendErrVect)
- ; thing_inside
+ where
+ loadOneModule :: ModuleName -- the module to load
+ -> DsM Bool -- under which condition
+ -> Message -- error message if module not found
+ -> DsM GlobalRdrEnv -- empty if condition 'False'
+ loadOneModule modname check err
+ = do { doLoad <- check
+ ; if not doLoad
+ then return emptyGlobalRdrEnv
+ else do {
+ ; result <- liftIO $ findImportedModule hsc_env modname Nothing
+ ; case result of
+ Found _ mod -> loadModule err mod
+ _ -> pprPgmError "Unable to use Data Parallel Haskell (DPH):" err
+ } }
+
+ paErr = ptext (sLit "To use -XParallelArrays,") <+> specBackend $$ hint1 $$ hint2
+ veErr = ptext (sLit "To use -fvectorise,") <+> specBackend $$ hint1 $$ hint2
+ specBackend = ptext (sLit "you must specify a DPH backend package")
+ hint1 = ptext (sLit "Look for packages named 'dph-lifted-*' with 'ghc-pkg'")
+ hint2 = ptext (sLit "You may need to install them with 'cabal install dph-examples'")
+
+ initDPHBuiltins thing_inside
+ = do { -- If '-XParallelArrays' given, we populate the builtin table for desugaring those
+ ; doInitBuiltins <- checkLoadDAP
+ ; if doInitBuiltins
+ then dsInitPArrBuiltin thing_inside
+ else thing_inside
}
- sdoc = ptext (sLit "Internal Data Parallel Haskell interface 'Data.Array.Parallel.Prim'")
-
- selectBackendErrVect = sLit "To use -fvectorise select a DPH backend with -fdph-par or -fdph-seq"
- selectBackendErrPA = sLit "To use -XParallelArrays select a DPH backend with -fdph-par or -fdph-seq"
+ checkLoadDAP = do { paEnabled <- xoptM Opt_ParallelArrays
+ ; return $ paEnabled &&
+ mod /= gHC_PARR' &&
+ moduleName mod /= dATA_ARRAY_PARALLEL_NAME
+ }
+ -- do not load 'Data.Array.Parallel' iff compiling 'base:GHC.PArr' or a
+ -- module called 'dATA_ARRAY_PARALLEL_NAME'; see also the comments at the top
+ -- of 'base:GHC.PArr' and 'Data.Array.Parallel' in the DPH libraries
initDsTc :: DsM a -> TcM a
initDsTc thing_inside
@@ -228,23 +280,23 @@ mkDsEnvs dflags mod rdr_env type_env msg_var
, ds_unqual = mkPrintUnqualified dflags rdr_env
, ds_msgs = msg_var
, ds_dph_env = emptyGlobalRdrEnv
+ , ds_parr_bi = panic "DsMonad: uninitialised ds_parr_bi"
}
lcl_env = DsLclEnv { ds_meta = emptyNameEnv
, ds_loc = noSrcSpan
}
in (gbl_env, lcl_env)
--- Attempt to load the given module and return its exported entities if successful; otherwise, return an
--- empty environment. See "Note [Loading Data.Array.Parallel.Prim]".
+-- Attempt to load the given module and return its exported entities if successful.
--
loadModule :: SDoc -> Module -> DsM GlobalRdrEnv
loadModule doc mod
- = do { env <- getGblEnv
+ = do { env <- getGblEnv
; setEnvs (ds_if_env env) $ do
{ iface <- loadInterface doc mod ImportBySystem
- ; case iface of
- Failed _err -> return $ mkGlobalRdrEnv []
- Succeeded iface -> return $ mkGlobalRdrEnv . gresFromAvails prov . mi_exports $ iface
+ ; case iface of
+ Failed err -> pprPanic "DsMonad.loadModule: failed to load" (err $$ doc)
+ Succeeded iface -> return $ mkGlobalRdrEnv . gresFromAvails prov . mi_exports $ iface
} }
where
prov = Imported [ImpSpec { is_decl = imp_spec, is_item = ImpAll }]
@@ -253,15 +305,6 @@ loadModule doc mod
name = moduleName mod
\end{code}
-Note [Loading Data.Array.Parallel.Prim]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We generally attempt to load the interface of 'Data.Array.Parallel.Prim' when a DPH backend is selected.
-However, while compiling packages containing a DPH backend, we will start out compiling the modules
-'Data.Array.Parallel.Prim' depends on — i.e., when compiling these modules, the interface won't exist yet.
-This is fine, as these modules do not use the vectoriser, but we need to ensure that GHC doesn't barf when
-the interface is missing. Instead of an error message, we just put an empty 'GlobalRdrEnv' into the
-'DsM' state.
-
%************************************************************************
%* *
@@ -355,18 +398,11 @@ dsLookupGlobalId :: Name -> DsM Id
dsLookupGlobalId name
= tyThingId <$> dsLookupGlobal name
--- Looking up a global DPH 'Id' is like 'dsLookupGlobalId', but the package, in which the looked
--- up name is located, varies with the active DPH backend.
+-- |Get a name from "Data.Array.Parallel" for the desugarer, from the 'ds_parr_bi' component of the
+-- global desugerar environment.
--
-dsLookupDPHId :: (PackageId -> Name) -> DsM Id
-dsLookupDPHId nameInPkg
- = do { dflags <- getDOpts
- ; case dphPackageMaybe dflags of
- Just pkg -> tyThingId <$> dsLookupGlobal (nameInPkg pkg)
- Nothing -> failWithDs $ ptext err
- }
- where
- err = sLit "To use -XParallelArrays select a DPH backend with -fdph-par or -fdph-seq"
+dsDPHBuiltin :: (PArrBuiltin -> a) -> DsM a
+dsDPHBuiltin sel = (sel . ds_parr_bi) <$> getGblEnv
dsLookupTyCon :: Name -> DsM TyCon
dsLookupTyCon name
@@ -378,28 +414,61 @@ dsLookupDataCon name
\end{code}
\begin{code}
--- Complain if 'Data.Array.Parallel.Prim' wasn't loaded (and we are about to use it).
---
--- See "Note [Loading Data.Array.Parallel.Prim]".
+-- Look up a name exported by 'Data.Array.Parallel.Prim' or 'Data.Array.Parallel.Prim'.
--
-assertDAPPLoaded :: DsM ()
-assertDAPPLoaded
- = do { env <- ds_dph_env <$> getGblEnv
- ; when (null $ occEnvElts env) $
- panic "'Data.Array.Parallel.Prim' not available; maybe missing dependency in DPH package"
- }
-
--- Look up a name exported by 'Data.Array.Parallel.Prim'.
---
-lookupDAPPRdrEnv :: OccName -> DsM Name
-lookupDAPPRdrEnv occ
+dsLookupDPHRdrEnv :: OccName -> DsM Name
+dsLookupDPHRdrEnv occ
= do { env <- ds_dph_env <$> getGblEnv
; let gres = lookupGlobalRdrEnv env occ
; case gres of
- [] -> pprPanic "Name not found in 'Data.Array.Parallel.Prim':" (ppr occ)
+ [] -> pprPanic nameNotFound (ppr occ)
[gre] -> return $ gre_name gre
- _ -> pprPanic "Multiple definitions in 'Data.Array.Parallel.Prim':" (ppr occ)
+ _ -> pprPanic multipleNames (ppr occ)
}
+ where
+ nameNotFound = "Name not found in 'Data.Array.Parallel' or 'Data.Array.Parallel.Prim':"
+ multipleNames = "Multiple definitions in 'Data.Array.Parallel' and 'Data.Array.Parallel.Prim':"
+
+-- Populate 'ds_parr_bi' from 'ds_dph_env'.
+--
+dsInitPArrBuiltin :: DsM a -> DsM a
+dsInitPArrBuiltin thing_inside
+ = do { lengthPVar <- externalVar (fsLit "lengthP")
+ ; replicatePVar <- externalVar (fsLit "replicateP")
+ ; singletonPVar <- externalVar (fsLit "singletonP")
+ ; mapPVar <- externalVar (fsLit "mapP")
+ ; filterPVar <- externalVar (fsLit "filterP")
+ ; zipPVar <- externalVar (fsLit "zipP")
+ ; crossMapPVar <- externalVar (fsLit "crossMapP")
+ ; indexPVar <- externalVar (fsLit "!:")
+ ; emptyPVar <- externalVar (fsLit "emptyP")
+ ; appPVar <- externalVar (fsLit "+:+")
+ -- ; enumFromToPVar <- externalVar (fsLit "enumFromToP")
+ -- ; enumFromThenToPVar <- externalVar (fsLit "enumFromThenToP")
+ ; enumFromToPVar <- return arithErr
+ ; enumFromThenToPVar <- return arithErr
+
+ ; updGblEnv (\env -> env {ds_parr_bi = PArrBuiltin
+ { lengthPVar = lengthPVar
+ , replicatePVar = replicatePVar
+ , singletonPVar = singletonPVar
+ , mapPVar = mapPVar
+ , filterPVar = filterPVar
+ , zipPVar = zipPVar
+ , crossMapPVar = crossMapPVar
+ , indexPVar = indexPVar
+ , emptyPVar = emptyPVar
+ , appPVar = appPVar
+ , enumFromToPVar = enumFromToPVar
+ , enumFromThenToPVar = enumFromThenToPVar
+ } })
+ thing_inside
+ }
+ where
+ externalVar :: FastString -> DsM Var
+ externalVar fs = dsLookupDPHRdrEnv (mkVarOccFS fs) >>= dsLookupGlobalId
+
+ arithErr = panic "Arithmetic sequences have to wait until we support type classes"
\end{code}
\begin{code}
diff --git a/compiler/deSugar/DsUtils.lhs b/compiler/deSugar/DsUtils.lhs
index df049aae9c..6a46bbe93d 100644
--- a/compiler/deSugar/DsUtils.lhs
+++ b/compiler/deSugar/DsUtils.lhs
@@ -389,7 +389,7 @@ mkCoAlgCaseMatchResult var ty match_alts
isPArrFakeAlts [] = panic "DsUtils: unexpectedly found an empty list of PArr fake alternatives"
--
mk_parrCase fail = do
- lengthP <- dsLookupDPHId lengthPName
+ lengthP <- dsDPHBuiltin lengthPVar
alt <- unboxAlt
return (mkWildCase (len lengthP) intTy ty [alt])
where
@@ -401,7 +401,7 @@ mkCoAlgCaseMatchResult var ty match_alts
--
unboxAlt = do
l <- newSysLocalDs intPrimTy
- indexP <- dsLookupDPHId indexPName
+ indexP <- dsDPHBuiltin indexPVar
alts <- mapM (mkAlt indexP) sorted_alts
return (DataAlt intDataCon, [l], mkWildCase (Var l) intPrimTy ty (dft : alts))
where
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index 040ca6b09f..aea6d8d173 100755
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -301,6 +301,7 @@ Library
LoadIface
MkIface
TcIface
+ FlagChecker
Annotations
BreakArray
CmdLineParser
diff --git a/compiler/ghci/RtClosureInspect.hs b/compiler/ghci/RtClosureInspect.hs
index 84d0acf316..f521ee6b06 100644
--- a/compiler/ghci/RtClosureInspect.hs
+++ b/compiler/ghci/RtClosureInspect.hs
@@ -45,6 +45,7 @@ import Var
import TcRnMonad
import TcType
import TcMType
+import TcHsSyn ( mkZonkTcTyVar )
import TcUnify
import TcEnv
@@ -1130,7 +1131,7 @@ zonkTerm = foldTermM (TermFoldM
zonkRttiType :: TcType -> TcM Type
-- Zonk the type, replacing any unbound Meta tyvars
-- by skolems, safely out of Meta-tyvar-land
-zonkRttiType = zonkType (mkZonkTcTyVar zonk_unbound_meta)
+zonkRttiType = zonkType (mkZonkTcTyVar zonk_unbound_meta mkTyVarTy)
where
zonk_unbound_meta tv
= ASSERT( isTcTyVar tv )
diff --git a/compiler/hsSyn/Convert.lhs b/compiler/hsSyn/Convert.lhs
index fc33dc125f..6f88319b06 100644
--- a/compiler/hsSyn/Convert.lhs
+++ b/compiler/hsSyn/Convert.lhs
@@ -27,7 +27,6 @@ import qualified OccName
import OccName
import SrcLoc
import Type
-import Coercion
import TysWiredIn
import BasicTypes as Hs
import ForeignCall
@@ -204,7 +203,7 @@ cvtDec (ForeignD ford)
cvtDec (FamilyD flav tc tvs kind)
= do { (_, tc', tvs') <- cvt_tycl_hdr [] tc tvs
- ; let kind' = fmap cvtKind kind
+ ; kind' <- cvtMaybeKind kind
; returnL $ TyClD (TyFamily (cvtFamFlavour flav) tc' tvs' kind') }
where
cvtFamFlavour TypeFam = TypeFamily
@@ -785,7 +784,8 @@ cvt_tv (TH.PlainTV nm)
}
cvt_tv (TH.KindedTV nm ki)
= do { nm' <- tName nm
- ; returnL $ KindedTyVar nm' (cvtKind ki)
+ ; ki' <- cvtKind ki
+ ; returnL $ KindedTyVar nm' ki' placeHolderKind
}
cvtContext :: TH.Cxt -> CvtM (LHsContext RdrName)
@@ -842,7 +842,8 @@ cvtType ty
SigT ty ki
-> do { ty' <- cvtType ty
- ; mk_apps (HsKindSig ty' (cvtKind ki)) tys'
+ ; ki' <- cvtKind ki
+ ; mk_apps (HsKindSig ty' ki') tys'
}
_ -> failWith (ptext (sLit "Malformed type") <+> text (show ty))
@@ -859,9 +860,16 @@ split_ty_app ty = go ty []
go (AppT f a) as' = do { a' <- cvtType a; go f (a':as') }
go f as = return (f,as)
-cvtKind :: TH.Kind -> Type.Kind
-cvtKind StarK = liftedTypeKind
-cvtKind (ArrowK k1 k2) = mkArrowKind (cvtKind k1) (cvtKind k2)
+cvtKind :: TH.Kind -> CvtM (LHsKind RdrName)
+cvtKind StarK = returnL (HsTyVar (getRdrName liftedTypeKindTyCon))
+cvtKind (ArrowK k1 k2) = do
+ k1' <- cvtKind k1
+ k2' <- cvtKind k2
+ returnL (HsFunTy k1' k2')
+
+cvtMaybeKind :: Maybe TH.Kind -> CvtM (Maybe (LHsKind RdrName))
+cvtMaybeKind Nothing = return Nothing
+cvtMaybeKind (Just ki) = cvtKind ki >>= return . Just
-----------------------------------------------------------
diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs
index ff33213b76..b6bc0c702b 100644
--- a/compiler/hsSyn/HsBinds.lhs
+++ b/compiler/hsSyn/HsBinds.lhs
@@ -23,6 +23,7 @@ import {-# SOURCE #-} HsExpr ( pprExpr, LHsExpr,
GRHSs, pprPatBind )
import {-# SOURCE #-} HsPat ( LPat )
+import HsLit
import HsTypes
import PprCore ()
import CoreSyn
@@ -461,9 +462,9 @@ data HsWrapper
| WpEvLam EvVar -- \d. [] the 'd' is an evidence variable
| WpEvApp EvTerm -- [] d the 'd' is evidence for a constraint
- -- Type abstraction and application
- | WpTyLam TyVar -- \a. [] the 'a' is a type variable (not coercion var)
- | WpTyApp Type -- [] t the 't' is a type (not coercion)
+ -- Kind and Type abstraction and application
+ | WpTyLam TyVar -- \a. [] the 'a' is a type/kind variable (not coercion var)
+ | WpTyApp KindOrType -- [] t the 't' is a type (not coercion)
| WpLet TcEvBinds -- Non-empty (or possibly non-empty) evidence bindings,
diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs
index 480401b84a..ea34e7991c 100644
--- a/compiler/hsSyn/HsDecls.lhs
+++ b/compiler/hsSyn/HsDecls.lhs
@@ -14,7 +14,7 @@ module HsDecls (
-- * Toplevel declarations
HsDecl(..), LHsDecl,
-- ** Class or type declarations
- TyClDecl(..), LTyClDecl,
+ TyClDecl(..), LTyClDecl, TyClGroup,
isClassDecl, isSynDecl, isDataDecl, isTypeDecl, isFamilyDecl,
isFamInstDecl, tcdName, tyClDeclTyVars,
countTyClDecls,
@@ -63,7 +63,6 @@ import HsDoc
import TyCon
import NameSet
import Name
-import {- Kind parts of -} Type
import BasicTypes
import Coercion
import ForeignCall
@@ -431,6 +430,8 @@ Interface file code:
-- In both cases, 'tcdVars' collects all variables we need to quantify over.
type LTyClDecl name = Located (TyClDecl name)
+type TyClGroup name = [LTyClDecl name] -- this is used in TcTyClsDecls to represent
+ -- strongly connected components of decls
-- | A type or class declaration.
data TyClDecl name
@@ -444,7 +445,7 @@ data TyClDecl name
TyFamily { tcdFlavour:: FamilyFlavour, -- type or data
tcdLName :: Located name, -- type constructor
tcdTyVars :: [LHsTyVarBndr name], -- type variables
- tcdKind :: Maybe Kind -- result kind
+ tcdKind :: Maybe (LHsKind name) -- result kind
}
@@ -461,7 +462,7 @@ data TyClDecl name
tcdTyPats :: Maybe [LHsType name], -- ^ Type patterns.
-- See Note [tcdTyVars and tcdTyPats]
- tcdKindSig:: Maybe Kind,
+ tcdKindSig:: Maybe (LHsKind name),
-- ^ Optional kind signature.
--
-- @(Just k)@ for a GADT-style @data@, or @data
@@ -535,14 +536,18 @@ tcdTyPats = Just tys
This is a data/type family instance declaration
tcdTyVars are fv(tys)
- Eg class C a b where
- type F a x :: *
- instance D p s => C (p,q) [r] where
- type F (p,q) x = p -> x
- The tcdTyVars of the F instance decl are {p,q,x},
- i.e. not including s, nor r
- (and indeed neither s nor should be mentioned
- on the RHS of the F instance decl; Trac #5515)
+ Eg class C s t where
+ type F t p :: *
+ instance C w (a,b) where
+ type F (a,b) x = x->a
+ The tcdTyVars of the F decl are {a,b,x}, even though the F decl
+ is nested inside the 'instance' decl.
+
+ However after the renamer, the uniques will match up:
+ instance C w7 (a8,b9) where
+ type F (a8,b9) x10 = x10->a8
+ so that we can compare the type patter in the 'instance' decl and
+ in the associated 'type' decl
------------------------------
Simple classifiers
@@ -631,7 +636,7 @@ instance OutputableBndr name
pp_kind = case mb_kind of
Nothing -> empty
- Just kind -> dcolon <+> pprKind kind
+ Just kind -> dcolon <+> ppr kind
ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdTyPats = typats,
tcdSynRhs = mono_ty})
@@ -653,7 +658,7 @@ instance OutputableBndr name
derivings
where
ppr_sigx Nothing = empty
- ppr_sigx (Just kind) = dcolon <+> pprKind kind
+ ppr_sigx (Just kind) = dcolon <+> ppr kind
ppr (ClassDecl {tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars,
tcdFDs = fds,
diff --git a/compiler/hsSyn/HsExpr.lhs b/compiler/hsSyn/HsExpr.lhs
index 869532e858..7b814e14bb 100644
--- a/compiler/hsSyn/HsExpr.lhs
+++ b/compiler/hsSyn/HsExpr.lhs
@@ -1197,7 +1197,8 @@ data HsBracket id = ExpBr (LHsExpr id) -- [| expr |]
| DecBrL [LHsDecl id] -- [d| decls |]; result of parser
| DecBrG (HsGroup id) -- [d| decls |]; result of renamer
| TypBr (LHsType id) -- [t| type |]
- | VarBr id -- 'x, ''T
+ | VarBr Bool id -- True: 'x, False: ''T
+ -- (The Bool flag is used only in pprHsBracket)
deriving (Data, Typeable)
instance OutputableBndr id => Outputable (HsBracket id) where
@@ -1210,11 +1211,8 @@ pprHsBracket (PatBr p) = thBrackets (char 'p') (ppr p)
pprHsBracket (DecBrG gp) = thBrackets (char 'd') (ppr gp)
pprHsBracket (DecBrL ds) = thBrackets (char 'd') (vcat (map ppr ds))
pprHsBracket (TypBr t) = thBrackets (char 't') (ppr t)
-pprHsBracket (VarBr n) = char '\'' <> ppr n
--- Infelicity: can't show ' vs '', because
--- we can't ask n what its OccName is, because the
--- pretty-printer for HsExpr doesn't ask for NamedThings
--- But the pretty-printer for names will show the OccName class
+pprHsBracket (VarBr True n) = char '\'' <> ppr n
+pprHsBracket (VarBr False n) = ptext (sLit "''") <> ppr n
thBrackets :: SDoc -> SDoc -> SDoc
thBrackets pp_kind pp_body = char '[' <> pp_kind <> char '|' <+>
diff --git a/compiler/hsSyn/HsExpr.lhs-boot b/compiler/hsSyn/HsExpr.lhs-boot
index 4dff75c802..6666243264 100644
--- a/compiler/hsSyn/HsExpr.lhs-boot
+++ b/compiler/hsSyn/HsExpr.lhs-boot
@@ -1,4 +1,5 @@
\begin{code}
+{-# LANGUAGE KindSignatures #-}
{-# OPTIONS -fno-warn-tabs #-}
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and
@@ -13,11 +14,12 @@ import Outputable ( SDoc, OutputableBndr )
import {-# SOURCE #-} HsPat ( LPat )
import Data.Data
-
-data HsExpr i
-data HsSplice i
-data MatchGroup a
-data GRHSs a
+
+-- IA0_NOTE: We need kind annotations because of kind polymorphism
+data HsExpr (i :: *)
+data HsSplice (i :: *)
+data MatchGroup (a :: *)
+data GRHSs (a :: *)
instance Typeable1 HsSplice
instance Data i => Data (HsSplice i)
diff --git a/compiler/hsSyn/HsLit.lhs b/compiler/hsSyn/HsLit.lhs
index b8e4b11e6b..efa61dde67 100644
--- a/compiler/hsSyn/HsLit.lhs
+++ b/compiler/hsSyn/HsLit.lhs
@@ -20,8 +20,7 @@ module HsLit where
import {-# SOURCE #-} HsExpr( SyntaxExpr, pprExpr )
import BasicTypes ( FractionalLit(..) )
-import HsTypes ( PostTcType )
-import Type ( Type )
+import Type ( Type, Kind )
import Outputable
import FastString
@@ -31,6 +30,26 @@ import Data.Data
%************************************************************************
%* *
+\subsection{Annotating the syntax}
+%* *
+%************************************************************************
+
+\begin{code}
+type PostTcKind = Kind
+type PostTcType = Type -- Used for slots in the abstract syntax
+ -- where we want to keep slot for a type
+ -- to be added by the type checker...but
+ -- before typechecking it's just bogus
+
+placeHolderType :: PostTcType -- Used before typechecking
+placeHolderType = panic "Evaluated the place holder for a PostTcType"
+
+placeHolderKind :: PostTcKind -- Used before typechecking
+placeHolderKind = panic "Evaluated the place holder for a PostTcKind"
+\end{code}
+
+%************************************************************************
+%* *
\subsection[HsLit]{Literals}
%* *
%************************************************************************
diff --git a/compiler/hsSyn/HsPat.lhs-boot b/compiler/hsSyn/HsPat.lhs-boot
index 7ba338e41f..28991030ad 100644
--- a/compiler/hsSyn/HsPat.lhs-boot
+++ b/compiler/hsSyn/HsPat.lhs-boot
@@ -1,10 +1,13 @@
\begin{code}
+{-# LANGUAGE KindSignatures #-}
+
module HsPat where
import SrcLoc( Located )
import Data.Data
-data Pat i
+-- IA0_NOTE: We need kind annotation because of kind polymorphism.
+data Pat (i :: *)
type LPat i = Located (Pat i)
instance Typeable1 Pat
diff --git a/compiler/hsSyn/HsTypes.lhs b/compiler/hsSyn/HsTypes.lhs
index 9e20dbdd4d..fec71af3a0 100644
--- a/compiler/hsSyn/HsTypes.lhs
+++ b/compiler/hsSyn/HsTypes.lhs
@@ -16,11 +16,12 @@ HsTypes: Abstract syntax: user-defined types
{-# LANGUAGE DeriveDataTypeable #-}
module HsTypes (
- HsType(..), LHsType,
+ HsType(..), LHsType, HsKind, LHsKind,
HsTyVarBndr(..), LHsTyVarBndr,
HsTupleSort(..), HsExplicitFlag(..),
HsContext, LHsContext,
HsQuasiQuote(..),
+ HsTyWrapper(..),
LBangType, BangType, HsBang(..),
getBangType, getBangStrictness,
@@ -29,16 +30,13 @@ module HsTypes (
mkExplicitHsForAllTy, mkImplicitHsForAllTy, hsExplicitTvs,
hsTyVarName, hsTyVarNames, replaceTyVarName, replaceLTyVarName,
- hsTyVarKind, hsTyVarNameKind,
+ hsTyVarKind, hsLTyVarKind, hsTyVarNameKind,
hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsLTyVarLocNames,
splitHsInstDeclTy_maybe, splitLHsInstDeclTy_maybe,
splitHsForAllTy, splitLHsForAllTy,
splitHsClassTy_maybe, splitLHsClassTy_maybe,
splitHsFunType,
- splitHsAppTys, mkHsAppTys,
-
- -- Type place holder
- PostTcType, placeHolderType, PostTcKind, placeHolderKind,
+ splitHsAppTys, mkHsAppTys, mkHsOpTy,
-- Printing
pprParendHsType, pprHsForAll, pprHsContext, ppr_hs_context,
@@ -46,7 +44,9 @@ module HsTypes (
import {-# SOURCE #-} HsExpr ( HsSplice, pprSplice )
-import NameSet ( FreeVars )
+import HsLit
+
+import NameSet( FreeVars )
import Type
import HsDoc
import BasicTypes
@@ -61,26 +61,6 @@ import Data.Data
%************************************************************************
%* *
-\subsection{Annotating the syntax}
-%* *
-%************************************************************************
-
-\begin{code}
-type PostTcKind = Kind
-type PostTcType = Type -- Used for slots in the abstract syntax
- -- where we want to keep slot for a type
- -- to be added by the type checker...but
- -- before typechecking it's just bogus
-
-placeHolderType :: PostTcType -- Used before typechecking
-placeHolderType = panic "Evaluated the place holder for a PostTcType"
-
-placeHolderKind :: PostTcKind -- Used before typechecking
-placeHolderKind = panic "Evaluated the place holder for a PostTcKind"
-\end{code}
-
-%************************************************************************
-%* *
Quasi quotes; used in types and elsewhere
%* *
%************************************************************************
@@ -136,6 +116,8 @@ type LHsContext name = Located (HsContext name)
type HsContext name = [LHsType name]
type LHsType name = Located (HsType name)
+type HsKind name = HsType name
+type LHsKind name = Located (HsKind name)
data HsType name
= HsForAllTy HsExplicitFlag -- Renamer leaves this flag unchanged, to record the way
@@ -146,7 +128,8 @@ data HsType name
(LHsContext name)
(LHsType name)
- | HsTyVar name -- Type variable or type constructor
+ | HsTyVar name -- Type variable, type constructor, or data constructor
+ -- see Note [Promotions (HsTyVar)]
| HsAppTy (LHsType name)
(LHsType name)
@@ -161,7 +144,7 @@ data HsType name
| HsTupleTy HsTupleSort
[LHsType name] -- Element types (length gives arity)
- | HsOpTy (LHsType name) (Located name) (LHsType name)
+ | HsOpTy (LHsType name) (LHsTyOp name) (LHsType name)
| HsParTy (LHsType name) -- See Note [Parens in HsSyn] in HsExpr
-- Parenthesis preserved for the precedence re-arrangement in RnTypes
@@ -174,7 +157,7 @@ data HsType name
(LHsType name) -- Always allowed even without TypeOperators, and has special kinding rule
| HsKindSig (LHsType name) -- (ty :: kind)
- Kind -- A type with a kind signature
+ (LHsKind name) -- A type with a kind signature
| HsQuasiQuoteTy (HsQuasiQuote name)
@@ -189,11 +172,69 @@ data HsType name
| HsCoreTy Type -- An escape hatch for tunnelling a *closed*
-- Core Type through HsSyn.
-
+
+ | HsExplicitListTy -- A promoted explicit list
+ PostTcKind -- See Note [Promoted lists and tuples]
+ [LHsType name]
+
+ | HsExplicitTupleTy -- A promoted explicit tuple
+ [PostTcKind] -- See Note [Promoted lists and tuples]
+ [LHsType name]
+
+ | HsWrapTy HsTyWrapper (HsType name) -- only in typechecker output
+ deriving (Data, Typeable)
+
+data HsTyWrapper
+ = WpKiApps [Kind] -- kind instantiation: [] k1 k2 .. kn
deriving (Data, Typeable)
+type LHsTyOp name = HsTyOp (Located name)
+type HsTyOp name = (HsTyWrapper, name)
+
+mkHsOpTy :: LHsType name -> Located name -> LHsType name -> HsType name
+mkHsOpTy ty1 op ty2 = HsOpTy ty1 (WpKiApps [], op) ty2
+\end{code}
+
+Note [Promotions (HsTyVar)]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+HsTyVar: A name in a type or kind.
+ Here are the allowed namespaces for the name.
+ In a type:
+ Var: not allowed
+ Data: promoted data constructor
+ Tv: type variable
+ TcCls before renamer: type constructor, class constructor, or promoted data constructor
+ TcCls after renamer: type constructor or class constructor
+ In a kind:
+ Var, Data: not allowed
+ Tv: kind variable
+ TcCls: kind constructor or promoted type constructor
+
+
+Note [Promoted lists and tuples]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Notice the difference between
+ HsListTy HsExplicitListTy
+ HsTupleTy HsExplicitListTupleTy
+
+E.g. f :: [Int] HsListTy
+
+ g3 :: T '[] All these use
+ g2 :: T '[True] HsExplicitListTy
+ g1 :: T '[True,False]
+ g1a :: T [True,False] (can omit ' where unambiguous)
+
+ kind of T :: [Bool] -> * This kind uses HsListTy!
+
+E.g. h :: (Int,Bool) HsTupleTy; f is a pair
+ k :: S '(True,False) HsExplicitTypleTy; S is indexed by
+ a type-level pair of booleans
+ kind of S :: (Bool,Bool) -> * This kind uses HsExplicitTupleTy
+
+
+\begin{code}
data HsTupleSort = HsUnboxedTuple
- | HsBoxyTuple Kind -- Either a Constraint or normal tuple: resolved during type checking
+ | HsBoxyTuple PostTcKind -- Either a Constraint or normal tuple: resolved during type checking
deriving (Data, Typeable)
data HsExplicitFlag = Explicit | Implicit deriving (Data, Typeable)
@@ -252,9 +293,10 @@ data HsTyVarBndr name
name -- See Note [Printing KindedTyVars]
PostTcKind
- | KindedTyVar
- name
- Kind
+ | KindedTyVar
+ name
+ (LHsKind name) -- The user-supplied kind signature
+ PostTcKind
-- *** NOTA BENE *** A "monotype" in a pragma can have
-- for-alls in it, (mostly to do with dictionaries). These
-- must be explicitly Kinded.
@@ -262,15 +304,18 @@ data HsTyVarBndr name
hsTyVarName :: HsTyVarBndr name -> name
hsTyVarName (UserTyVar n _) = n
-hsTyVarName (KindedTyVar n _) = n
+hsTyVarName (KindedTyVar n _ _) = n
hsTyVarKind :: HsTyVarBndr name -> Kind
hsTyVarKind (UserTyVar _ k) = k
-hsTyVarKind (KindedTyVar _ k) = k
+hsTyVarKind (KindedTyVar _ _ k) = k
+
+hsLTyVarKind :: LHsTyVarBndr name -> Kind
+hsLTyVarKind = hsTyVarKind . unLoc
hsTyVarNameKind :: HsTyVarBndr name -> (name, Kind)
hsTyVarNameKind (UserTyVar n k) = (n,k)
-hsTyVarNameKind (KindedTyVar n k) = (n,k)
+hsTyVarNameKind (KindedTyVar n _ k) = (n,k)
hsLTyVarName :: LHsTyVarBndr name -> name
hsLTyVarName = hsTyVarName . unLoc
@@ -287,12 +332,18 @@ hsLTyVarLocName = fmap hsTyVarName
hsLTyVarLocNames :: [LHsTyVarBndr name] -> [Located name]
hsLTyVarLocNames = map hsLTyVarLocName
-replaceTyVarName :: HsTyVarBndr name1 -> name2 -> HsTyVarBndr name2
-replaceTyVarName (UserTyVar _ k) n' = UserTyVar n' k
-replaceTyVarName (KindedTyVar _ k) n' = KindedTyVar n' k
-
-replaceLTyVarName :: LHsTyVarBndr name1 -> name2 -> LHsTyVarBndr name2
-replaceLTyVarName (L loc n1) n2 = L loc (replaceTyVarName n1 n2)
+replaceTyVarName :: (Monad m) => HsTyVarBndr name1 -> name2 -- new type name
+ -> (LHsKind name1 -> m (LHsKind name2)) -- kind renaming
+ -> m (HsTyVarBndr name2)
+replaceTyVarName (UserTyVar _ k) n' _ = return $ UserTyVar n' k
+replaceTyVarName (KindedTyVar _ k tck) n' rn = do
+ k' <- rn k
+ return $ KindedTyVar n' k' tck
+
+replaceLTyVarName :: (Monad m) => LHsTyVarBndr name1 -> name2
+ -> (LHsKind name1 -> m (LHsKind name2))
+ -> m (LHsTyVarBndr name2)
+replaceLTyVarName (L loc n1) n2 rn = replaceTyVarName n1 n2 rn >>= return . L loc
\end{code}
@@ -351,12 +402,12 @@ splitLHsClassTy_maybe ty
= checkl ty []
where
checkl (L l ty) args = case ty of
- HsTyVar t -> Just (L l t, args)
- HsAppTy l r -> checkl l (r:args)
- HsOpTy l tc r -> checkl (fmap HsTyVar tc) (l:r:args)
- HsParTy t -> checkl t args
- HsKindSig ty _ -> checkl ty args
- _ -> Nothing
+ HsTyVar t -> Just (L l t, args)
+ HsAppTy l r -> checkl l (r:args)
+ HsOpTy l (_, tc) r -> checkl (fmap HsTyVar tc) (l:r:args)
+ HsParTy t -> checkl t args
+ HsKindSig ty _ -> checkl ty args
+ _ -> Nothing
-- Splits HsType into the (init, last) parts
-- Breaks up any parens in the result type:
@@ -380,9 +431,9 @@ splitHsFunType other = ([], other)
instance (OutputableBndr name) => Outputable (HsType name) where
ppr ty = pprHsType ty
-instance (Outputable name) => Outputable (HsTyVarBndr name) where
+instance (OutputableBndr name) => Outputable (HsTyVarBndr name) where
ppr (UserTyVar name _) = ppr name
- ppr (KindedTyVar name kind) = hsep [ppr name, dcolon, pprParendKind kind]
+ ppr (KindedTyVar name kind _) = parens $ hsep [ppr name, dcolon, ppr kind]
pprHsForAll :: OutputableBndr name => HsExplicitFlag -> [LHsTyVarBndr name] -> LHsContext name -> SDoc
pprHsForAll exp tvs cxt
@@ -470,12 +521,28 @@ ppr_mono_ty _ (HsTupleTy con tys) = tupleParens std_con (interpp'SP tys)
where std_con = case con of
HsUnboxedTuple -> UnboxedTuple
HsBoxyTuple _ -> BoxedTuple
-ppr_mono_ty _ (HsKindSig ty kind) = parens (ppr_mono_lty pREC_TOP ty <+> dcolon <+> pprKind kind)
+ppr_mono_ty _ (HsKindSig ty kind) = parens (ppr_mono_lty pREC_TOP ty <+> dcolon <+> ppr kind)
ppr_mono_ty _ (HsListTy ty) = brackets (ppr_mono_lty pREC_TOP ty)
ppr_mono_ty _ (HsPArrTy ty) = pabrackets (ppr_mono_lty pREC_TOP ty)
ppr_mono_ty prec (HsIParamTy n ty) = maybeParen prec pREC_FUN (ppr n <+> dcolon <+> ppr_mono_lty pREC_TOP ty)
ppr_mono_ty _ (HsSpliceTy s _ _) = pprSplice s
ppr_mono_ty _ (HsCoreTy ty) = ppr ty
+ppr_mono_ty _ (HsExplicitListTy _ tys) = quote $ brackets (interpp'SP tys)
+ppr_mono_ty _ (HsExplicitTupleTy _ tys) = quote $ parens (interpp'SP tys)
+
+ppr_mono_ty ctxt_prec (HsWrapTy (WpKiApps _kis) ty)
+ = ppr_mono_ty ctxt_prec ty
+-- We are not printing kind applications. If we wanted to do so, we should do
+-- something like this:
+{-
+ = go ctxt_prec kis ty
+ where
+ go ctxt_prec [] ty = ppr_mono_ty ctxt_prec ty
+ go ctxt_prec (ki:kis) ty
+ = maybeParen ctxt_prec pREC_CON $
+ hsep [ go pREC_FUN kis ty
+ , ptext (sLit "@") <> pprParendKind ki ]
+-}
ppr_mono_ty ctxt_prec (HsEqTy ty1 ty2)
= maybeParen ctxt_prec pREC_OP $
@@ -485,9 +552,9 @@ ppr_mono_ty ctxt_prec (HsAppTy fun_ty arg_ty)
= maybeParen ctxt_prec pREC_CON $
hsep [ppr_mono_lty pREC_FUN fun_ty, ppr_mono_lty pREC_CON arg_ty]
-ppr_mono_ty ctxt_prec (HsOpTy ty1 op ty2)
+ppr_mono_ty ctxt_prec (HsOpTy ty1 (wrapper, op) ty2)
= maybeParen ctxt_prec pREC_OP $
- ppr_mono_lty pREC_OP ty1 <+> ppr op <+> ppr_mono_lty pREC_OP ty2
+ ppr_mono_lty pREC_OP ty1 <+> ppr_mono_ty pREC_CON (HsWrapTy wrapper (HsTyVar (unLoc op))) <+> ppr_mono_lty pREC_OP ty2
ppr_mono_ty _ (HsParTy ty)
= parens (ppr_mono_lty pREC_TOP ty)
diff --git a/compiler/iface/BinIface.hs b/compiler/iface/BinIface.hs
index 63c60d1f3e..eb6ca87ba3 100644
--- a/compiler/iface/BinIface.hs
+++ b/compiler/iface/BinIface.hs
@@ -1,21 +1,20 @@
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
+--
+-- (c) The University of Glasgow 2002-2006
+--
{-# OPTIONS_GHC -O #-}
-- We always optimise this, otherwise performance of a non-optimised
-- compiler is severely affected
---
--- (c) The University of Glasgow 2002-2006
---
--- Binary interface file support.
-
-module BinIface ( writeBinIface, readBinIface, getSymtabName, getDictFastString,
- CheckHiWay(..), TraceBinIFaceReading(..) ) where
+-- | Binary interface file support.
+module BinIface (
+ writeBinIface,
+ readBinIface,
+ getSymtabName,
+ getDictFastString,
+ CheckHiWay(..),
+ TraceBinIFaceReading(..)
+ ) where
#include "HsVersions.h"
@@ -62,179 +61,182 @@ import Data.IORef
import Control.Monad
import System.Time ( ClockTime(..) )
+
+-- ---------------------------------------------------------------------------
+-- Reading and writing binary interface files
+--
+
data CheckHiWay = CheckHiWay | IgnoreHiWay
deriving Eq
data TraceBinIFaceReading = TraceBinIFaceReading | QuietBinIFaceReading
deriving Eq
--- ---------------------------------------------------------------------------
--- Reading and writing binary interface files
-
+-- | Read an interface file
readBinIface :: CheckHiWay -> TraceBinIFaceReading -> FilePath
-> TcRnIf a b ModIface
readBinIface checkHiWay traceBinIFaceReading hi_path = do
- ncu <- mkNameCacheUpdater
- dflags <- getDOpts
- liftIO $ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu
+ ncu <- mkNameCacheUpdater
+ dflags <- getDOpts
+ liftIO $ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu
readBinIface_ :: DynFlags -> CheckHiWay -> TraceBinIFaceReading -> FilePath
-> NameCacheUpdater
-> IO ModIface
readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do
- let printer :: SDoc -> IO ()
- printer = case traceBinIFaceReading of
- TraceBinIFaceReading -> \sd -> printSDoc sd defaultDumpStyle
- QuietBinIFaceReading -> \_ -> return ()
- wantedGot :: Outputable a => String -> a -> a -> IO ()
- wantedGot what wanted got
- = printer (text what <> text ": " <>
+ let printer :: SDoc -> IO ()
+ printer = case traceBinIFaceReading of
+ TraceBinIFaceReading -> \sd -> printSDoc sd defaultDumpStyle
+ QuietBinIFaceReading -> \_ -> return ()
+ wantedGot :: Outputable a => String -> a -> a -> IO ()
+ wantedGot what wanted got =
+ printer (text what <> text ": " <>
vcat [text "Wanted " <> ppr wanted <> text ",",
text "got " <> ppr got])
- errorOnMismatch :: (Eq a, Show a) => String -> a -> a -> IO ()
- errorOnMismatch what wanted got
+ errorOnMismatch :: (Eq a, Show a) => String -> a -> a -> IO ()
+ errorOnMismatch what wanted got =
-- This will be caught by readIface which will emit an error
-- msg containing the iface module name.
- = when (wanted /= got) $ ghcError $ ProgramError
- (what ++ " (wanted " ++ show wanted
- ++ ", got " ++ show got ++ ")")
- bh <- Binary.readBinMem hi_path
-
- -- Read the magic number to check that this really is a GHC .hi file
- -- (This magic number does not change when we change
- -- GHC interface file format)
- magic <- get bh
- wantedGot "Magic" (binaryInterfaceMagic dflags) magic
- errorOnMismatch "magic number mismatch: old/corrupt interface file?"
- (binaryInterfaceMagic dflags) magic
-
- -- Note [dummy iface field]
- -- read a dummy 32/64 bit value. This field used to hold the
- -- dictionary pointer in old interface file formats, but now
- -- the dictionary pointer is after the version (where it
- -- should be). Also, the serialisation of value of type "Bin
- -- a" used to depend on the word size of the machine, now they
- -- are always 32 bits.
- --
- if wORD_SIZE == 4
- then do _ <- Binary.get bh :: IO Word32; return ()
- else do _ <- Binary.get bh :: IO Word64; return ()
-
- -- Check the interface file version and ways.
- check_ver <- get bh
- let our_ver = show opt_HiVersion
- wantedGot "Version" our_ver check_ver
- errorOnMismatch "mismatched interface file versions" our_ver check_ver
-
- check_way <- get bh
- let way_descr = getWayDescr dflags
- wantedGot "Way" way_descr check_way
- when (checkHiWay == CheckHiWay) $
- errorOnMismatch "mismatched interface file ways" way_descr check_way
-
- -- Read the dictionary
- -- The next word in the file is a pointer to where the dictionary is
- -- (probably at the end of the file)
- dict_p <- Binary.get bh
- data_p <- tellBin bh -- Remember where we are now
- seekBin bh dict_p
- dict <- getDictionary bh
- seekBin bh data_p -- Back to where we were before
-
- -- Initialise the user-data field of bh
- bh <- do
- bh <- return $ setUserData bh $ newReadState (error "getSymtabName")
- (getDictFastString dict)
-
- symtab_p <- Binary.get bh -- Get the symtab ptr
+ when (wanted /= got) $ ghcError $ ProgramError
+ (what ++ " (wanted " ++ show wanted
+ ++ ", got " ++ show got ++ ")")
+ bh <- Binary.readBinMem hi_path
+
+ -- Read the magic number to check that this really is a GHC .hi file
+ -- (This magic number does not change when we change
+ -- GHC interface file format)
+ magic <- get bh
+ wantedGot "Magic" (binaryInterfaceMagic dflags) magic
+ errorOnMismatch "magic number mismatch: old/corrupt interface file?"
+ (binaryInterfaceMagic dflags) magic
+
+ -- Note [dummy iface field]
+ -- read a dummy 32/64 bit value. This field used to hold the
+ -- dictionary pointer in old interface file formats, but now
+ -- the dictionary pointer is after the version (where it
+ -- should be). Also, the serialisation of value of type "Bin
+ -- a" used to depend on the word size of the machine, now they
+ -- are always 32 bits.
+ if wORD_SIZE == 4
+ then do _ <- Binary.get bh :: IO Word32; return ()
+ else do _ <- Binary.get bh :: IO Word64; return ()
+
+ -- Check the interface file version and ways.
+ check_ver <- get bh
+ let our_ver = show opt_HiVersion
+ wantedGot "Version" our_ver check_ver
+ errorOnMismatch "mismatched interface file versions" our_ver check_ver
+
+ check_way <- get bh
+ let way_descr = getWayDescr dflags
+ wantedGot "Way" way_descr check_way
+ when (checkHiWay == CheckHiWay) $
+ errorOnMismatch "mismatched interface file ways" way_descr check_way
+
+ -- Read the dictionary
+ -- The next word in the file is a pointer to where the dictionary is
+ -- (probably at the end of the file)
+ dict_p <- Binary.get bh
data_p <- tellBin bh -- Remember where we are now
- seekBin bh symtab_p
- symtab <- getSymbolTable bh ncu
+ seekBin bh dict_p
+ dict <- getDictionary bh
seekBin bh data_p -- Back to where we were before
-
- -- It is only now that we know how to get a Name
- return $ setUserData bh $ newReadState (getSymtabName ncu dict symtab)
- (getDictFastString dict)
- -- Read the interface file
- get bh
+ -- Initialise the user-data field of bh
+ bh <- do
+ bh <- return $ setUserData bh $ newReadState (error "getSymtabName")
+ (getDictFastString dict)
+ symtab_p <- Binary.get bh -- Get the symtab ptr
+ data_p <- tellBin bh -- Remember where we are now
+ seekBin bh symtab_p
+ symtab <- getSymbolTable bh ncu
+ seekBin bh data_p -- Back to where we were before
+
+ -- It is only now that we know how to get a Name
+ return $ setUserData bh $ newReadState (getSymtabName ncu dict symtab)
+ (getDictFastString dict)
+ -- Read the interface file
+ get bh
+-- | Write an interface file
writeBinIface :: DynFlags -> FilePath -> ModIface -> IO ()
writeBinIface dflags hi_path mod_iface = do
- bh <- openBinMem initBinMemSize
- put_ bh (binaryInterfaceMagic dflags)
-
- -- dummy 32/64-bit field before the version/way for
- -- compatibility with older interface file formats.
- -- See Note [dummy iface field] above.
- if wORD_SIZE == 4
- then Binary.put_ bh (0 :: Word32)
- else Binary.put_ bh (0 :: Word64)
-
- -- The version and way descriptor go next
- put_ bh (show opt_HiVersion)
- let way_descr = getWayDescr dflags
- put_ bh way_descr
-
- -- Remember where the dictionary pointer will go
- dict_p_p <- tellBin bh
- put_ bh dict_p_p -- Placeholder for ptr to dictionary
-
- -- Remember where the symbol table pointer will go
- symtab_p_p <- tellBin bh
- put_ bh symtab_p_p
-
- -- Make some intial state
- symtab_next <- newFastMutInt
- writeFastMutInt symtab_next 0
- symtab_map <- newIORef emptyUFM
- let bin_symtab = BinSymbolTable {
- bin_symtab_next = symtab_next,
- bin_symtab_map = symtab_map }
- dict_next_ref <- newFastMutInt
- writeFastMutInt dict_next_ref 0
- dict_map_ref <- newIORef emptyUFM
- let bin_dict = BinDictionary {
- bin_dict_next = dict_next_ref,
- bin_dict_map = dict_map_ref }
+ bh <- openBinMem initBinMemSize
+ put_ bh (binaryInterfaceMagic dflags)
+
+ -- dummy 32/64-bit field before the version/way for
+ -- compatibility with older interface file formats.
+ -- See Note [dummy iface field] above.
+ if wORD_SIZE == 4
+ then Binary.put_ bh (0 :: Word32)
+ else Binary.put_ bh (0 :: Word64)
+
+ -- The version and way descriptor go next
+ put_ bh (show opt_HiVersion)
+ let way_descr = getWayDescr dflags
+ put_ bh way_descr
+
+ -- Remember where the dictionary pointer will go
+ dict_p_p <- tellBin bh
+ -- Placeholder for ptr to dictionary
+ put_ bh dict_p_p
+
+ -- Remember where the symbol table pointer will go
+ symtab_p_p <- tellBin bh
+ put_ bh symtab_p_p
+
+ -- Make some intial state
+ symtab_next <- newFastMutInt
+ writeFastMutInt symtab_next 0
+ symtab_map <- newIORef emptyUFM
+ let bin_symtab = BinSymbolTable {
+ bin_symtab_next = symtab_next,
+ bin_symtab_map = symtab_map }
+ dict_next_ref <- newFastMutInt
+ writeFastMutInt dict_next_ref 0
+ dict_map_ref <- newIORef emptyUFM
+ let bin_dict = BinDictionary {
+ bin_dict_next = dict_next_ref,
+ bin_dict_map = dict_map_ref }
- -- Put the main thing,
- bh <- return $ setUserData bh $ newWriteState (putName bin_dict bin_symtab)
- (putFastString bin_dict)
- put_ bh mod_iface
-
- -- Write the symtab pointer at the fornt of the file
- symtab_p <- tellBin bh -- This is where the symtab will start
- putAt bh symtab_p_p symtab_p -- Fill in the placeholder
- seekBin bh symtab_p -- Seek back to the end of the file
-
- -- Write the symbol table itself
- symtab_next <- readFastMutInt symtab_next
- symtab_map <- readIORef symtab_map
- putSymbolTable bh symtab_next symtab_map
- debugTraceMsg dflags 3 (text "writeBinIface:" <+> int symtab_next
+ -- Put the main thing,
+ bh <- return $ setUserData bh $ newWriteState (putName bin_dict bin_symtab)
+ (putFastString bin_dict)
+ put_ bh mod_iface
+
+ -- Write the symtab pointer at the fornt of the file
+ symtab_p <- tellBin bh -- This is where the symtab will start
+ putAt bh symtab_p_p symtab_p -- Fill in the placeholder
+ seekBin bh symtab_p -- Seek back to the end of the file
+
+ -- Write the symbol table itself
+ symtab_next <- readFastMutInt symtab_next
+ symtab_map <- readIORef symtab_map
+ putSymbolTable bh symtab_next symtab_map
+ debugTraceMsg dflags 3 (text "writeBinIface:" <+> int symtab_next
<+> text "Names")
- -- NB. write the dictionary after the symbol table, because
- -- writing the symbol table may create more dictionary entries.
+ -- NB. write the dictionary after the symbol table, because
+ -- writing the symbol table may create more dictionary entries.
- -- Write the dictionary pointer at the fornt of the file
- dict_p <- tellBin bh -- This is where the dictionary will start
- putAt bh dict_p_p dict_p -- Fill in the placeholder
- seekBin bh dict_p -- Seek back to the end of the file
+ -- Write the dictionary pointer at the fornt of the file
+ dict_p <- tellBin bh -- This is where the dictionary will start
+ putAt bh dict_p_p dict_p -- Fill in the placeholder
+ seekBin bh dict_p -- Seek back to the end of the file
- -- Write the dictionary itself
- dict_next <- readFastMutInt dict_next_ref
- dict_map <- readIORef dict_map_ref
- putDictionary bh dict_next dict_map
- debugTraceMsg dflags 3 (text "writeBinIface:" <+> int dict_next
- <+> text "dict entries")
+ -- Write the dictionary itself
+ dict_next <- readFastMutInt dict_next_ref
+ dict_map <- readIORef dict_map_ref
+ putDictionary bh dict_next dict_map
+ debugTraceMsg dflags 3 (text "writeBinIface:" <+> int dict_next
+ <+> text "dict entries")
- -- And send the result to the file
- writeBinMem bh hi_path
+ -- And send the result to the file
+ writeBinMem bh hi_path
+-- | Initial ram buffer to allocate for writing interface files
initBinMemSize :: Int
initBinMemSize = 1024 * 1024
@@ -243,54 +245,45 @@ binaryInterfaceMagic dflags
| target32Bit (targetPlatform dflags) = 0x1face
| otherwise = 0x1face64
+
-- -----------------------------------------------------------------------------
-- The symbol table
+--
putSymbolTable :: BinHandle -> Int -> UniqFM (Int,Name) -> IO ()
putSymbolTable bh next_off symtab = do
- put_ bh next_off
- let names = elems (array (0,next_off-1) (eltsUFM symtab))
- mapM_ (\n -> serialiseName bh n symtab) names
+ put_ bh next_off
+ let names = elems (array (0,next_off-1) (eltsUFM symtab))
+ mapM_ (\n -> serialiseName bh n symtab) names
-getSymbolTable :: BinHandle -> NameCacheUpdater
- -> IO SymbolTable
+getSymbolTable :: BinHandle -> NameCacheUpdater -> IO SymbolTable
getSymbolTable bh ncu = do
- sz <- get bh
- od_names <- sequence (replicate sz (get bh))
- updateNameCache ncu $ \namecache ->
- let
- arr = listArray (0,sz-1) names
- (namecache', names) =
+ sz <- get bh
+ od_names <- sequence (replicate sz (get bh))
+ updateNameCache ncu $ \namecache ->
+ let arr = listArray (0,sz-1) names
+ (namecache', names) =
mapAccumR (fromOnDiskName arr) namecache od_names
- in (namecache', arr)
+ in (namecache', arr)
type OnDiskName = (PackageId, ModuleName, OccName)
-fromOnDiskName
- :: Array Int Name
- -> NameCache
- -> OnDiskName
- -> (NameCache, Name)
+fromOnDiskName :: Array Int Name -> NameCache -> OnDiskName -> (NameCache, Name)
fromOnDiskName _ nc (pid, mod_name, occ) =
- let
- mod = mkModule pid mod_name
+ let mod = mkModule pid mod_name
cache = nsNames nc
- in
- case lookupOrigNameCache cache mod occ of
- Just name -> (nc, name)
- Nothing ->
- case takeUniqFromSupply (nsUniqs nc) of
- (uniq, us) ->
- let
- name = mkExternalName uniq mod occ noSrcSpan
- new_cache = extendNameCache cache mod occ name
- in
- ( nc{ nsUniqs = us, nsNames = new_cache }, name )
+ in case lookupOrigNameCache cache mod occ of
+ Just name -> (nc, name)
+ Nothing ->
+ let (uniq, us) = takeUniqFromSupply (nsUniqs nc)
+ name = mkExternalName uniq mod occ noSrcSpan
+ new_cache = extendNameCache cache mod occ name
+ in ( nc{ nsUniqs = us, nsNames = new_cache }, name )
serialiseName :: BinHandle -> Name -> UniqFM (Int,Name) -> IO ()
serialiseName bh name _ = do
- let mod = ASSERT2( isExternalName name, ppr name ) nameModule name
- put_ bh (modulePackageId mod, moduleName mod, nameOccName name)
+ let mod = ASSERT2( isExternalName name, ppr name ) nameModule name
+ put_ bh (modulePackageId mod, moduleName mod, nameOccName name)
-- Note [Symbol table representation of names]
@@ -318,8 +311,7 @@ knownKeyNamesMap :: UniqFM Name
knownKeyNamesMap = listToUFM_Directly [(nameUnique n, n) | n <- knownKeyNames]
where
knownKeyNames :: [Name]
- knownKeyNames = map getName wiredInThings
- ++ basicKnownKeyNames
+ knownKeyNames = map getName wiredInThings ++ basicKnownKeyNames
-- See Note [Symbol table representation of names]
@@ -479,148 +471,152 @@ data BinDictionary = BinDictionary {
instance Binary ModIface where
put_ bh (ModIface {
- mi_module = mod,
- mi_boot = is_boot,
- mi_iface_hash= iface_hash,
- mi_mod_hash = mod_hash,
- mi_orphan = orphan,
- mi_finsts = hasFamInsts,
- mi_deps = deps,
- mi_usages = usages,
- mi_exports = exports,
- mi_exp_hash = exp_hash,
+ mi_module = mod,
+ mi_boot = is_boot,
+ mi_iface_hash= iface_hash,
+ mi_mod_hash = mod_hash,
+ mi_flag_hash = flag_hash,
+ mi_orphan = orphan,
+ mi_finsts = hasFamInsts,
+ mi_deps = deps,
+ mi_usages = usages,
+ mi_exports = exports,
+ mi_exp_hash = exp_hash,
mi_used_th = used_th,
mi_fixities = fixities,
- mi_warns = warns,
- mi_anns = anns,
- mi_decls = decls,
- mi_insts = insts,
- mi_fam_insts = fam_insts,
- mi_rules = rules,
- mi_orphan_hash = orphan_hash,
+ mi_warns = warns,
+ mi_anns = anns,
+ mi_decls = decls,
+ mi_insts = insts,
+ mi_fam_insts = fam_insts,
+ mi_rules = rules,
+ mi_orphan_hash = orphan_hash,
mi_vect_info = vect_info,
mi_hpc = hpc_info,
mi_trust = trust,
mi_trust_pkg = trust_pkg }) = do
- put_ bh mod
- put_ bh is_boot
- put_ bh iface_hash
- put_ bh mod_hash
- put_ bh orphan
- put_ bh hasFamInsts
- lazyPut bh deps
- lazyPut bh usages
- put_ bh exports
- put_ bh exp_hash
+ put_ bh mod
+ put_ bh is_boot
+ put_ bh iface_hash
+ put_ bh mod_hash
+ put_ bh flag_hash
+ put_ bh orphan
+ put_ bh hasFamInsts
+ lazyPut bh deps
+ lazyPut bh usages
+ put_ bh exports
+ put_ bh exp_hash
put_ bh used_th
put_ bh fixities
- lazyPut bh warns
- lazyPut bh anns
+ lazyPut bh warns
+ lazyPut bh anns
put_ bh decls
- put_ bh insts
- put_ bh fam_insts
- lazyPut bh rules
- put_ bh orphan_hash
+ put_ bh insts
+ put_ bh fam_insts
+ lazyPut bh rules
+ put_ bh orphan_hash
put_ bh vect_info
- put_ bh hpc_info
- put_ bh trust
- put_ bh trust_pkg
+ put_ bh hpc_info
+ put_ bh trust
+ put_ bh trust_pkg
get bh = do
- mod_name <- get bh
- is_boot <- get bh
- iface_hash <- get bh
- mod_hash <- get bh
- orphan <- get bh
- hasFamInsts <- get bh
- deps <- lazyGet bh
- usages <- lazyGet bh
- exports <- get bh
- exp_hash <- get bh
- used_th <- get bh
- fixities <- get bh
- warns <- lazyGet bh
- anns <- lazyGet bh
- decls <- get bh
- insts <- get bh
- fam_insts <- get bh
- rules <- lazyGet bh
- orphan_hash <- get bh
- vect_info <- get bh
- hpc_info <- get bh
- trust <- get bh
- trust_pkg <- get bh
- return (ModIface {
- mi_module = mod_name,
- mi_boot = is_boot,
- mi_iface_hash = iface_hash,
- mi_mod_hash = mod_hash,
- mi_orphan = orphan,
- mi_finsts = hasFamInsts,
- mi_deps = deps,
- mi_usages = usages,
- mi_exports = exports,
- mi_exp_hash = exp_hash,
- mi_used_th = used_th,
- mi_anns = anns,
- mi_fixities = fixities,
- mi_warns = warns,
- mi_decls = decls,
- mi_globals = Nothing,
- mi_insts = insts,
- mi_fam_insts = fam_insts,
- mi_rules = rules,
- mi_orphan_hash = orphan_hash,
- mi_vect_info = vect_info,
- mi_hpc = hpc_info,
- mi_trust = trust,
- mi_trust_pkg = trust_pkg,
- -- And build the cached values
- mi_warn_fn = mkIfaceWarnCache warns,
- mi_fix_fn = mkIfaceFixCache fixities,
- mi_hash_fn = mkIfaceHashCache decls })
+ mod_name <- get bh
+ is_boot <- get bh
+ iface_hash <- get bh
+ mod_hash <- get bh
+ flag_hash <- get bh
+ orphan <- get bh
+ hasFamInsts <- get bh
+ deps <- lazyGet bh
+ usages <- {-# SCC "bin_usages" #-} lazyGet bh
+ exports <- {-# SCC "bin_exports" #-} get bh
+ exp_hash <- get bh
+ used_th <- get bh
+ fixities <- {-# SCC "bin_fixities" #-} get bh
+ warns <- {-# SCC "bin_warns" #-} lazyGet bh
+ anns <- {-# SCC "bin_anns" #-} lazyGet bh
+ decls <- {-# SCC "bin_tycldecls" #-} get bh
+ insts <- {-# SCC "bin_insts" #-} get bh
+ fam_insts <- {-# SCC "bin_fam_insts" #-} get bh
+ rules <- {-# SCC "bin_rules" #-} lazyGet bh
+ orphan_hash <- get bh
+ vect_info <- get bh
+ hpc_info <- get bh
+ trust <- get bh
+ trust_pkg <- get bh
+ return (ModIface {
+ mi_module = mod_name,
+ mi_boot = is_boot,
+ mi_iface_hash = iface_hash,
+ mi_mod_hash = mod_hash,
+ mi_flag_hash = flag_hash,
+ mi_orphan = orphan,
+ mi_finsts = hasFamInsts,
+ mi_deps = deps,
+ mi_usages = usages,
+ mi_exports = exports,
+ mi_exp_hash = exp_hash,
+ mi_used_th = used_th,
+ mi_anns = anns,
+ mi_fixities = fixities,
+ mi_warns = warns,
+ mi_decls = decls,
+ mi_globals = Nothing,
+ mi_insts = insts,
+ mi_fam_insts = fam_insts,
+ mi_rules = rules,
+ mi_orphan_hash = orphan_hash,
+ mi_vect_info = vect_info,
+ mi_hpc = hpc_info,
+ mi_trust = trust,
+ mi_trust_pkg = trust_pkg,
+ -- And build the cached values
+ mi_warn_fn = mkIfaceWarnCache warns,
+ mi_fix_fn = mkIfaceFixCache fixities,
+ mi_hash_fn = mkIfaceHashCache decls })
getWayDescr :: DynFlags -> String
getWayDescr dflags
| cGhcUnregisterised == "YES" = 'u':tag
| otherwise = tag
where tag = buildTag dflags
- -- if this is an unregisterised build, make sure our interfaces
- -- can't be used by a registerised build.
+ -- if this is an unregisterised build, make sure our interfaces
+ -- can't be used by a registerised build.
-------------------------------------------------------------------------
--- Types from: HscTypes
+-- Types from: HscTypes
-------------------------------------------------------------------------
instance Binary Dependencies where
put_ bh deps = do put_ bh (dep_mods deps)
- put_ bh (dep_pkgs deps)
- put_ bh (dep_orphs deps)
- put_ bh (dep_finsts deps)
+ put_ bh (dep_pkgs deps)
+ put_ bh (dep_orphs deps)
+ put_ bh (dep_finsts deps)
get bh = do ms <- get bh
- ps <- get bh
- os <- get bh
- fis <- get bh
- return (Deps { dep_mods = ms, dep_pkgs = ps, dep_orphs = os,
- dep_finsts = fis })
+ ps <- get bh
+ os <- get bh
+ fis <- get bh
+ return (Deps { dep_mods = ms, dep_pkgs = ps, dep_orphs = os,
+ dep_finsts = fis })
instance Binary AvailInfo where
put_ bh (Avail aa) = do
- putByte bh 0
- put_ bh aa
+ putByte bh 0
+ put_ bh aa
put_ bh (AvailTC ab ac) = do
- putByte bh 1
- put_ bh ab
- put_ bh ac
+ putByte bh 1
+ put_ bh ab
+ put_ bh ac
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- return (Avail aa)
- _ -> do ab <- get bh
- ac <- get bh
- return (AvailTC ab ac)
+ h <- getByte bh
+ case h of
+ 0 -> do aa <- get bh
+ return (Avail aa)
+ _ -> do ab <- get bh
+ ac <- get bh
+ return (AvailTC ab ac)
-- where should this be located?
@@ -709,29 +705,29 @@ instance Binary WarningTxt where
return (DeprecatedTxt d)
-------------------------------------------------------------------------
--- Types from: BasicTypes
+-- Types from: BasicTypes
-------------------------------------------------------------------------
instance Binary Activation where
put_ bh NeverActive = do
- putByte bh 0
+ putByte bh 0
put_ bh AlwaysActive = do
- putByte bh 1
+ putByte bh 1
put_ bh (ActiveBefore aa) = do
- putByte bh 2
- put_ bh aa
+ putByte bh 2
+ put_ bh aa
put_ bh (ActiveAfter ab) = do
- putByte bh 3
- put_ bh ab
+ putByte bh 3
+ put_ bh ab
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return NeverActive
- 1 -> do return AlwaysActive
- 2 -> do aa <- get bh
- return (ActiveBefore aa)
- _ -> do ab <- get bh
- return (ActiveAfter ab)
+ h <- getByte bh
+ case h of
+ 0 -> do return NeverActive
+ 1 -> do return AlwaysActive
+ 2 -> do aa <- get bh
+ return (ActiveBefore aa)
+ _ -> do ab <- get bh
+ return (ActiveAfter ab)
instance Binary RuleMatchInfo where
put_ bh FunLike = putByte bh 0
@@ -773,13 +769,15 @@ instance Binary HsBang where
put_ bh HsStrict = putByte bh 1
put_ bh HsUnpack = putByte bh 2
put_ bh HsUnpackFailed = putByte bh 3
+ put_ bh HsNoUnpack = putByte bh 4
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return HsNoBang
- 1 -> do return HsStrict
- 2 -> do return HsUnpack
- _ -> do return HsUnpackFailed
+ h <- getByte bh
+ case h of
+ 0 -> do return HsNoBang
+ 1 -> do return HsStrict
+ 2 -> do return HsUnpack
+ 3 -> do return HsUnpackFailed
+ _ -> do return HsNoUnpack
instance Binary TupleSort where
put_ bh BoxedTuple = putByte bh 0
@@ -794,254 +792,324 @@ instance Binary TupleSort where
instance Binary RecFlag where
put_ bh Recursive = do
- putByte bh 0
+ putByte bh 0
put_ bh NonRecursive = do
- putByte bh 1
+ putByte bh 1
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return Recursive
- _ -> do return NonRecursive
+ h <- getByte bh
+ case h of
+ 0 -> do return Recursive
+ _ -> do return NonRecursive
instance Binary DefMethSpec where
put_ bh NoDM = putByte bh 0
put_ bh VanillaDM = putByte bh 1
put_ bh GenericDM = putByte bh 2
get bh = do
- h <- getByte bh
- case h of
- 0 -> return NoDM
- 1 -> return VanillaDM
- _ -> return GenericDM
+ h <- getByte bh
+ case h of
+ 0 -> return NoDM
+ 1 -> return VanillaDM
+ _ -> return GenericDM
instance Binary FixityDirection where
put_ bh InfixL = do
- putByte bh 0
+ putByte bh 0
put_ bh InfixR = do
- putByte bh 1
+ putByte bh 1
put_ bh InfixN = do
- putByte bh 2
+ putByte bh 2
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return InfixL
- 1 -> do return InfixR
- _ -> do return InfixN
+ h <- getByte bh
+ case h of
+ 0 -> do return InfixL
+ 1 -> do return InfixR
+ _ -> do return InfixN
instance Binary Fixity where
put_ bh (Fixity aa ab) = do
- put_ bh aa
- put_ bh ab
+ put_ bh aa
+ put_ bh ab
get bh = do
- aa <- get bh
- ab <- get bh
- return (Fixity aa ab)
+ aa <- get bh
+ ab <- get bh
+ return (Fixity aa ab)
instance (Binary name) => Binary (IPName name) where
put_ bh (IPName aa) = put_ bh aa
get bh = do aa <- get bh
- return (IPName aa)
+ return (IPName aa)
-------------------------------------------------------------------------
--- Types from: Demand
+-- Types from: Demand
-------------------------------------------------------------------------
instance Binary DmdType where
- -- Ignore DmdEnv when spitting out the DmdType
+ -- Ignore DmdEnv when spitting out the DmdType
put bh (DmdType _ ds dr) = do p <- put bh ds; put_ bh dr; return (castBin p)
get bh = do ds <- get bh; dr <- get bh; return (DmdType emptyVarEnv ds dr)
instance Binary Demand where
put_ bh Top = do
- putByte bh 0
+ putByte bh 0
put_ bh Abs = do
- putByte bh 1
+ putByte bh 1
put_ bh (Call aa) = do
- putByte bh 2
- put_ bh aa
+ putByte bh 2
+ put_ bh aa
put_ bh (Eval ab) = do
- putByte bh 3
- put_ bh ab
+ putByte bh 3
+ put_ bh ab
put_ bh (Defer ac) = do
- putByte bh 4
- put_ bh ac
+ putByte bh 4
+ put_ bh ac
put_ bh (Box ad) = do
- putByte bh 5
- put_ bh ad
+ putByte bh 5
+ put_ bh ad
put_ bh Bot = do
- putByte bh 6
+ putByte bh 6
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return Top
- 1 -> do return Abs
- 2 -> do aa <- get bh
- return (Call aa)
- 3 -> do ab <- get bh
- return (Eval ab)
- 4 -> do ac <- get bh
- return (Defer ac)
- 5 -> do ad <- get bh
- return (Box ad)
- _ -> do return Bot
+ h <- getByte bh
+ case h of
+ 0 -> do return Top
+ 1 -> do return Abs
+ 2 -> do aa <- get bh
+ return (Call aa)
+ 3 -> do ab <- get bh
+ return (Eval ab)
+ 4 -> do ac <- get bh
+ return (Defer ac)
+ 5 -> do ad <- get bh
+ return (Box ad)
+ _ -> do return Bot
instance Binary Demands where
put_ bh (Poly aa) = do
- putByte bh 0
- put_ bh aa
+ putByte bh 0
+ put_ bh aa
put_ bh (Prod ab) = do
- putByte bh 1
- put_ bh ab
+ putByte bh 1
+ put_ bh ab
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- return (Poly aa)
- _ -> do ab <- get bh
- return (Prod ab)
+ h <- getByte bh
+ case h of
+ 0 -> do aa <- get bh
+ return (Poly aa)
+ _ -> do ab <- get bh
+ return (Prod ab)
instance Binary DmdResult where
put_ bh TopRes = do
- putByte bh 0
+ putByte bh 0
put_ bh RetCPR = do
- putByte bh 1
+ putByte bh 1
put_ bh BotRes = do
- putByte bh 2
+ putByte bh 2
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return TopRes
- 1 -> do return RetCPR -- Really use RetCPR even if -fcpr-off
- -- The wrapper was generated for CPR in
- -- the imported module!
- _ -> do return BotRes
+ h <- getByte bh
+ case h of
+ 0 -> do return TopRes
+ 1 -> do return RetCPR -- Really use RetCPR even if -fcpr-off
+ -- The wrapper was generated for CPR in
+ -- the imported module!
+ _ -> do return BotRes
instance Binary StrictSig where
put_ bh (StrictSig aa) = do
- put_ bh aa
+ put_ bh aa
get bh = do
- aa <- get bh
- return (StrictSig aa)
+ aa <- get bh
+ return (StrictSig aa)
-------------------------------------------------------------------------
--- Types from: CostCentre
+-- Types from: CostCentre
-------------------------------------------------------------------------
instance Binary IsCafCC where
put_ bh CafCC = do
- putByte bh 0
+ putByte bh 0
put_ bh NotCafCC = do
- putByte bh 1
+ putByte bh 1
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return CafCC
- _ -> do return NotCafCC
+ h <- getByte bh
+ case h of
+ 0 -> do return CafCC
+ _ -> do return NotCafCC
instance Binary CostCentre where
put_ bh NoCostCentre = do
- putByte bh 0
+ putByte bh 0
put_ bh (NormalCC aa ab ac) = do
- putByte bh 1
- put_ bh aa
- put_ bh ab
- put_ bh ac
+ putByte bh 1
+ put_ bh aa
+ put_ bh ab
+ put_ bh ac
put_ bh (AllCafsCC ae) = do
- putByte bh 2
- put_ bh ae
+ putByte bh 2
+ put_ bh ae
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return NoCostCentre
- 1 -> do aa <- get bh
- ab <- get bh
- ac <- get bh
+ h <- getByte bh
+ case h of
+ 0 -> do return NoCostCentre
+ 1 -> do aa <- get bh
+ ab <- get bh
+ ac <- get bh
return (NormalCC aa ab ac)
- _ -> do ae <- get bh
- return (AllCafsCC ae)
+ _ -> do ae <- get bh
+ return (AllCafsCC ae)
-------------------------------------------------------------------------
--- IfaceTypes and friends
+-- IfaceTypes and friends
-------------------------------------------------------------------------
instance Binary IfaceBndr where
put_ bh (IfaceIdBndr aa) = do
- putByte bh 0
- put_ bh aa
+ putByte bh 0
+ put_ bh aa
put_ bh (IfaceTvBndr ab) = do
- putByte bh 1
- put_ bh ab
+ putByte bh 1
+ put_ bh ab
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- return (IfaceIdBndr aa)
- _ -> do ab <- get bh
- return (IfaceTvBndr ab)
+ h <- getByte bh
+ case h of
+ 0 -> do aa <- get bh
+ return (IfaceIdBndr aa)
+ _ -> do ab <- get bh
+ return (IfaceTvBndr ab)
instance Binary IfaceLetBndr where
put_ bh (IfLetBndr a b c) = do
- put_ bh a
- put_ bh b
- put_ bh c
+ put_ bh a
+ put_ bh b
+ put_ bh c
get bh = do a <- get bh
- b <- get bh
- c <- get bh
- return (IfLetBndr a b c)
+ b <- get bh
+ c <- get bh
+ return (IfLetBndr a b c)
instance Binary IfaceType where
put_ bh (IfaceForAllTy aa ab) = do
- putByte bh 0
- put_ bh aa
- put_ bh ab
+ putByte bh 0
+ put_ bh aa
+ put_ bh ab
put_ bh (IfaceTyVar ad) = do
- putByte bh 1
- put_ bh ad
+ putByte bh 1
+ put_ bh ad
put_ bh (IfaceAppTy ae af) = do
- putByte bh 2
- put_ bh ae
- put_ bh af
+ putByte bh 2
+ put_ bh ae
+ put_ bh af
put_ bh (IfaceFunTy ag ah) = do
- putByte bh 3
- put_ bh ag
- put_ bh ah
+ putByte bh 3
+ put_ bh ag
+ put_ bh ah
- -- Simple compression for common cases of TyConApp
- put_ bh (IfaceTyConApp (IfaceAnyTc k) []) = do { putByte bh 4; put_ bh k }
- put_ bh (IfaceTyConApp (IfaceTc tc) tys) = do { putByte bh 5; put_ bh tc; put_ bh tys }
- put_ bh (IfaceTyConApp tc tys) = do { putByte bh 6; put_ bh tc; put_ bh tys }
-
- put_ bh (IfaceCoConApp cc tys) = do { putByte bh 7; put_ bh cc; put_ bh tys }
+ -- Simple compression for common cases of TyConApp
+ put_ bh (IfaceTyConApp IfaceIntTc []) = putByte bh 6
+ put_ bh (IfaceTyConApp IfaceCharTc []) = putByte bh 7
+ put_ bh (IfaceTyConApp IfaceBoolTc []) = putByte bh 8
+ put_ bh (IfaceTyConApp IfaceListTc [ty]) = do { putByte bh 9; put_ bh ty }
+ -- Unit tuple and pairs
+ put_ bh (IfaceTyConApp (IfaceTupTc BoxedTuple 0) []) = putByte bh 10
+ put_ bh (IfaceTyConApp (IfaceTupTc BoxedTuple 2) [t1,t2])
+ = do { putByte bh 11; put_ bh t1; put_ bh t2 }
+ -- Kind cases
+ put_ bh (IfaceTyConApp IfaceLiftedTypeKindTc []) = putByte bh 12
+ put_ bh (IfaceTyConApp IfaceOpenTypeKindTc []) = putByte bh 13
+ put_ bh (IfaceTyConApp IfaceUnliftedTypeKindTc []) = putByte bh 14
+ put_ bh (IfaceTyConApp IfaceUbxTupleKindTc []) = putByte bh 15
+ put_ bh (IfaceTyConApp IfaceArgTypeKindTc []) = putByte bh 16
+ put_ bh (IfaceTyConApp IfaceConstraintKindTc []) = putByte bh 17
+ put_ bh (IfaceTyConApp IfaceSuperKindTc []) = putByte bh 18
+
+ put_ bh (IfaceCoConApp cc tys)
+ = do { putByte bh 19; put_ bh cc; put_ bh tys }
+
+ -- Generic cases
+ put_ bh (IfaceTyConApp (IfaceTc tc) tys)
+ = do { putByte bh 20; put_ bh tc; put_ bh tys }
+ put_ bh (IfaceTyConApp tc tys)
+ = do { putByte bh 21; put_ bh tc; put_ bh tys }
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- ab <- get bh
- return (IfaceForAllTy aa ab)
- 1 -> do ad <- get bh
- return (IfaceTyVar ad)
- 2 -> do ae <- get bh
- af <- get bh
- return (IfaceAppTy ae af)
- 3 -> do ag <- get bh
- ah <- get bh
- return (IfaceFunTy ag ah)
- 4 -> do { k <- get bh; return (IfaceTyConApp (IfaceAnyTc k) []) }
- 5 -> do { tc <- get bh; tys <- get bh; return (IfaceTyConApp (IfaceTc tc) tys) }
- 6 -> do { tc <- get bh; tys <- get bh; return (IfaceTyConApp tc tys) }
- _ -> do { cc <- get bh; tys <- get bh; return (IfaceCoConApp cc tys) }
+ h <- getByte bh
+ case h of
+ 0 -> do aa <- get bh
+ ab <- get bh
+ return (IfaceForAllTy aa ab)
+ 1 -> do ad <- get bh
+ return (IfaceTyVar ad)
+ 2 -> do ae <- get bh
+ af <- get bh
+ return (IfaceAppTy ae af)
+ 3 -> do ag <- get bh
+ ah <- get bh
+ return (IfaceFunTy ag ah)
+
+ -- Now the special cases for TyConApp
+ 6 -> return (IfaceTyConApp IfaceIntTc [])
+ 7 -> return (IfaceTyConApp IfaceCharTc [])
+ 8 -> return (IfaceTyConApp IfaceBoolTc [])
+ 9 -> do { ty <- get bh; return (IfaceTyConApp IfaceListTc [ty]) }
+ 10 -> return (IfaceTyConApp (IfaceTupTc BoxedTuple 0) [])
+ 11 -> do { t1 <- get bh; t2 <- get bh
+ ; return (IfaceTyConApp (IfaceTupTc BoxedTuple 2) [t1,t2]) }
+ 12 -> return (IfaceTyConApp IfaceLiftedTypeKindTc [])
+ 13 -> return (IfaceTyConApp IfaceOpenTypeKindTc [])
+ 14 -> return (IfaceTyConApp IfaceUnliftedTypeKindTc [])
+ 15 -> return (IfaceTyConApp IfaceUbxTupleKindTc [])
+ 16 -> return (IfaceTyConApp IfaceArgTypeKindTc [])
+ 17 -> return (IfaceTyConApp IfaceConstraintKindTc [])
+ 18 -> return (IfaceTyConApp IfaceSuperKindTc [])
+
+ 19 -> do { cc <- get bh; tys <- get bh
+ ; return (IfaceCoConApp cc tys) }
+
+ 20 -> do { tc <- get bh; tys <- get bh
+ ; return (IfaceTyConApp (IfaceTc tc) tys) }
+ 21 -> do { tc <- get bh; tys <- get bh
+ ; return (IfaceTyConApp tc tys) }
+
+ _ -> panic ("get IfaceType " ++ show h)
instance Binary IfaceTyCon where
- put_ bh (IfaceTc ext) = do { putByte bh 1; put_ bh ext }
- put_ bh (IfaceAnyTc k) = do { putByte bh 2; put_ bh k }
+ -- Int,Char,Bool can't show up here because they can't not be saturated
+ put_ bh IfaceIntTc = putByte bh 1
+ put_ bh IfaceBoolTc = putByte bh 2
+ put_ bh IfaceCharTc = putByte bh 3
+ put_ bh IfaceListTc = putByte bh 4
+ put_ bh IfacePArrTc = putByte bh 5
+ put_ bh IfaceLiftedTypeKindTc = putByte bh 6
+ put_ bh IfaceOpenTypeKindTc = putByte bh 7
+ put_ bh IfaceUnliftedTypeKindTc = putByte bh 8
+ put_ bh IfaceUbxTupleKindTc = putByte bh 9
+ put_ bh IfaceArgTypeKindTc = putByte bh 10
+ put_ bh IfaceConstraintKindTc = putByte bh 11
+ put_ bh IfaceSuperKindTc = putByte bh 12
+ put_ bh (IfaceTupTc bx ar) = do { putByte bh 13; put_ bh bx; put_ bh ar }
+ put_ bh (IfaceTc ext) = do { putByte bh 14; put_ bh ext }
+ put_ bh (IfaceIPTc n) = do { putByte bh 15; put_ bh n }
get bh = do
- h <- getByte bh
- case h of
- 1 -> do { ext <- get bh; return (IfaceTc ext) }
- _ -> do { k <- get bh; return (IfaceAnyTc k) }
+ h <- getByte bh
+ case h of
+ 1 -> return IfaceIntTc
+ 2 -> return IfaceBoolTc
+ 3 -> return IfaceCharTc
+ 4 -> return IfaceListTc
+ 5 -> return IfacePArrTc
+ 6 -> return IfaceLiftedTypeKindTc
+ 7 -> return IfaceOpenTypeKindTc
+ 8 -> return IfaceUnliftedTypeKindTc
+ 9 -> return IfaceUbxTupleKindTc
+ 10 -> return IfaceArgTypeKindTc
+ 11 -> return IfaceConstraintKindTc
+ 12 -> return IfaceSuperKindTc
+ 13 -> do { bx <- get bh; ar <- get bh; return (IfaceTupTc bx ar) }
+ 14 -> do { ext <- get bh; return (IfaceTc ext) }
+ 15 -> do { n <- get bh; return (IfaceIPTc n) }
+ _ -> panic ("get IfaceTyCon " ++ show h)
instance Binary IfaceCoCon where
put_ bh (IfaceCoAx n) = do { putByte bh 0; put_ bh n }
@@ -1054,273 +1122,241 @@ instance Binary IfaceCoCon where
put_ bh (IfaceIPCoAx ip) = do { putByte bh 7; put_ bh ip }
get bh = do
- h <- getByte bh
- case h of
+ h <- getByte bh
+ case h of
0 -> do { n <- get bh; return (IfaceCoAx n) }
- 1 -> return IfaceReflCo
- 2 -> return IfaceUnsafeCo
- 3 -> return IfaceSymCo
- 4 -> return IfaceTransCo
- 5 -> return IfaceInstCo
+ 1 -> return IfaceReflCo
+ 2 -> return IfaceUnsafeCo
+ 3 -> return IfaceSymCo
+ 4 -> return IfaceTransCo
+ 5 -> return IfaceInstCo
6 -> do { d <- get bh; return (IfaceNthCo d) }
- _ -> do { ip <- get bh; return (IfaceIPCoAx ip) }
+ 7 -> do { ip <- get bh; return (IfaceIPCoAx ip) }
+ _ -> panic ("get IfaceCoCon " ++ show h)
-------------------------------------------------------------------------
--- IfaceExpr and friends
+-- IfaceExpr and friends
-------------------------------------------------------------------------
instance Binary IfaceExpr where
put_ bh (IfaceLcl aa) = do
- putByte bh 0
- put_ bh aa
+ putByte bh 0
+ put_ bh aa
put_ bh (IfaceType ab) = do
- putByte bh 1
- put_ bh ab
+ putByte bh 1
+ put_ bh ab
put_ bh (IfaceCo ab) = do
- putByte bh 2
- put_ bh ab
+ putByte bh 2
+ put_ bh ab
put_ bh (IfaceTuple ac ad) = do
- putByte bh 3
- put_ bh ac
- put_ bh ad
+ putByte bh 3
+ put_ bh ac
+ put_ bh ad
put_ bh (IfaceLam ae af) = do
- putByte bh 4
- put_ bh ae
- put_ bh af
+ putByte bh 4
+ put_ bh ae
+ put_ bh af
put_ bh (IfaceApp ag ah) = do
- putByte bh 5
- put_ bh ag
- put_ bh ah
+ putByte bh 5
+ put_ bh ag
+ put_ bh ah
put_ bh (IfaceCase ai aj ak) = do
- putByte bh 6
- put_ bh ai
- put_ bh aj
- put_ bh ak
+ putByte bh 6
+ put_ bh ai
+ put_ bh aj
+ put_ bh ak
put_ bh (IfaceLet al am) = do
- putByte bh 7
- put_ bh al
- put_ bh am
+ putByte bh 7
+ put_ bh al
+ put_ bh am
put_ bh (IfaceTick an ao) = do
- putByte bh 8
- put_ bh an
- put_ bh ao
+ putByte bh 8
+ put_ bh an
+ put_ bh ao
put_ bh (IfaceLit ap) = do
- putByte bh 9
- put_ bh ap
+ putByte bh 9
+ put_ bh ap
put_ bh (IfaceFCall as at) = do
- putByte bh 10
- put_ bh as
- put_ bh at
+ putByte bh 10
+ put_ bh as
+ put_ bh at
put_ bh (IfaceExt aa) = do
- putByte bh 11
- put_ bh aa
+ putByte bh 11
+ put_ bh aa
put_ bh (IfaceCast ie ico) = do
- putByte bh 12
- put_ bh ie
- put_ bh ico
+ putByte bh 12
+ put_ bh ie
+ put_ bh ico
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- return (IfaceLcl aa)
- 1 -> do ab <- get bh
- return (IfaceType ab)
- 2 -> do ab <- get bh
- return (IfaceCo ab)
- 3 -> do ac <- get bh
- ad <- get bh
- return (IfaceTuple ac ad)
- 4 -> do ae <- get bh
- af <- get bh
- return (IfaceLam ae af)
- 5 -> do ag <- get bh
- ah <- get bh
- return (IfaceApp ag ah)
- 6 -> do ai <- get bh
- aj <- get bh
- ak <- get bh
- return (IfaceCase ai aj ak)
- 7 -> do al <- get bh
- am <- get bh
- return (IfaceLet al am)
- 8 -> do an <- get bh
- ao <- get bh
- return (IfaceTick an ao)
- 9 -> do ap <- get bh
- return (IfaceLit ap)
- 10 -> do as <- get bh
- at <- get bh
- return (IfaceFCall as at)
- 11 -> do aa <- get bh
- return (IfaceExt aa)
- 12 -> do ie <- get bh
- ico <- get bh
- return (IfaceCast ie ico)
- _ -> panic ("get IfaceExpr " ++ show h)
+ h <- getByte bh
+ case h of
+ 0 -> do aa <- get bh
+ return (IfaceLcl aa)
+ 1 -> do ab <- get bh
+ return (IfaceType ab)
+ 2 -> do ab <- get bh
+ return (IfaceCo ab)
+ 3 -> do ac <- get bh
+ ad <- get bh
+ return (IfaceTuple ac ad)
+ 4 -> do ae <- get bh
+ af <- get bh
+ return (IfaceLam ae af)
+ 5 -> do ag <- get bh
+ ah <- get bh
+ return (IfaceApp ag ah)
+ 6 -> do ai <- get bh
+ aj <- get bh
+ ak <- get bh
+ return (IfaceCase ai aj ak)
+ 7 -> do al <- get bh
+ am <- get bh
+ return (IfaceLet al am)
+ 8 -> do an <- get bh
+ ao <- get bh
+ return (IfaceTick an ao)
+ 9 -> do ap <- get bh
+ return (IfaceLit ap)
+ 10 -> do as <- get bh
+ at <- get bh
+ return (IfaceFCall as at)
+ 11 -> do aa <- get bh
+ return (IfaceExt aa)
+ 12 -> do ie <- get bh
+ ico <- get bh
+ return (IfaceCast ie ico)
+ _ -> panic ("get IfaceExpr " ++ show h)
instance Binary IfaceConAlt where
- put_ bh IfaceDefault = do
- putByte bh 0
- put_ bh (IfaceDataAlt aa) = do
- putByte bh 1
- put_ bh aa
- put_ bh (IfaceLitAlt ac) = do
- putByte bh 2
- put_ bh ac
+ put_ bh IfaceDefault = putByte bh 0
+ put_ bh (IfaceDataAlt aa) = putByte bh 1 >> put_ bh aa
+ put_ bh (IfaceLitAlt ac) = putByte bh 2 >> put_ bh ac
get bh = do
- h <- getByte bh
- case h of
- 0 -> do return IfaceDefault
- 1 -> do aa <- get bh
- return (IfaceDataAlt aa)
- _ -> do ac <- get bh
- return (IfaceLitAlt ac)
+ h <- getByte bh
+ case h of
+ 0 -> return IfaceDefault
+ 1 -> get bh >>= (return . IfaceDataAlt)
+ _ -> get bh >>= (return . IfaceLitAlt)
instance Binary IfaceBinding where
- put_ bh (IfaceNonRec aa ab) = do
- putByte bh 0
- put_ bh aa
- put_ bh ab
- put_ bh (IfaceRec ac) = do
- putByte bh 1
- put_ bh ac
+ put_ bh (IfaceNonRec aa ab) = putByte bh 0 >> put_ bh aa >> put_ bh ab
+ put_ bh (IfaceRec ac) = putByte bh 1 >> put_ bh ac
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- ab <- get bh
- return (IfaceNonRec aa ab)
- _ -> do ac <- get bh
- return (IfaceRec ac)
+ h <- getByte bh
+ case h of
+ 0 -> do { aa <- get bh; ab <- get bh; return (IfaceNonRec aa ab) }
+ _ -> do { ac <- get bh; return (IfaceRec ac) }
instance Binary IfaceIdDetails where
put_ bh IfVanillaId = putByte bh 0
- put_ bh (IfRecSelId a b) = do { putByte bh 1; put_ bh a; put_ bh b }
+ put_ bh (IfRecSelId a b) = putByte bh 1 >> put_ bh a >> put_ bh b
put_ bh IfDFunId = putByte bh 2
get bh = do
- h <- getByte bh
- case h of
- 0 -> return IfVanillaId
- 1 -> do a <- get bh
- b <- get bh
- return (IfRecSelId a b)
- _ -> return IfDFunId
+ h <- getByte bh
+ case h of
+ 0 -> return IfVanillaId
+ 1 -> do { a <- get bh; b <- get bh; return (IfRecSelId a b) }
+ _ -> return IfDFunId
instance Binary IfaceIdInfo where
- put_ bh NoInfo = putByte bh 0
- put_ bh (HasInfo i) = do
- putByte bh 1
- lazyPut bh i -- NB lazyPut
+ put_ bh NoInfo = putByte bh 0
+ put_ bh (HasInfo i) = putByte bh 1 >> lazyPut bh i -- NB lazyPut
get bh = do
- h <- getByte bh
- case h of
- 0 -> return NoInfo
- _ -> do info <- lazyGet bh -- NB lazyGet
- return (HasInfo info)
+ h <- getByte bh
+ case h of
+ 0 -> return NoInfo
+ _ -> lazyGet bh >>= (return . HasInfo) -- NB lazyGet
instance Binary IfaceInfoItem where
- put_ bh (HsArity aa) = do
- putByte bh 0
- put_ bh aa
- put_ bh (HsStrictness ab) = do
- putByte bh 1
- put_ bh ab
- put_ bh (HsUnfold lb ad) = do
- putByte bh 2
- put_ bh lb
- put_ bh ad
- put_ bh (HsInline ad) = do
- putByte bh 3
- put_ bh ad
- put_ bh HsNoCafRefs = do
- putByte bh 4
+ put_ bh (HsArity aa) = putByte bh 0 >> put_ bh aa
+ put_ bh (HsStrictness ab) = putByte bh 1 >> put_ bh ab
+ put_ bh (HsUnfold lb ad) = putByte bh 2 >> put_ bh lb >> put_ bh ad
+ put_ bh (HsInline ad) = putByte bh 3 >> put_ bh ad
+ put_ bh HsNoCafRefs = putByte bh 4
get bh = do
- h <- getByte bh
- case h of
- 0 -> do aa <- get bh
- return (HsArity aa)
- 1 -> do ab <- get bh
- return (HsStrictness ab)
- 2 -> do lb <- get bh
- ad <- get bh
- return (HsUnfold lb ad)
- 3 -> do ad <- get bh
- return (HsInline ad)
- _ -> do return HsNoCafRefs
+ h <- getByte bh
+ case h of
+ 0 -> get bh >>= (return . HsArity)
+ 1 -> get bh >>= (return . HsStrictness)
+ 2 -> do lb <- get bh
+ ad <- get bh
+ return (HsUnfold lb ad)
+ 3 -> get bh >>= (return . HsInline)
+ _ -> return HsNoCafRefs
instance Binary IfaceUnfolding where
put_ bh (IfCoreUnfold s e) = do
- putByte bh 0
- put_ bh s
- put_ bh e
+ putByte bh 0
+ put_ bh s
+ put_ bh e
put_ bh (IfInlineRule a b c d) = do
- putByte bh 1
- put_ bh a
- put_ bh b
- put_ bh c
- put_ bh d
+ putByte bh 1
+ put_ bh a
+ put_ bh b
+ put_ bh c
+ put_ bh d
put_ bh (IfLclWrapper a n) = do
- putByte bh 2
- put_ bh a
- put_ bh n
+ putByte bh 2
+ put_ bh a
+ put_ bh n
put_ bh (IfExtWrapper a n) = do
- putByte bh 3
- put_ bh a
- put_ bh n
+ putByte bh 3
+ put_ bh a
+ put_ bh n
put_ bh (IfDFunUnfold as) = do
- putByte bh 4
- put_ bh as
+ putByte bh 4
+ put_ bh as
put_ bh (IfCompulsory e) = do
- putByte bh 5
- put_ bh e
+ putByte bh 5
+ put_ bh e
get bh = do
- h <- getByte bh
- case h of
- 0 -> do s <- get bh
- e <- get bh
- return (IfCoreUnfold s e)
- 1 -> do a <- get bh
- b <- get bh
- c <- get bh
- d <- get bh
- return (IfInlineRule a b c d)
- 2 -> do a <- get bh
- n <- get bh
- return (IfLclWrapper a n)
- 3 -> do a <- get bh
- n <- get bh
- return (IfExtWrapper a n)
- 4 -> do as <- get bh
- return (IfDFunUnfold as)
- _ -> do e <- get bh
- return (IfCompulsory e)
+ h <- getByte bh
+ case h of
+ 0 -> do s <- get bh
+ e <- get bh
+ return (IfCoreUnfold s e)
+ 1 -> do a <- get bh
+ b <- get bh
+ c <- get bh
+ d <- get bh
+ return (IfInlineRule a b c d)
+ 2 -> do a <- get bh
+ n <- get bh
+ return (IfLclWrapper a n)
+ 3 -> do a <- get bh
+ n <- get bh
+ return (IfExtWrapper a n)
+ 4 -> do as <- get bh
+ return (IfDFunUnfold as)
+ _ -> do e <- get bh
+ return (IfCompulsory e)
instance Binary IfaceTickish where
put_ bh (IfaceHpcTick m ix) = do
- putByte bh 0
- put_ bh m
- put_ bh ix
+ putByte bh 0
+ put_ bh m
+ put_ bh ix
put_ bh (IfaceSCC cc tick push) = do
- putByte bh 1
- put_ bh cc
- put_ bh tick
- put_ bh push
+ putByte bh 1
+ put_ bh cc
+ put_ bh tick
+ put_ bh push
get bh = do
- h <- getByte bh
- case h of
- 0 -> do m <- get bh
- ix <- get bh
- return (IfaceHpcTick m ix)
- 1 -> do cc <- get bh
- tick <- get bh
- push <- get bh
- return (IfaceSCC cc tick push)
- _ -> panic ("get IfaceTickish " ++ show h)
+ h <- getByte bh
+ case h of
+ 0 -> do m <- get bh
+ ix <- get bh
+ return (IfaceHpcTick m ix)
+ 1 -> do cc <- get bh
+ tick <- get bh
+ push <- get bh
+ return (IfaceSCC cc tick push)
+ _ -> panic ("get IfaceTickish " ++ show h)
-------------------------------------------------------------------------
--- IfaceDecl and friends
+-- IfaceDecl and friends
-------------------------------------------------------------------------
-- A bit of magic going on here: there's no need to store the OccName
@@ -1331,161 +1367,164 @@ instance Binary IfaceTickish where
instance Binary IfaceDecl where
put_ bh (IfaceId name ty details idinfo) = do
- putByte bh 0
- put_ bh (occNameFS name)
- put_ bh ty
- put_ bh details
- put_ bh idinfo
+ putByte bh 0
+ put_ bh (occNameFS name)
+ put_ bh ty
+ put_ bh details
+ put_ bh idinfo
+
put_ _ (IfaceForeign _ _) =
- error "Binary.put_(IfaceDecl): IfaceForeign"
+ error "Binary.put_(IfaceDecl): IfaceForeign"
+
put_ bh (IfaceData a1 a2 a3 a4 a5 a6 a7) = do
- putByte bh 2
- put_ bh (occNameFS a1)
- put_ bh a2
- put_ bh a3
- put_ bh a4
- put_ bh a5
- put_ bh a6
- put_ bh a7
+ putByte bh 2
+ put_ bh (occNameFS a1)
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
+ put_ bh a6
+ put_ bh a7
+
put_ bh (IfaceSyn a1 a2 a3 a4 a5) = do
- putByte bh 3
- put_ bh (occNameFS a1)
- put_ bh a2
- put_ bh a3
- put_ bh a4
- put_ bh a5
+ putByte bh 3
+ put_ bh (occNameFS a1)
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
+
put_ bh (IfaceClass a1 a2 a3 a4 a5 a6 a7) = do
- putByte bh 4
- put_ bh a1
- put_ bh (occNameFS a2)
- put_ bh a3
- put_ bh a4
- put_ bh a5
- put_ bh a6
- put_ bh a7
+ putByte bh 4
+ put_ bh a1
+ put_ bh (occNameFS a2)
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
+ put_ bh a6
+ put_ bh a7
+
get bh = do
- h <- getByte bh
- case h of
- 0 -> do name <- get bh
- ty <- get bh
- details <- get bh
- idinfo <- get bh
- occ <- return $! mkOccNameFS varName name
- return (IfaceId occ ty details idinfo)
- 1 -> error "Binary.get(TyClDecl): ForeignType"
- 2 -> do
- a1 <- get bh
- a2 <- get bh
- a3 <- get bh
- a4 <- get bh
- a5 <- get bh
- a6 <- get bh
- a7 <- get bh
+ h <- getByte bh
+ case h of
+ 0 -> do name <- get bh
+ ty <- get bh
+ details <- get bh
+ idinfo <- get bh
+ occ <- return $! mkOccNameFS varName name
+ return (IfaceId occ ty details idinfo)
+ 1 -> error "Binary.get(TyClDecl): ForeignType"
+ 2 -> do a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
+ a6 <- get bh
+ a7 <- get bh
occ <- return $! mkOccNameFS tcName a1
- return (IfaceData occ a2 a3 a4 a5 a6 a7)
- 3 -> do
- a1 <- get bh
- a2 <- get bh
- a3 <- get bh
- a4 <- get bh
- a5 <- get bh
+ return (IfaceData occ a2 a3 a4 a5 a6 a7)
+ 3 -> do a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
occ <- return $! mkOccNameFS tcName a1
- return (IfaceSyn occ a2 a3 a4 a5)
- _ -> do
- a1 <- get bh
- a2 <- get bh
- a3 <- get bh
- a4 <- get bh
- a5 <- get bh
- a6 <- get bh
- a7 <- get bh
+ return (IfaceSyn occ a2 a3 a4 a5)
+ _ -> do a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
+ a6 <- get bh
+ a7 <- get bh
occ <- return $! mkOccNameFS clsName a2
- return (IfaceClass a1 occ a3 a4 a5 a6 a7)
+ return (IfaceClass a1 occ a3 a4 a5 a6 a7)
instance Binary IfaceInst where
put_ bh (IfaceInst cls tys dfun flag orph) = do
- put_ bh cls
- put_ bh tys
- put_ bh dfun
- put_ bh flag
- put_ bh orph
- get bh = do cls <- get bh
- tys <- get bh
- dfun <- get bh
- flag <- get bh
- orph <- get bh
- return (IfaceInst cls tys dfun flag orph)
+ put_ bh cls
+ put_ bh tys
+ put_ bh dfun
+ put_ bh flag
+ put_ bh orph
+ get bh = do
+ cls <- get bh
+ tys <- get bh
+ dfun <- get bh
+ flag <- get bh
+ orph <- get bh
+ return (IfaceInst cls tys dfun flag orph)
instance Binary IfaceFamInst where
put_ bh (IfaceFamInst fam tys tycon) = do
- put_ bh fam
- put_ bh tys
- put_ bh tycon
- get bh = do fam <- get bh
- tys <- get bh
- tycon <- get bh
- return (IfaceFamInst fam tys tycon)
+ put_ bh fam
+ put_ bh tys
+ put_ bh tycon
+ get bh = do
+ fam <- get bh
+ tys <- get bh
+ tycon <- get bh
+ return (IfaceFamInst fam tys tycon)
instance Binary OverlapFlag where
put_ bh (NoOverlap b) = putByte bh 0 >> put_ bh b
put_ bh (OverlapOk b) = putByte bh 1 >> put_ bh b
put_ bh (Incoherent b) = putByte bh 2 >> put_ bh b
- get bh = do h <- getByte bh
- b <- get bh
- case h of
- 0 -> return $ NoOverlap b
- 1 -> return $ OverlapOk b
- 2 -> return $ Incoherent b
- _ -> panic ("get OverlapFlag " ++ show h)
+ get bh = do
+ h <- getByte bh
+ b <- get bh
+ case h of
+ 0 -> return $ NoOverlap b
+ 1 -> return $ OverlapOk b
+ 2 -> return $ Incoherent b
+ _ -> panic ("get OverlapFlag " ++ show h)
instance Binary IfaceConDecls where
- put_ bh (IfAbstractTyCon d) = do { putByte bh 0; put_ bh d }
- put_ bh IfOpenDataTyCon = putByte bh 1
- put_ bh (IfDataTyCon cs) = do { putByte bh 2
- ; put_ bh cs }
- put_ bh (IfNewTyCon c) = do { putByte bh 3
- ; put_ bh c }
+ put_ bh (IfAbstractTyCon d) = putByte bh 0 >> put_ bh d
+ put_ bh IfOpenDataTyCon = putByte bh 1
+ put_ bh (IfDataTyCon cs) = putByte bh 2 >> put_ bh cs
+ put_ bh (IfNewTyCon c) = putByte bh 3 >> put_ bh c
get bh = do
- h <- getByte bh
- case h of
- 0 -> do { d <- get bh; return (IfAbstractTyCon d) }
- 1 -> return IfOpenDataTyCon
- 2 -> do cs <- get bh
- return (IfDataTyCon cs)
- _ -> do aa <- get bh
- return (IfNewTyCon aa)
+ h <- getByte bh
+ case h of
+ 0 -> get bh >>= (return . IfAbstractTyCon)
+ 1 -> return IfOpenDataTyCon
+ 2 -> get bh >>= (return . IfDataTyCon)
+ _ -> get bh >>= (return . IfNewTyCon)
instance Binary IfaceConDecl where
put_ bh (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) = do
- put_ bh a1
- put_ bh a2
- put_ bh a3
- put_ bh a4
- put_ bh a5
- put_ bh a6
- put_ bh a7
- put_ bh a8
- put_ bh a9
- put_ bh a10
- get bh = do a1 <- get bh
- a2 <- get bh
- a3 <- get bh
- a4 <- get bh
- a5 <- get bh
- a6 <- get bh
- a7 <- get bh
- a8 <- get bh
- a9 <- get bh
- a10 <- get bh
- return (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)
+ put_ bh a1
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
+ put_ bh a6
+ put_ bh a7
+ put_ bh a8
+ put_ bh a9
+ put_ bh a10
+ get bh = do
+ a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
+ a6 <- get bh
+ a7 <- get bh
+ a8 <- get bh
+ a9 <- get bh
+ a10 <- get bh
+ return (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10)
instance Binary IfaceAT where
put_ bh (IfaceAT dec defs) = do
- put_ bh dec
- put_ bh defs
- get bh = do dec <- get bh
- defs <- get bh
- return (IfaceAT dec defs)
+ put_ bh dec
+ put_ bh defs
+ get bh = do
+ dec <- get bh
+ defs <- get bh
+ return (IfaceAT dec defs)
instance Binary IfaceATDefault where
put_ bh (IfaceATD tvs pat_tys ty) = do
@@ -1495,37 +1534,37 @@ instance Binary IfaceATDefault where
get bh = liftM3 IfaceATD (get bh) (get bh) (get bh)
instance Binary IfaceClassOp where
- put_ bh (IfaceClassOp n def ty) = do
- put_ bh (occNameFS n)
- put_ bh def
- put_ bh ty
- get bh = do
- n <- get bh
- def <- get bh
- ty <- get bh
+ put_ bh (IfaceClassOp n def ty) = do
+ put_ bh (occNameFS n)
+ put_ bh def
+ put_ bh ty
+ get bh = do
+ n <- get bh
+ def <- get bh
+ ty <- get bh
occ <- return $! mkOccNameFS varName n
- return (IfaceClassOp occ def ty)
+ return (IfaceClassOp occ def ty)
instance Binary IfaceRule where
put_ bh (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8) = do
- put_ bh a1
- put_ bh a2
- put_ bh a3
- put_ bh a4
- put_ bh a5
- put_ bh a6
- put_ bh a7
- put_ bh a8
+ put_ bh a1
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
+ put_ bh a6
+ put_ bh a7
+ put_ bh a8
get bh = do
- a1 <- get bh
- a2 <- get bh
- a3 <- get bh
- a4 <- get bh
- a5 <- get bh
- a6 <- get bh
- a7 <- get bh
- a8 <- get bh
- return (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8)
+ a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
+ a6 <- get bh
+ a7 <- get bh
+ a8 <- get bh
+ return (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8)
instance Binary IfaceAnnotation where
put_ bh (IfaceAnnotation a1 a2) = do
@@ -1546,25 +1585,23 @@ instance Binary name => Binary (AnnTarget name) where
get bh = do
h <- getByte bh
case h of
- 0 -> do a <- get bh
- return (NamedTarget a)
- _ -> do a <- get bh
- return (ModuleTarget a)
+ 0 -> get bh >>= (return . NamedTarget)
+ _ -> get bh >>= (return . ModuleTarget)
instance Binary IfaceVectInfo where
put_ bh (IfaceVectInfo a1 a2 a3 a4 a5) = do
- put_ bh a1
- put_ bh a2
- put_ bh a3
- put_ bh a4
- put_ bh a5
+ put_ bh a1
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
get bh = do
- a1 <- get bh
- a2 <- get bh
- a3 <- get bh
- a4 <- get bh
- a5 <- get bh
- return (IfaceVectInfo a1 a2 a3 a4 a5)
+ a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
+ return (IfaceVectInfo a1 a2 a3 a4 a5)
instance Binary IfaceTrustInfo where
put_ bh iftrust = putByte bh $ trustInfoToNum iftrust
diff --git a/compiler/iface/BuildTyCl.lhs b/compiler/iface/BuildTyCl.lhs
index 348da8c6c4..9d4a825586 100644
--- a/compiler/iface/BuildTyCl.lhs
+++ b/compiler/iface/BuildTyCl.lhs
@@ -15,6 +15,7 @@ module BuildTyCl (
buildSynTyCon,
buildAlgTyCon,
buildDataCon,
+ buildPromotedDataTyCon,
TcMethInfo, buildClass,
distinctAbstractTyConRhs, totallyAbstractTyConRhs,
mkNewTyConRhs, mkDataTyConRhs,
@@ -34,11 +35,13 @@ import MkId
import Class
import TyCon
import Type
+import Kind ( promoteType, isPromotableType )
import Coercion
import TcRnMonad
import Util ( isSingleton )
import Outputable
+import Unique ( getUnique )
\end{code}
@@ -59,11 +62,10 @@ buildSynTyCon tc_name tvs rhs rhs_kind parent mb_family
| otherwise
= return (mkSynTyCon tc_name kind tvs rhs parent)
- where
- kind = mkArrowKinds (map tyVarKind tvs) rhs_kind
+ where kind = mkForAllArrowKinds tvs rhs_kind
------------------------------------------------------
-buildAlgTyCon :: Name -> [TyVar]
+buildAlgTyCon :: Name -> [TyVar] -- ^ Kind variables adn type variables
-> ThetaType -- ^ Stupid theta
-> AlgTyConRhs
-> RecFlag
@@ -72,22 +74,21 @@ buildAlgTyCon :: Name -> [TyVar]
-> Maybe (TyCon, [Type]) -- ^ family instance if applicable
-> TcRnIf m n TyCon
-buildAlgTyCon tc_name tvs stupid_theta rhs is_rec gadt_syn
+buildAlgTyCon tc_name ktvs stupid_theta rhs is_rec gadt_syn
parent mb_family
| Just fam_inst_info <- mb_family
= -- We need to tie a knot as the coercion of a data instance depends
-- on the instance representation tycon and vice versa.
ASSERT( isNoParent parent )
fixM $ \ tycon_rec -> do
- { fam_parent <- mkFamInstParentInfo tc_name tvs fam_inst_info tycon_rec
- ; return (mkAlgTyCon tc_name kind tvs stupid_theta rhs
+ { fam_parent <- mkFamInstParentInfo tc_name ktvs fam_inst_info tycon_rec
+ ; return (mkAlgTyCon tc_name kind ktvs stupid_theta rhs
fam_parent is_rec gadt_syn) }
| otherwise
- = return (mkAlgTyCon tc_name kind tvs stupid_theta rhs
+ = return (mkAlgTyCon tc_name kind ktvs stupid_theta rhs
parent is_rec gadt_syn)
- where
- kind = mkArrowKinds (map tyVarKind tvs) liftedTypeKind
+ where kind = mkForAllArrowKinds ktvs liftedTypeKind
-- | If a family tycon with instance types is given, the current tycon is an
-- instance of that family and we need to
@@ -224,6 +225,11 @@ mkDataConStupidTheta tycon arg_tys univ_tvs
arg_tyvars = tyVarsOfTypes arg_tys
in_arg_tys pred = not $ isEmptyVarSet $
tyVarsOfType pred `intersectVarSet` arg_tyvars
+
+buildPromotedDataTyCon :: DataCon -> TyCon
+buildPromotedDataTyCon dc = ASSERT ( isPromotableType ty )
+ mkPromotedDataTyCon dc (getName dc) (getUnique dc) (promoteType ty)
+ where ty = dataConUserType dc
\end{code}
@@ -301,7 +307,7 @@ buildClass no_unf tycon_name tvs sc_theta fds at_items sig_stuff tc_isrec
then mkNewTyConRhs tycon_name rec_tycon dict_con
else return (mkDataTyConRhs [dict_con])
- ; let { clas_kind = mkArrowKinds (map tyVarKind tvs) constraintKind
+ ; let { clas_kind = mkForAllArrowKinds tvs constraintKind
; tycon = mkClassTyCon tycon_name clas_kind tvs
rhs rec_clas tc_isrec
diff --git a/compiler/iface/FlagChecker.hs b/compiler/iface/FlagChecker.hs
new file mode 100644
index 0000000000..f670437ffe
--- /dev/null
+++ b/compiler/iface/FlagChecker.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE RecordWildCards #-}
+
+-- | This module manages storing the various GHC option flags in a modules
+-- interface file as part of the recompilation checking infrastructure.
+module FlagChecker (
+ fingerprintDynFlags
+ ) where
+
+import Binary
+import BinIface ()
+import DynFlags
+import HscTypes
+import Name
+import Fingerprint
+-- import Outputable
+
+import Data.List (sort)
+import System.FilePath (normalise)
+
+-- | Produce a fingerprint of a @DynFlags@ value. We only base
+-- the finger print on important fields in @DynFlags@ so that
+-- the recompilation checker can use this fingerprint.
+fingerprintDynFlags :: DynFlags -> (BinHandle -> Name -> IO ())
+ -> IO Fingerprint
+
+fingerprintDynFlags DynFlags{..} nameio =
+ let mainis = (mainModIs, mainFunIs)
+ -- pkgopts = (thisPackage dflags, sort $ packageFlags dflags)
+ safeHs = setSafeMode safeHaskell
+ -- oflags = sort $ filter filterOFlags $ flags dflags
+
+ -- *all* the extension flags and the language
+ lang = (fmap fromEnum language,
+ sort $ map fromEnum $ extensionFlags)
+
+ -- -I, -D and -U flags affect CPP
+ cpp = (map normalise includePaths, sOpt_P settings)
+ -- normalise: eliminate spurious differences due to "./foo" vs "foo"
+
+ -- -i, -osuf, -hcsuf, -hisuf, -odir, -hidir, -stubdir, -o, -ohi
+ paths = (map normalise importPaths,
+ [ objectSuf, hcSuf, hiSuf ],
+ [ objectDir, hiDir, stubDir, outputFile, outputHi ])
+
+ in -- pprTrace "flags" (ppr (mainis, safeHs, lang, cpp, paths)) $
+ computeFingerprint nameio (mainis, safeHs, lang, cpp, paths)
+
diff --git a/compiler/iface/IfaceSyn.lhs b/compiler/iface/IfaceSyn.lhs
index deeac37c65..92fb0d9937 100644
--- a/compiler/iface/IfaceSyn.lhs
+++ b/compiler/iface/IfaceSyn.lhs
@@ -500,6 +500,7 @@ pp_condecls tc (IfDataTyCon cs) = equals <+> sep (punctuate (ptext (sLit " |"))
(map (pprIfaceConDecl tc) cs))
mkIfaceEqPred :: IfaceType -> IfaceType -> IfacePredType
+-- IA0_NOTE: This is wrong, but only used for pretty-printing.
mkIfaceEqPred ty1 ty2 = IfaceTyConApp (IfaceTc eqTyConName) [ty1, ty2]
pprIfaceConDecl :: OccName -> IfaceConDecl -> SDoc
@@ -718,7 +719,9 @@ freeNamesIfDecl d@IfaceData{} =
freeNamesIfDecl d@IfaceSyn{} =
freeNamesIfTvBndrs (ifTyVars d) &&&
freeNamesIfSynRhs (ifSynRhs d) &&&
- freeNamesIfTcFam (ifFamInst d)
+ freeNamesIfTcFam (ifFamInst d) &&&
+ freeNamesIfKind (ifSynKind d) -- IA0_NOTE: because of promotion, we
+ -- return names in the kind signature
freeNamesIfDecl d@IfaceClass{} =
freeNamesIfTvBndrs (ifTyVars d) &&&
freeNamesIfContext (ifCtxt d) &&&
@@ -769,6 +772,9 @@ freeNamesIfConDecl c =
fnList freeNamesIfType (ifConArgTys c) &&&
fnList freeNamesIfType (map snd (ifConEqSpec c)) -- equality constraints
+freeNamesIfKind :: IfaceType -> NameSet
+freeNamesIfKind = freeNamesIfType
+
freeNamesIfType :: IfaceType -> NameSet
freeNamesIfType (IfaceTyVar _) = emptyNameSet
freeNamesIfType (IfaceAppTy s t) = freeNamesIfType s &&& freeNamesIfType t
@@ -795,8 +801,8 @@ freeNamesIfLetBndr (IfLetBndr _name ty info) = freeNamesIfType ty
&&& freeNamesIfIdInfo info
freeNamesIfTvBndr :: IfaceTvBndr -> NameSet
-freeNamesIfTvBndr (_fs,k) = freeNamesIfType k
- -- kinds can have Names inside, when the Kind is an equality predicate
+freeNamesIfTvBndr (_fs,k) = freeNamesIfKind k
+ -- kinds can have Names inside, because of promotion
freeNamesIfIdBndr :: IfaceIdBndr -> NameSet
freeNamesIfIdBndr = freeNamesIfTvBndr
diff --git a/compiler/iface/IfaceType.lhs b/compiler/iface/IfaceType.lhs
index 471acd0639..5441287eef 100644
--- a/compiler/iface/IfaceType.lhs
+++ b/compiler/iface/IfaceType.lhs
@@ -21,7 +21,7 @@ module IfaceType (
ifaceTyConName,
-- Conversion from Type -> IfaceType
- toIfaceType, toIfaceContext,
+ toIfaceType, toIfaceKind, toIfaceContext,
toIfaceBndr, toIfaceIdBndr, toIfaceTvBndrs,
toIfaceTyCon, toIfaceTyCon_name,
@@ -87,12 +87,20 @@ data IfaceType -- A kind of universal type, used for types, kinds, and coerci
type IfacePredType = IfaceType
type IfaceContext = [IfacePredType]
-data IfaceTyCon -- Encodes type consructors, kind constructors
- -- coercion constructors, the lot
- = IfaceTc IfExtName -- The common case
- | IfaceAnyTc IfaceKind -- Used for AnyTyCon (see Note [Any Types] in TysPrim)
- -- other than 'Any :: *' itself
- -- XXX: remove this case after Any becomes kind-polymorphic
+data IfaceTyCon -- Encodes type constructors, kind constructors
+ -- coercion constructors, the lot
+ = IfaceTc IfExtName -- The common case
+ | IfaceIntTc | IfaceBoolTc | IfaceCharTc
+ | IfaceListTc | IfacePArrTc
+ | IfaceTupTc TupleSort Arity
+ | IfaceIPTc IfIPName -- Used for implicit parameter TyCons
+
+ -- Kind constructors
+ | IfaceLiftedTypeKindTc | IfaceOpenTypeKindTc | IfaceUnliftedTypeKindTc
+ | IfaceUbxTupleKindTc | IfaceArgTypeKindTc | IfaceConstraintKindTc
+
+ -- SuperKind constructor
+ | IfaceSuperKindTc -- IA0_NOTE: You might want to check if I didn't forget something.
-- Coercion constructors
data IfaceCoCon
@@ -103,13 +111,29 @@ data IfaceCoCon
| IfaceNthCo Int
ifaceTyConName :: IfaceTyCon -> Name
+ifaceTyConName IfaceIntTc = intTyConName
+ifaceTyConName IfaceBoolTc = boolTyConName
+ifaceTyConName IfaceCharTc = charTyConName
+ifaceTyConName IfaceListTc = listTyConName
+ifaceTyConName IfacePArrTc = parrTyConName
+ifaceTyConName (IfaceTupTc bx ar) = getName (tupleTyCon bx ar)
+ifaceTyConName IfaceLiftedTypeKindTc = liftedTypeKindTyConName
+ifaceTyConName IfaceOpenTypeKindTc = openTypeKindTyConName
+ifaceTyConName IfaceUnliftedTypeKindTc = unliftedTypeKindTyConName
+ifaceTyConName IfaceUbxTupleKindTc = ubxTupleKindTyConName
+ifaceTyConName IfaceArgTypeKindTc = argTypeKindTyConName
+ifaceTyConName IfaceConstraintKindTc = constraintKindTyConName
+ifaceTyConName IfaceSuperKindTc = tySuperKindTyConName
ifaceTyConName (IfaceTc ext) = ext
-ifaceTyConName (IfaceAnyTc k) = pprPanic "ifaceTyConName:AnyTc" (ppr k)
+ifaceTyConName (IfaceIPTc n) = pprPanic "ifaceTyConName:IPTc" (ppr n)
-- Note [The Name of an IfaceAnyTc]
\end{code}
Note [The Name of an IfaceAnyTc]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+IA0_NOTE: This is an old comment. It needs to be updated with IPTc which
+I don't know about.
+
It isn't easy to get the Name of an IfaceAnyTc in a pure way. What you
really need to do is to transform it to a TyCon, and get the Name of that.
But doing so needs the monad because there's an IfaceKind inside, and we
@@ -190,8 +214,7 @@ pprIfaceIdBndr :: (IfLclName, IfaceType) -> SDoc
pprIfaceIdBndr (name, ty) = hsep [ppr name, dcolon, ppr ty]
pprIfaceTvBndr :: IfaceTvBndr -> SDoc
-pprIfaceTvBndr (tv, IfaceTyConApp (IfaceTc n) [])
- | n == liftedTypeKindTyConName
+pprIfaceTvBndr (tv, IfaceTyConApp IfaceLiftedTypeKindTc [])
= ppr tv
pprIfaceTvBndr (tv, kind) = parens (ppr tv <> dcolon <> ppr kind)
pprIfaceTvBndrs :: [IfaceTvBndr] -> SDoc
@@ -255,18 +278,21 @@ pprIfaceForAllPart tvs ctxt doc
-------------------
ppr_tc_app :: Int -> IfaceTyCon -> [IfaceType] -> SDoc
-ppr_tc_app _ tc [] = ppr_tc tc
-ppr_tc_app _ (IfaceTc n) [ty] | n == listTyConName = brackets (pprIfaceType ty)
-ppr_tc_app _ (IfaceTc n) [ty] | n == parrTyConName = pabrackets (pprIfaceType ty)
-ppr_tc_app _ (IfaceTc n) tys
- | Just (ATyCon tc) <- wiredInNameTyThing_maybe n
- , Just sort <- tyConTuple_maybe tc
- , tyConArity tc == length tys
- = tupleParens sort (sep (punctuate comma (map pprIfaceType tys)))
- | Just (ATyCon tc) <- wiredInNameTyThing_maybe n
- , Just ip <- tyConIP_maybe tc
- , [ty] <- tys
- = parens (ppr ip <> dcolon <> pprIfaceType ty)
+ppr_tc_app _ tc [] = ppr_tc tc
+
+ppr_tc_app _ IfaceListTc [ty] = brackets (pprIfaceType ty)
+ppr_tc_app _ IfaceListTc _ = panic "ppr_tc_app IfaceListTc"
+
+ppr_tc_app _ IfacePArrTc [ty] = pabrackets (pprIfaceType ty)
+ppr_tc_app _ IfacePArrTc _ = panic "ppr_tc_app IfacePArrTc"
+
+ppr_tc_app _ (IfaceTupTc sort _) tys =
+ tupleParens sort (sep (punctuate comma (map pprIfaceType tys)))
+
+ppr_tc_app _ (IfaceIPTc n) [ty] =
+ parens (ppr n <> dcolon <> pprIfaceType ty)
+ppr_tc_app _ (IfaceIPTc _) _ = panic "ppr_tc_app IfaceIPTc"
+
ppr_tc_app ctxt_prec tc tys
= maybeParen ctxt_prec tYCON_PREC
(sep [ppr_tc tc, nest 4 (sep (map pprParendIfaceType tys))])
@@ -278,11 +304,8 @@ ppr_tc tc = ppr tc
-------------------
instance Outputable IfaceTyCon where
- ppr (IfaceAnyTc k) = ptext (sLit "Any") <> pprParendIfaceType k
- -- We can't easily get the Name of an IfaceAnyTc
- -- (see Note [The Name of an IfaceAnyTc])
- -- so we fake it. It's only for debug printing!
- ppr (IfaceTc ext) = ppr ext
+ ppr (IfaceIPTc n) = ppr (IPName n)
+ ppr other_tc = ppr (ifaceTyConName other_tc)
instance Outputable IfaceCoCon where
ppr (IfaceCoAx n) = ppr n
@@ -350,8 +373,9 @@ toIfaceCoVar = occNameFS . getOccName
----------------
toIfaceTyCon :: TyCon -> IfaceTyCon
toIfaceTyCon tc
- | isAnyTyCon tc = IfaceAnyTc (toIfaceKind (tyConKind tc))
- | otherwise = IfaceTc (tyConName tc)
+ | isTupleTyCon tc = IfaceTupTc (tupleTyConSort tc) (tyConArity tc)
+ | Just n <- tyConIP_maybe tc = IfaceIPTc (ipFastString n)
+ | otherwise = toIfaceTyCon_name (tyConName tc)
toIfaceTyCon_name :: Name -> IfaceTyCon
toIfaceTyCon_name nm
@@ -362,7 +386,20 @@ toIfaceTyCon_name nm
toIfaceWiredInTyCon :: TyCon -> Name -> IfaceTyCon
toIfaceWiredInTyCon tc nm
- | isAnyTyCon tc = IfaceAnyTc (toIfaceKind (tyConKind tc))
+ | isTupleTyCon tc = IfaceTupTc (tupleTyConSort tc) (tyConArity tc)
+ | Just n <- tyConIP_maybe tc = IfaceIPTc (ipFastString n)
+ | nm == intTyConName = IfaceIntTc
+ | nm == boolTyConName = IfaceBoolTc
+ | nm == charTyConName = IfaceCharTc
+ | nm == listTyConName = IfaceListTc
+ | nm == parrTyConName = IfacePArrTc
+ | nm == liftedTypeKindTyConName = IfaceLiftedTypeKindTc
+ | nm == unliftedTypeKindTyConName = IfaceUnliftedTypeKindTc
+ | nm == openTypeKindTyConName = IfaceOpenTypeKindTc
+ | nm == argTypeKindTyConName = IfaceArgTypeKindTc
+ | nm == constraintKindTyConName = IfaceConstraintKindTc
+ | nm == ubxTupleKindTyConName = IfaceUbxTupleKindTc
+ | nm == tySuperKindTyConName = IfaceSuperKindTc
| otherwise = IfaceTc nm
----------------
diff --git a/compiler/iface/LoadIface.lhs b/compiler/iface/LoadIface.lhs
index 2f62ca5f4a..063158cf4e 100644
--- a/compiler/iface/LoadIface.lhs
+++ b/compiler/iface/LoadIface.lhs
@@ -250,7 +250,7 @@ loadInterface doc_str mod from
; new_eps_fam_insts <- mapM tcIfaceFamInst (mi_fam_insts iface)
; new_eps_rules <- tcIfaceRules ignore_prags (mi_rules iface)
; new_eps_anns <- tcIfaceAnnotations (mi_anns iface)
- ; new_eps_vect_info <- tcIfaceVectInfo mod (mi_vect_info iface)
+ ; new_eps_vect_info <- tcIfaceVectInfo mod (mkNameEnv new_eps_decls) (mi_vect_info iface)
; let { final_iface = iface {
mi_decls = panic "No mi_decls in PIT",
@@ -660,6 +660,7 @@ pprModIface iface
, nest 2 (text "ABI hash:" <+> ppr (mi_mod_hash iface))
, nest 2 (text "export-list hash:" <+> ppr (mi_exp_hash iface))
, nest 2 (text "orphan hash:" <+> ppr (mi_orphan_hash iface))
+ , nest 2 (text "flag hash:" <+> ppr (mi_flag_hash iface))
, nest 2 (text "used TH splices:" <+> ppr (mi_used_th iface))
, nest 2 (ptext (sLit "where"))
, ptext (sLit "exports:")
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index c25186444f..86c46bac6c 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -4,13 +4,9 @@
%
\begin{code}
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
+-- | Module for constructing @ModIface@ values (interface files),
+-- writing them to disk and comparing two versions to see if
+-- recompilation is required.
module MkIface (
mkUsedNames,
mkDependencies,
@@ -61,6 +57,8 @@ Basic idea:
import IfaceSyn
import LoadIface
+import FlagChecker
+
import Id
import IdInfo
import Demand
@@ -155,10 +153,10 @@ mkIface hsc_env maybe_old_fingerprint mod_details
-- for non-optimising compilation, or where we aren't generating any
-- object code at all ('HscNothing').
mkIfaceTc :: HscEnv
- -> Maybe Fingerprint -- The old fingerprint, if we have it
- -> ModDetails -- gotten from mkBootModDetails, probably
- -> TcGblEnv -- Usages, deprecations, etc
- -> IO (Messages, Maybe (ModIface, Bool))
+ -> Maybe Fingerprint -- The old fingerprint, if we have it
+ -> ModDetails -- gotten from mkBootModDetails, probably
+ -> TcGblEnv -- Usages, deprecations, etc
+ -> IO (Messages, Maybe (ModIface, Bool))
mkIfaceTc hsc_env maybe_old_fingerprint mod_details
tc_result@TcGblEnv{ tcg_mod = this_mod,
tcg_src = hsc_src,
@@ -230,128 +228,131 @@ mkIface_ :: HscEnv -> Maybe Fingerprint -> Module -> IsBootInterface
mkIface_ hsc_env maybe_old_fingerprint
this_mod is_boot used_names used_th deps rdr_env fix_env src_warns
hpc_info dir_imp_mods pkg_trust_req dependent_files
- ModDetails{ md_insts = insts,
- md_fam_insts = fam_insts,
- md_rules = rules,
- md_anns = anns,
+ ModDetails{ md_insts = insts,
+ md_fam_insts = fam_insts,
+ md_rules = rules,
+ md_anns = anns,
md_vect_info = vect_info,
- md_types = type_env,
- md_exports = exports }
--- NB: notice that mkIface does not look at the bindings
--- only at the TypeEnv. The previous Tidy phase has
--- put exactly the info into the TypeEnv that we want
--- to expose in the interface
-
- = do { usages <- mkUsageInfo hsc_env this_mod dir_imp_mods used_names dependent_files
+ md_types = type_env,
+ md_exports = exports }
+-- NB: notice that mkIface does not look at the bindings
+-- only at the TypeEnv. The previous Tidy phase has
+-- put exactly the info into the TypeEnv that we want
+-- to expose in the interface
+
+ = do { usages <- mkUsageInfo hsc_env this_mod dir_imp_mods used_names dependent_files
; safeInf <- hscGetSafeInf hsc_env
- ; let { entities = typeEnvElts type_env ;
+ ; let { entities = typeEnvElts type_env ;
decls = [ tyThingToIfaceDecl entity
- | entity <- entities,
- let name = getName entity,
+ | entity <- entities,
+ let name = getName entity,
not (isImplicitTyThing entity),
- -- No implicit Ids and class tycons in the interface file
- not (isWiredInName name),
- -- Nor wired-in things; the compiler knows about them anyhow
- nameIsLocalOrFrom this_mod name ]
- -- Sigh: see Note [Root-main Id] in TcRnDriver
-
- ; fixities = [(occ,fix) | FixItem occ fix <- nameEnvElts fix_env]
- ; warns = src_warns
- ; iface_rules = map (coreRuleToIfaceRule this_mod) rules
- ; iface_insts = map instanceToIfaceInst insts
- ; iface_fam_insts = map famInstToIfaceFamInst fam_insts
+ -- No implicit Ids and class tycons in the interface file
+ not (isWiredInName name),
+ -- Nor wired-in things; the compiler knows about them anyhow
+ nameIsLocalOrFrom this_mod name ]
+ -- Sigh: see Note [Root-main Id] in TcRnDriver
+
+ ; fixities = [(occ,fix) | FixItem occ fix <- nameEnvElts fix_env]
+ ; warns = src_warns
+ ; iface_rules = map (coreRuleToIfaceRule this_mod) rules
+ ; iface_insts = map instanceToIfaceInst insts
+ ; iface_fam_insts = map famInstToIfaceFamInst fam_insts
; iface_vect_info = flattenVectInfo vect_info
+ -- Check if we are in Safe Inference mode but we failed to pass
+ -- the muster
; safeMode = if safeInferOn dflags && not safeInf
then Sf_None
else safeHaskell dflags
; trust_info = setSafeMode safeMode
- ; intermediate_iface = ModIface {
- mi_module = this_mod,
- mi_boot = is_boot,
- mi_deps = deps,
- mi_usages = usages,
- mi_exports = mkIfaceExports exports,
-
- -- Sort these lexicographically, so that
- -- the result is stable across compilations
- mi_insts = sortLe le_inst iface_insts,
- mi_fam_insts= sortLe le_fam_inst iface_fam_insts,
- mi_rules = sortLe le_rule iface_rules,
-
- mi_vect_info = iface_vect_info,
-
- mi_fixities = fixities,
- mi_warns = warns,
- mi_anns = mkIfaceAnnotations anns,
- mi_globals = Just rdr_env,
-
- -- Left out deliberately: filled in by addVersionInfo
- mi_iface_hash = fingerprint0,
- mi_mod_hash = fingerprint0,
- mi_exp_hash = fingerprint0,
- mi_used_th = used_th,
+ ; intermediate_iface = ModIface {
+ mi_module = this_mod,
+ mi_boot = is_boot,
+ mi_deps = deps,
+ mi_usages = usages,
+ mi_exports = mkIfaceExports exports,
+
+ -- Sort these lexicographically, so that
+ -- the result is stable across compilations
+ mi_insts = sortLe le_inst iface_insts,
+ mi_fam_insts = sortLe le_fam_inst iface_fam_insts,
+ mi_rules = sortLe le_rule iface_rules,
+
+ mi_vect_info = iface_vect_info,
+
+ mi_fixities = fixities,
+ mi_warns = warns,
+ mi_anns = mkIfaceAnnotations anns,
+ mi_globals = Just rdr_env,
+
+ -- Left out deliberately: filled in by addFingerprints
+ mi_iface_hash = fingerprint0,
+ mi_mod_hash = fingerprint0,
+ mi_flag_hash = fingerprint0,
+ mi_exp_hash = fingerprint0,
+ mi_used_th = used_th,
mi_orphan_hash = fingerprint0,
- mi_orphan = False, -- Always set by addVersionInfo, but
- -- it's a strict field, so we can't omit it.
- mi_finsts = False, -- Ditto
- mi_decls = deliberatelyOmitted "decls",
- mi_hash_fn = deliberatelyOmitted "hash_fn",
- mi_hpc = isHpcUsed hpc_info,
- mi_trust = trust_info,
- mi_trust_pkg = pkg_trust_req,
-
- -- And build the cached values
- mi_warn_fn = mkIfaceWarnCache warns,
- mi_fix_fn = mkIfaceFixCache fixities }
- }
+ mi_orphan = False, -- Always set by addFingerprints, but
+ -- it's a strict field, so we can't omit it.
+ mi_finsts = False, -- Ditto
+ mi_decls = deliberatelyOmitted "decls",
+ mi_hash_fn = deliberatelyOmitted "hash_fn",
+ mi_hpc = isHpcUsed hpc_info,
+ mi_trust = trust_info,
+ mi_trust_pkg = pkg_trust_req,
+
+ -- And build the cached values
+ mi_warn_fn = mkIfaceWarnCache warns,
+ mi_fix_fn = mkIfaceFixCache fixities }
+ }
; (new_iface, no_change_at_all)
- <- {-# SCC "versioninfo" #-}
- addFingerprints hsc_env maybe_old_fingerprint
+ <- {-# SCC "versioninfo" #-}
+ addFingerprints hsc_env maybe_old_fingerprint
intermediate_iface decls
- -- Warn about orphans
- ; let warn_orphs = wopt Opt_WarnOrphans dflags
+ -- Warn about orphans
+ ; let warn_orphs = wopt Opt_WarnOrphans dflags
warn_auto_orphs = wopt Opt_WarnAutoOrphans dflags
orph_warnings --- Laziness means no work done unless -fwarn-orphans
- | warn_orphs || warn_auto_orphs = rule_warns `unionBags` inst_warns
- | otherwise = emptyBag
- errs_and_warns = (orph_warnings, emptyBag)
- unqual = mkPrintUnqualified dflags rdr_env
- inst_warns = listToBag [ instOrphWarn unqual d
- | (d,i) <- insts `zip` iface_insts
- , isNothing (ifInstOrph i) ]
- rule_warns = listToBag [ ruleOrphWarn unqual this_mod r
- | r <- iface_rules
- , isNothing (ifRuleOrph r)
+ | warn_orphs || warn_auto_orphs = rule_warns `unionBags` inst_warns
+ | otherwise = emptyBag
+ errs_and_warns = (orph_warnings, emptyBag)
+ unqual = mkPrintUnqualified dflags rdr_env
+ inst_warns = listToBag [ instOrphWarn unqual d
+ | (d,i) <- insts `zip` iface_insts
+ , isNothing (ifInstOrph i) ]
+ rule_warns = listToBag [ ruleOrphWarn unqual this_mod r
+ | r <- iface_rules
+ , isNothing (ifRuleOrph r)
, if ifRuleAuto r then warn_auto_orphs
else warn_orphs ]
- ; if errorsFound dflags errs_and_warns
+ ; if errorsFound dflags errs_and_warns
then return ( errs_and_warns, Nothing )
else do {
- -- Debug printing
- ; dumpIfSet_dyn dflags Opt_D_dump_hi "FINAL INTERFACE"
- (pprModIface new_iface)
+ -- Debug printing
+ ; dumpIfSet_dyn dflags Opt_D_dump_hi "FINAL INTERFACE"
+ (pprModIface new_iface)
-- bug #1617: on reload we weren't updating the PrintUnqualified
-- correctly. This stems from the fact that the interface had
- -- not changed, so addVersionInfo returns the old ModIface
+ -- not changed, so addFingerprints returns the old ModIface
-- with the old GlobalRdrEnv (mi_globals).
; let final_iface = new_iface{ mi_globals = Just rdr_env }
- ; return (errs_and_warns, Just (final_iface, no_change_at_all)) }}
+ ; return (errs_and_warns, Just (final_iface, no_change_at_all)) }}
where
r1 `le_rule` r2 = ifRuleName r1 <= ifRuleName r2
i1 `le_inst` i2 = ifDFun i1 `le_occ` ifDFun i2
i1 `le_fam_inst` i2 = ifFamInstTcName i1 `le_occ` ifFamInstTcName i2
le_occ :: Name -> Name -> Bool
- -- Compare lexicographically by OccName, *not* by unique, because
- -- the latter is not stable across compilations
+ -- Compare lexicographically by OccName, *not* by unique, because
+ -- the latter is not stable across compilations
le_occ n1 n2 = nameOccName n1 <= nameOccName n2
dflags = hsc_dflags hsc_env
@@ -413,10 +414,10 @@ mkHashFun hsc_env eps
addFingerprints
:: HscEnv
-> Maybe Fingerprint -- the old fingerprint, if any
- -> ModIface -- The new interface (lacking decls)
+ -> ModIface -- The new interface (lacking decls)
-> [IfaceDecl] -- The new decls
-> IO (ModIface, -- Updated interface
- Bool) -- True <=> no changes at all;
+ Bool) -- True <=> no changes at all;
-- no need to write Iface
addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
@@ -432,9 +433,9 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
edges :: [(IfaceDeclABI, Unique, [Unique])]
edges = [ (abi, getUnique (ifName decl), out)
- | decl <- new_decls
+ | decl <- new_decls
, let abi = declABI decl
- , let out = localOccs $ freeNamesDeclABI abi
+ , let out = localOccs $ freeNamesDeclABI abi
]
name_module n = ASSERT2( isExternalName n, ppr n ) nameModule n
@@ -470,7 +471,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- wired-in names don't have fingerprints
| otherwise
= ASSERT2( isExternalName name, ppr name )
- let hash | nameModule name /= this_mod = global_hash_fn name
+ let hash | nameModule name /= this_mod = global_hash_fn name
| otherwise =
snd (lookupOccEnv local_env (getOccName name)
`orElse` pprPanic "urk! lookup local fingerprint"
@@ -499,32 +500,46 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
decl = abiDecl abi
-- pprTrace "fingerprinting" (ppr (ifName decl) ) $ do
hash <- computeFingerprint hash_fn abi
- return (extend_hash_env (hash,decl) local_env,
- (hash,decl) : decls_w_hashes)
+ env' <- extend_hash_env local_env (hash,decl)
+ return (env', (hash,decl) : decls_w_hashes)
fingerprint_group (local_env, decls_w_hashes) (CyclicSCC abis)
= do let decls = map abiDecl abis
- local_env' = foldr extend_hash_env local_env
+ local_env1 <- foldM extend_hash_env local_env
(zip (repeat fingerprint0) decls)
- hash_fn = mk_put_name local_env'
+ let hash_fn = mk_put_name local_env1
-- pprTrace "fingerprinting" (ppr (map ifName decls) ) $ do
let stable_abis = sortBy cmp_abiNames abis
-- put the cycle in a canonical order
hash <- computeFingerprint hash_fn stable_abis
let pairs = zip (repeat hash) decls
- return (foldr extend_hash_env local_env pairs,
- pairs ++ decls_w_hashes)
+ local_env2 <- foldM extend_hash_env local_env pairs
+ return (local_env2, pairs ++ decls_w_hashes)
- extend_hash_env :: (Fingerprint,IfaceDecl)
- -> OccEnv (OccName,Fingerprint)
- -> OccEnv (OccName,Fingerprint)
- extend_hash_env (hash,d) env0 = foldr add_imp env1 (ifaceDeclSubBndrs d)
+ -- we have fingerprinted the whole declaration, but we now need
+ -- to assign fingerprints to all the OccNames that it binds, to
+ -- use when referencing those OccNames in later declarations.
+ --
+ -- We better give each name bound by the declaration a
+ -- different fingerprint! So we calculate the fingerprint of
+ -- each binder by combining the fingerprint of the whole
+ -- declaration with the name of the binder. (#5614)
+ extend_hash_env :: OccEnv (OccName,Fingerprint)
+ -> (Fingerprint,IfaceDecl)
+ -> IO (OccEnv (OccName,Fingerprint))
+ extend_hash_env env0 (hash,d) = do
+ let
+ sub_bndrs = ifaceDeclSubBndrs d
+ fp_sub_bndr occ = computeFingerprint putNameLiterally (hash,occ)
+ --
+ sub_fps <- mapM fp_sub_bndr sub_bndrs
+ return (foldr (\(b,fp) env -> extendOccEnv env b (b,fp)) env1
+ (zip sub_bndrs sub_fps))
where
decl_name = ifName d
item = (decl_name, hash)
env1 = extendOccEnv env0 decl_name item
- add_imp bndr env = extendOccEnv env bndr item
-
+
--
(local_env, decls_w_hashes) <-
foldM fingerprint_group (emptyOccEnv, []) groups
@@ -562,6 +577,12 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- put the declarations in a canonical order, sorted by OccName
let sorted_decls = Map.elems $ Map.fromList $
[(ifName d, e) | e@(_, d) <- decls_w_hashes]
+
+ -- the flag hash depends on:
+ -- - (some of) dflags
+ -- it returns two hashes, one that shouldn't change
+ -- the abi hash and one that should
+ flag_hash <- fingerprintDynFlags dflags putNameLiterally
-- the ABI hash depends on:
-- - decls
@@ -569,6 +590,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- - orphans
-- - deprecations
-- - vect info
+ -- - flag abi hash
mod_hash <- computeFingerprint putNameLiterally
(map fst sorted_decls,
export_hash,
@@ -577,10 +599,10 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
mi_vect_info iface0)
-- The interface hash depends on:
- -- - the ABI hash, plus
- -- - usages
- -- - deps
- -- - hpc
+ -- - the ABI hash, plus
+ -- - usages
+ -- - deps
+ -- - hpc
iface_hash <- computeFingerprint putNameLiterally
(mod_hash,
mi_usages iface0,
@@ -595,6 +617,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
mi_iface_hash = iface_hash,
mi_exp_hash = export_hash,
mi_orphan_hash = orphan_hash,
+ mi_flag_hash = flag_hash,
mi_orphan = not (null orph_rules && null orph_insts
&& null (ifaceVectInfoVar (mi_vect_info iface0))),
mi_finsts = not . null $ mi_fam_insts iface0,
@@ -640,9 +663,9 @@ sortDependencies d
%************************************************************************
-%* *
- The ABI of an IfaceDecl
-%* *
+%* *
+ The ABI of an IfaceDecl
+%* *
%************************************************************************
Note [The ABI of an IfaceDecl]
@@ -674,17 +697,17 @@ data IfaceDeclExtras
= IfaceIdExtras Fixity [IfaceRule]
| IfaceDataExtras
- Fixity -- Fixity of the tycon itself
- [IfaceInstABI] -- Local instances of this tycon
- -- See Note [Orphans] in IfaceSyn
- [(Fixity,[IfaceRule])] -- For each construcotr, fixity and RULES
+ Fixity -- Fixity of the tycon itself
+ [IfaceInstABI] -- Local instances of this tycon
+ -- See Note [Orphans] in IfaceSyn
+ [(Fixity,[IfaceRule])] -- For each construcotr, fixity and RULES
| IfaceClassExtras
- Fixity -- Fixity of the class itself
- [IfaceInstABI] -- Local instances of this class *or*
- -- of its associated data types
- -- See Note [Orphans] in IfaceSyn
- [(Fixity,[IfaceRule])] -- For each class method, fixity and RULES
+ Fixity -- Fixity of the class itself
+ [IfaceInstABI] -- Local instances of this class *or*
+ -- of its associated data types
+ -- See Note [Orphans] in IfaceSyn
+ [(Fixity,[IfaceRule])] -- For each class method, fixity and RULES
| IfaceSynExtras Fixity
@@ -766,8 +789,8 @@ declExtras fix_fn rule_env inst_env decl
IfaceClassExtras (fix_fn n)
(map ifDFun $ (concatMap at_extras ats)
++ lookupOccEnvL inst_env n)
- -- Include instances of the associated types
- -- as well as instances of the class (Trac #5147)
+ -- Include instances of the associated types
+ -- as well as instances of the class (Trac #5147)
[id_extras op | IfaceClassOp op _ _ <- sigs]
IfaceSyn{} -> IfaceSynExtras (fix_fn n)
_other -> IfaceOtherDeclExtras
@@ -828,43 +851,43 @@ ruleOrphWarn unqual mod rule
----------------------
-- mkOrphMap partitions instance decls or rules into
--- (a) an OccEnv for ones that are not orphans,
--- mapping the local OccName to a list of its decls
--- (b) a list of orphan decls
-mkOrphMap :: (decl -> Maybe OccName) -- (Just occ) for a non-orphan decl, keyed by occ
- -- Nothing for an orphan decl
- -> [decl] -- Sorted into canonical order
- -> (OccEnv [decl], -- Non-orphan decls associated with their key;
- -- each sublist in canonical order
- [decl]) -- Orphan decls; in canonical order
+-- (a) an OccEnv for ones that are not orphans,
+-- mapping the local OccName to a list of its decls
+-- (b) a list of orphan decls
+mkOrphMap :: (decl -> Maybe OccName) -- (Just occ) for a non-orphan decl, keyed by occ
+ -- Nothing for an orphan decl
+ -> [decl] -- Sorted into canonical order
+ -> (OccEnv [decl], -- Non-orphan decls associated with their key;
+ -- each sublist in canonical order
+ [decl]) -- Orphan decls; in canonical order
mkOrphMap get_key decls
= foldl go (emptyOccEnv, []) decls
where
go (non_orphs, orphs) d
- | Just occ <- get_key d
- = (extendOccEnv_Acc (:) singleton non_orphs occ d, orphs)
- | otherwise = (non_orphs, d:orphs)
+ | Just occ <- get_key d
+ = (extendOccEnv_Acc (:) singleton non_orphs occ d, orphs)
+ | otherwise = (non_orphs, d:orphs)
\end{code}
%************************************************************************
-%* *
+%* *
Keeping track of what we've slurped, and fingerprints
-%* *
+%* *
%************************************************************************
\begin{code}
mkUsageInfo :: HscEnv -> Module -> ImportedMods -> NameSet -> [FilePath] -> IO [Usage]
mkUsageInfo hsc_env this_mod dir_imp_mods used_names dependent_files
- = do { eps <- hscEPS hsc_env
+ = do { eps <- hscEPS hsc_env
; mtimes <- mapM getModificationTime dependent_files
- ; let mod_usages = mk_mod_usage_info (eps_PIT eps) hsc_env this_mod
- dir_imp_mods used_names
- ; let usages = mod_usages ++ map to_file_usage (zip dependent_files mtimes)
- ; usages `seqList` return usages }
- -- seq the list of Usages returned: occasionally these
- -- don't get evaluated for a while and we can end up hanging on to
- -- the entire collection of Ifaces.
+ ; let mod_usages = mk_mod_usage_info (eps_PIT eps) hsc_env this_mod
+ dir_imp_mods used_names
+ ; let usages = mod_usages ++ map to_file_usage (zip dependent_files mtimes)
+ ; usages `seqList` return usages }
+ -- seq the list of Usages returned: occasionally these
+ -- don't get evaluated for a while and we can end up hanging on to
+ -- the entire collection of Ifaces.
where
to_file_usage (f, mtime) = UsageFile { usg_file_path = f, usg_mtime = mtime }
@@ -898,22 +921,22 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
| otherwise
= case nameModule_maybe name of
Nothing -> ASSERT2( isSystemName name, ppr name ) mv_map
- -- See Note [Internal used_names]
+ -- See Note [Internal used_names]
Just mod -> -- This lambda function is really just a
-- specialised (++); originally came about to
-- avoid quadratic behaviour (trac #2680)
extendModuleEnvWith (\_ xs -> occ:xs) mv_map mod [occ]
- where occ = nameOccName name
+ where occ = nameOccName name
-- We want to create a Usage for a home module if
- -- a) we used something from it; has something in used_names
- -- b) we imported it, even if we used nothing from it
- -- (need to recompile if its export list changes: export_fprint)
+ -- a) we used something from it; has something in used_names
+ -- b) we imported it, even if we used nothing from it
+ -- (need to recompile if its export list changes: export_fprint)
mkUsage :: Module -> Maybe Usage
mkUsage mod
- | isNothing maybe_iface -- We can't depend on it if we didn't
- -- load its interface.
+ | isNothing maybe_iface -- We can't depend on it if we didn't
+ -- load its interface.
|| mod == this_mod -- We don't care about usages of
-- things in *this* module
= Nothing
@@ -925,15 +948,15 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
-- for package modules, we record the module hash only
| (null used_occs
- && isNothing export_hash
+ && isNothing export_hash
&& not is_direct_import
- && not finsts_mod)
- = Nothing -- Record no usage info
+ && not finsts_mod)
+ = Nothing -- Record no usage info
-- for directly-imported modules, we always want to record a usage
-- on the orphan hash. This is what triggers a recompilation if
-- an orphan is added or removed somewhere below us in the future.
- | otherwise
+ | otherwise
= Just UsageHomeModule {
usg_mod_name = moduleName mod,
usg_mod_hash = mod_hash,
@@ -946,7 +969,7 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
-- modules accumulate in the PIT not HPT. Sigh.
Just iface = maybe_iface
- finsts_mod = mi_finsts iface
+ finsts_mod = mi_finsts iface
hash_env = mi_hash_fn iface
mod_hash = mi_mod_hash iface
export_hash | depend_on_exports = Just (mi_exp_hash iface)
@@ -962,12 +985,12 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
used_occs = lookupModuleEnv ent_map mod `orElse` []
- -- Making a Map here ensures that (a) we remove duplicates
+ -- Making a Map here ensures that (a) we remove duplicates
-- when we have usages on several subordinates of a single parent,
-- and (b) that the usages emerge in a canonical order, which
-- is why we use Map rather than OccEnv: Map works
-- using Ord on the OccNames, which is a lexicographic ordering.
- ent_hashs :: Map OccName Fingerprint
+ ent_hashs :: Map OccName Fingerprint
ent_hashs = Map.fromList (map lookup_occ used_occs)
lookup_occ occ =
@@ -1020,10 +1043,10 @@ mkIfaceExports exports
Note [Orignal module]
~~~~~~~~~~~~~~~~~~~~~
Consider this:
- module X where { data family T }
- module Y( T(..) ) where { import X; data instance T Int = MkT Int }
+ module X where { data family T }
+ module Y( T(..) ) where { import X; data instance T Int = MkT Int }
The exported Avail from Y will look like
- X.T{X.T, Y.MkT}
+ X.T{X.T, Y.MkT}
That is, in Y,
- only MkT is brought into scope by the data instance;
- but the parent (used for grouping and naming in T(..) exports) is X.T
@@ -1043,19 +1066,25 @@ Trac #5362 for an example. Such Names are always
%************************************************************************
-%* *
- Load the old interface file for this module (unless
- we have it aleady), and check whether it is up to date
-
-%* *
+%* *
+ Load the old interface file for this module (unless
+ we have it already), and check whether it is up to date
+
+%* *
%************************************************************************
\begin{code}
+-- | Top level function to check if the version of an old interface file
+-- is equivalent to the current source file the user asked us to compile.
+-- If the same, we can avoid recompilation. We return a tuple where the
+-- first element is a bool saying if we should recompile the object file
+-- and the second is maybe the interface file, where Nothng means to
+-- rebuild the interface file not use the exisitng one.
checkOldIface :: HscEnv
- -> ModSummary
+ -> ModSummary
-> SourceModified
- -> Maybe ModIface -- Old interface from compilation manager, if any
- -> IO (RecompileRequired, Maybe ModIface)
+ -> Maybe ModIface -- Old interface from compilation manager, if any
+ -> IO (RecompileRequired, Maybe ModIface)
checkOldIface hsc_env mod_summary source_modified maybe_iface
= do showPass (hsc_dflags hsc_env) $
@@ -1068,80 +1097,88 @@ check_old_iface :: HscEnv -> ModSummary -> SourceModified -> Maybe ModIface
check_old_iface hsc_env mod_summary src_modified maybe_iface
= let dflags = hsc_dflags hsc_env
getIface =
- case maybe_iface of
- Just _ -> do
- traceIf (text "We already have the old interface for" <+> ppr (ms_mod mod_summary))
- return maybe_iface
- Nothing -> do
- let iface_path = msHiFilePath mod_summary
- read_result <- readIface (ms_mod mod_summary) iface_path False
- case read_result of
- Failed err -> do
- traceIf (text "FYI: cannont read old interface file:" $$ nest 4 err)
- return Nothing
- Succeeded iface -> do
- traceIf (text "Read the interface file" <+> text iface_path)
- return $ Just iface
-
+ case maybe_iface of
+ Just _ -> do
+ traceIf (text "We already have the old interface for" <+> ppr (ms_mod mod_summary))
+ return maybe_iface
+ Nothing -> loadIface
+
+ loadIface = do
+ let iface_path = msHiFilePath mod_summary
+ read_result <- readIface (ms_mod mod_summary) iface_path False
+ case read_result of
+ Failed err -> do
+ traceIf (text "FYI: cannont read old interface file:" $$ nest 4 err)
+ return Nothing
+ Succeeded iface -> do
+ traceIf (text "Read the interface file" <+> text iface_path)
+ return $ Just iface
+
+ src_changed
+ | dopt Opt_ForceRecomp (hsc_dflags hsc_env) = True
+ | SourceModified <- src_modified = True
+ | otherwise = False
in do
- let src_changed
- | dopt Opt_ForceRecomp (hsc_dflags hsc_env) = True
- | SourceModified <- src_modified = True
- | otherwise = False
-
- when src_changed
- (traceHiDiffs (nest 4 (text "Source file changed or recompilation check turned off")))
-
- -- If the source has changed and we're in interactive mode,
- -- avoid reading an interface; just return the one we might
- -- have been supplied with.
- if not (isObjectTarget $ hscTarget dflags) && src_changed
- then return (outOfDate, maybe_iface)
- else do
- -- Try and read the old interface for the current module
- -- from the .hi file left from the last time we compiled it
+ when src_changed $
+ traceHiDiffs (nest 4 $ text "Source file changed or recompilation check turned off")
+
+ case src_changed of
+ -- If the source has changed and we're in interactive mode,
+ -- avoid reading an interface; just return the one we might
+ -- have been supplied with.
+ True | not (isObjectTarget $ hscTarget dflags) ->
+ return (outOfDate, maybe_iface)
+
+ -- Try and read the old interface for the current module
+ -- from the .hi file left from the last time we compiled it
+ True -> do
maybe_iface' <- getIface
- if src_changed
- then return (outOfDate, maybe_iface')
- else do
- case maybe_iface' of
- Nothing -> return (outOfDate, maybe_iface')
- Just iface ->
- -- We have got the old iface; check its versions
- -- even in the SourceUnmodifiedAndStable case we
- -- should check versions because some packages
- -- might have changed or gone away.
- checkVersions hsc_env mod_summary iface
-\end{code}
-
-@recompileRequired@ is called from the HscMain. It checks whether
-a recompilation is required. It needs access to the persistent state,
-finder, etc, because it may have to load lots of interface files to
-check their versions.
+ return (outOfDate, maybe_iface')
-\begin{code}
+ False -> do
+ maybe_iface' <- getIface
+ case maybe_iface' of
+ -- We can't retrieve the iface
+ Nothing -> return (outOfDate, Nothing)
+
+ -- We have got the old iface; check its versions
+ -- even in the SourceUnmodifiedAndStable case we
+ -- should check versions because some packages
+ -- might have changed or gone away.
+ Just iface -> checkVersions hsc_env mod_summary iface
+
+-- | @recompileRequired@ is called from the HscMain. It checks whether
+-- a recompilation is required. It needs access to the persistent state,
+-- finder, etc, because it may have to load lots of interface files to
+-- check their versions.
type RecompileRequired = Bool
upToDate, outOfDate :: Bool
-upToDate = False -- Recompile not required
-outOfDate = True -- Recompile required
-
--- | Check the safe haskell flags haven't changed
--- (e.g different flag on command line now)
-safeHsChanged :: HscEnv -> ModIface -> Bool
-safeHsChanged hsc_env iface
- = (getSafeMode $ mi_trust iface) /= (safeHaskell $ hsc_dflags hsc_env)
+upToDate = False -- Recompile not required
+outOfDate = True -- Recompile required
+-- | Check if a module is still the same 'version'.
+--
+-- This function is called in the recompilation checker after we have
+-- determined that the module M being checked hasn't had any changes
+-- to its source file since we last compiled M. So at this point in general
+-- two things may have changed that mean we should recompile M:
+-- * The interface export by a dependency of M has changed.
+-- * The compiler flags specified this time for M have changed
+-- in a manner that is significant for recompilaiton.
+-- We return not just if we should recompile the object file but also
+-- if we should rebuild the interface file.
checkVersions :: HscEnv
-> ModSummary
- -> ModIface -- Old interface
- -> IfG (RecompileRequired, Maybe ModIface)
+ -> ModIface -- Old interface
+ -> IfG (RecompileRequired, Maybe ModIface)
checkVersions hsc_env mod_summary iface
= do { traceHiDiffs (text "Considering whether compilation is required for" <+>
ppr (mi_module iface) <> colon)
+ ; recomp <- checkFlagHash hsc_env iface
+ ; if recomp then return (outOfDate, Nothing) else do {
; recomp <- checkDependencies hsc_env mod_summary iface
; if recomp then return (outOfDate, Just iface) else do {
- ; if trust_dif then return (outOfDate, Nothing) else do {
-- Source code unchanged and no errors yet... carry on
--
@@ -1161,12 +1198,20 @@ checkVersions hsc_env mod_summary iface
; return (recomp, Just iface)
}}}
where
- this_pkg = thisPackage (hsc_dflags hsc_env)
- trust_dif = safeHsChanged hsc_env iface
+ this_pkg = thisPackage (hsc_dflags hsc_env)
-- This is a bit of a hack really
mod_deps :: ModuleNameEnv (ModuleName, IsBootInterface)
mod_deps = mkModDeps (dep_mods (mi_deps iface))
+-- | Check the flags haven't changed
+checkFlagHash :: HscEnv -> ModIface -> IfG RecompileRequired
+checkFlagHash hsc_env iface = do
+ let old_hash = mi_flag_hash iface
+ new_hash <- liftIO $ fingerprintDynFlags (hsc_dflags hsc_env) putNameLiterally
+ case old_hash == new_hash of
+ True -> up_to_date (ptext $ sLit "Module flags unchanged")
+ False -> out_of_date_hash (ptext $ sLit " Module flags have changed")
+ old_hash new_hash
-- If the direct imports of this module are resolved to targets that
-- are not among the dependencies of the previous interface file,
@@ -1217,13 +1262,13 @@ checkDependencies hsc_env summary iface
needInterface :: Module -> (ModIface -> IfG RecompileRequired)
-> IfG RecompileRequired
needInterface mod continue
- = do -- Load the imported interface if possible
+ = do -- Load the imported interface if possible
let doc_str = sep [ptext (sLit "need version info for"), ppr mod]
traceHiDiffs (text "Checking usages for module" <+> ppr mod)
mb_iface <- loadInterface doc_str mod ImportBySystem
- -- Load the interface, but don't complain on failure;
- -- Instead, get an Either back which we can test
+ -- Load the interface, but don't complain on failure;
+ -- Instead, get an Either back which we can test
case mb_iface of
Failed _ -> (out_of_date (sep [ptext (sLit "Couldn't load interface for module"),
@@ -1235,11 +1280,10 @@ needInterface mod continue
Succeeded iface -> continue iface
-checkModUsage :: PackageId ->Usage -> IfG RecompileRequired
--- Given the usage information extracted from the old
+-- | Given the usage information extracted from the old
-- M.hi file for the module being compiled, figure out
-- whether M needs to be recompiled.
-
+checkModUsage :: PackageId -> Usage -> IfG RecompileRequired
checkModUsage _this_pkg UsagePackageModule{
usg_mod = mod,
usg_mod_hash = old_mod_hash }
@@ -1253,30 +1297,30 @@ checkModUsage _this_pkg UsagePackageModule{
checkModUsage this_pkg UsageHomeModule{
usg_mod_name = mod_name,
usg_mod_hash = old_mod_hash,
- usg_exports = maybe_old_export_hash,
- usg_entities = old_decl_hash }
+ usg_exports = maybe_old_export_hash,
+ usg_entities = old_decl_hash }
= do
let mod = mkModule this_pkg mod_name
needInterface mod $ \iface -> do
let
- new_mod_hash = mi_mod_hash iface
- new_decl_hash = mi_hash_fn iface
- new_export_hash = mi_exp_hash iface
+ new_mod_hash = mi_mod_hash iface
+ new_decl_hash = mi_hash_fn iface
+ new_export_hash = mi_exp_hash iface
- -- CHECK MODULE
+ -- CHECK MODULE
recompile <- checkModuleFingerprint old_mod_hash new_mod_hash
if not recompile then return upToDate else do
-
- -- CHECK EXPORT LIST
+
+ -- CHECK EXPORT LIST
checkMaybeHash maybe_old_export_hash new_export_hash
(ptext (sLit " Export list changed")) $ do
- -- CHECK ITEMS ONE BY ONE
+ -- CHECK ITEMS ONE BY ONE
recompile <- checkList [ checkEntityUsage new_decl_hash u
| u <- old_decl_hash]
if recompile
- then return outOfDate -- This one failed, so just bail out now
+ then return outOfDate -- This one failed, so just bail out now
else up_to_date (ptext (sLit " Great! The bits I use are up to date"))
@@ -1285,16 +1329,15 @@ checkModUsage _this_pkg UsageFile{ usg_file_path = file, usg_mtime = old_mtime }
return $ old_mtime /= new_mtime
-
------------------------
-checkModuleFingerprint :: Fingerprint -> Fingerprint -> IfG Bool
+checkModuleFingerprint :: Fingerprint -> Fingerprint -> IfG RecompileRequired
checkModuleFingerprint old_mod_hash new_mod_hash
| new_mod_hash == old_mod_hash
= up_to_date (ptext (sLit "Module fingerprint unchanged"))
| otherwise
= out_of_date_hash (ptext (sLit " Module fingerprint has changed"))
- old_mod_hash new_mod_hash
+ old_mod_hash new_mod_hash
------------------------
checkMaybeHash :: Maybe Fingerprint -> Fingerprint -> SDoc
@@ -1308,31 +1351,31 @@ checkMaybeHash maybe_old_hash new_hash doc continue
------------------------
checkEntityUsage :: (OccName -> Maybe (OccName, Fingerprint))
-> (OccName, Fingerprint)
- -> IfG Bool
+ -> IfG RecompileRequired
checkEntityUsage new_hash (name,old_hash)
= case new_hash name of
- Nothing -> -- We used it before, but it ain't there now
- out_of_date (sep [ptext (sLit "No longer exported:"), ppr name])
+ Nothing -> -- We used it before, but it ain't there now
+ out_of_date (sep [ptext (sLit "No longer exported:"), ppr name])
- Just (_, new_hash) -- It's there, but is it up to date?
- | new_hash == old_hash -> do traceHiDiffs (text " Up to date" <+> ppr name <+> parens (ppr new_hash))
- return upToDate
- | otherwise -> out_of_date_hash (ptext (sLit " Out of date:") <+> ppr name)
- old_hash new_hash
+ Just (_, new_hash) -- It's there, but is it up to date?
+ | new_hash == old_hash -> do traceHiDiffs (text " Up to date" <+> ppr name <+> parens (ppr new_hash))
+ return upToDate
+ | otherwise -> out_of_date_hash (ptext (sLit " Out of date:") <+> ppr name)
+ old_hash new_hash
-up_to_date, out_of_date :: SDoc -> IfG Bool
+up_to_date, out_of_date :: SDoc -> IfG RecompileRequired
up_to_date msg = traceHiDiffs msg >> return upToDate
out_of_date msg = traceHiDiffs msg >> return outOfDate
-out_of_date_hash :: SDoc -> Fingerprint -> Fingerprint -> IfG Bool
+out_of_date_hash :: SDoc -> Fingerprint -> Fingerprint -> IfG RecompileRequired
out_of_date_hash msg old_hash new_hash
= out_of_date (hsep [msg, ppr old_hash, ptext (sLit "->"), ppr new_hash])
----------------------
checkList :: [IfG RecompileRequired] -> IfG RecompileRequired
-- This helper is used in two places
-checkList [] = return upToDate
+checkList [] = return upToDate
checkList (check:checks) = do recompile <- check
if recompile
then return outOfDate
@@ -1340,79 +1383,79 @@ checkList (check:checks) = do recompile <- check
\end{code}
%************************************************************************
-%* *
- Converting things to their Iface equivalents
-%* *
+%* *
+ Converting things to their Iface equivalents
+%* *
%************************************************************************
\begin{code}
tyThingToIfaceDecl :: TyThing -> IfaceDecl
-- Assumption: the thing is already tidied, so that locally-bound names
--- (lambdas, for-alls) already have non-clashing OccNames
+-- (lambdas, for-alls) already have non-clashing OccNames
-- Reason: Iface stuff uses OccNames, and the conversion here does
--- not do tidying on the way
+-- not do tidying on the way
tyThingToIfaceDecl (AnId id)
= IfaceId { ifName = getOccName id,
- ifType = toIfaceType (idType id),
- ifIdDetails = toIfaceIdDetails (idDetails id),
- ifIdInfo = toIfaceIdInfo (idInfo id) }
+ ifType = toIfaceType (idType id),
+ ifIdDetails = toIfaceIdDetails (idDetails id),
+ ifIdInfo = toIfaceIdInfo (idInfo id) }
tyThingToIfaceDecl (ATyCon tycon)
| Just clas <- tyConClass_maybe tycon
= classToIfaceDecl clas
| isSynTyCon tycon
- = IfaceSyn { ifName = getOccName tycon,
- ifTyVars = toIfaceTvBndrs tyvars,
- ifSynRhs = syn_rhs,
- ifSynKind = syn_ki,
+ = IfaceSyn { ifName = getOccName tycon,
+ ifTyVars = toIfaceTvBndrs tyvars,
+ ifSynRhs = syn_rhs,
+ ifSynKind = syn_ki,
ifFamInst = famInstToIface (tyConFamInst_maybe tycon)
}
| isAlgTyCon tycon
- = IfaceData { ifName = getOccName tycon,
- ifTyVars = toIfaceTvBndrs tyvars,
- ifCtxt = toIfaceContext (tyConStupidTheta tycon),
- ifCons = ifaceConDecls (algTyConRhs tycon),
- ifRec = boolToRecFlag (isRecursiveTyCon tycon),
- ifGadtSyntax = isGadtSyntaxTyCon tycon,
- ifFamInst = famInstToIface (tyConFamInst_maybe tycon)}
+ = IfaceData { ifName = getOccName tycon,
+ ifTyVars = toIfaceTvBndrs tyvars,
+ ifCtxt = toIfaceContext (tyConStupidTheta tycon),
+ ifCons = ifaceConDecls (algTyConRhs tycon),
+ ifRec = boolToRecFlag (isRecursiveTyCon tycon),
+ ifGadtSyntax = isGadtSyntaxTyCon tycon,
+ ifFamInst = famInstToIface (tyConFamInst_maybe tycon)}
| isForeignTyCon tycon
= IfaceForeign { ifName = getOccName tycon,
- ifExtName = tyConExtName tycon }
+ ifExtName = tyConExtName tycon }
| otherwise = pprPanic "toIfaceDecl" (ppr tycon)
where
tyvars = tyConTyVars tycon
(syn_rhs, syn_ki)
= case synTyConRhs tycon of
- SynFamilyTyCon -> (Nothing, toIfaceType (synTyConResKind tycon))
- SynonymTyCon ty -> (Just (toIfaceType ty), toIfaceType (typeKind ty))
+ SynFamilyTyCon -> (Nothing, toIfaceType (synTyConResKind tycon))
+ SynonymTyCon ty -> (Just (toIfaceType ty), toIfaceType (typeKind ty))
ifaceConDecls (NewTyCon { data_con = con }) =
IfNewTyCon (ifaceConDecl con)
ifaceConDecls (DataTyCon { data_cons = cons }) =
IfDataTyCon (map ifaceConDecl cons)
ifaceConDecls DataFamilyTyCon {} = IfOpenDataTyCon
- ifaceConDecls (AbstractTyCon distinct) = IfAbstractTyCon distinct
- -- The last case happens when a TyCon has been trimmed during tidying
- -- Furthermore, tyThingToIfaceDecl is also used
- -- in TcRnDriver for GHCi, when browsing a module, in which case the
- -- AbstractTyCon case is perfectly sensible.
+ ifaceConDecls (AbstractTyCon distinct) = IfAbstractTyCon distinct
+ -- The last case happens when a TyCon has been trimmed during tidying
+ -- Furthermore, tyThingToIfaceDecl is also used
+ -- in TcRnDriver for GHCi, when browsing a module, in which case the
+ -- AbstractTyCon case is perfectly sensible.
ifaceConDecl data_con
- = IfCon { ifConOcc = getOccName (dataConName data_con),
- ifConInfix = dataConIsInfix data_con,
- ifConWrapper = isJust (dataConWrapId_maybe data_con),
- ifConUnivTvs = toIfaceTvBndrs univ_tvs,
- ifConExTvs = toIfaceTvBndrs ex_tvs,
- ifConEqSpec = to_eq_spec eq_spec,
- ifConCtxt = toIfaceContext theta,
- ifConArgTys = map toIfaceType arg_tys,
- ifConFields = map getOccName
- (dataConFieldLabels data_con),
- ifConStricts = dataConStrictMarks data_con }
+ = IfCon { ifConOcc = getOccName (dataConName data_con),
+ ifConInfix = dataConIsInfix data_con,
+ ifConWrapper = isJust (dataConWrapId_maybe data_con),
+ ifConUnivTvs = toIfaceTvBndrs univ_tvs,
+ ifConExTvs = toIfaceTvBndrs ex_tvs,
+ ifConEqSpec = to_eq_spec eq_spec,
+ ifConCtxt = toIfaceContext theta,
+ ifConArgTys = map toIfaceType arg_tys,
+ ifConFields = map getOccName
+ (dataConFieldLabels data_con),
+ ifConStricts = dataConStrictMarks data_con }
where
(univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _) = dataConFullSig data_con
@@ -1425,7 +1468,7 @@ tyThingToIfaceDecl (ATyCon tycon)
tyThingToIfaceDecl c@(ACoAxiom _) = pprPanic "tyThingToIfaceDecl (ACoCon _)" (ppr c)
tyThingToIfaceDecl (ADataCon dc)
- = pprPanic "toIfaceDecl" (ppr dc) -- Should be trimmed out earlier
+ = pprPanic "toIfaceDecl" (ppr dc) -- Should be trimmed out earlier
classToIfaceDecl :: Class -> IfaceDecl
@@ -1447,7 +1490,7 @@ classToIfaceDecl clas
= IfaceAT (tyThingToIfaceDecl (ATyCon tc))
(map to_if_at_def defs)
where
- to_if_at_def (ATD tvs pat_tys ty)
+ to_if_at_def (ATD tvs pat_tys ty _loc)
= IfaceATD (toIfaceTvBndrs tvs) (map toIfaceType pat_tys) (toIfaceType ty)
toIfaceClassOp (sel_id, def_meth)
@@ -1478,10 +1521,10 @@ instanceToIfaceInst (Instance { is_dfun = dfun_id, is_flag = oflag,
is_cls = cls_name, is_tcs = mb_tcs })
= ASSERT( cls_name == className cls )
IfaceInst { ifDFun = dfun_name,
- ifOFlag = oflag,
- ifInstCls = cls_name,
- ifInstTys = map do_rough mb_tcs,
- ifInstOrph = orph }
+ ifOFlag = oflag,
+ ifInstCls = cls_name,
+ ifInstTys = map do_rough mb_tcs,
+ ifInstOrph = orph }
where
do_rough Nothing = Nothing
do_rough (Just n) = Just (toIfaceTyCon_name n)
@@ -1490,26 +1533,26 @@ instanceToIfaceInst (Instance { is_dfun = dfun_id, is_flag = oflag,
mod = ASSERT( isExternalName dfun_name ) nameModule dfun_name
is_local name = nameIsLocalOrFrom mod name
- -- Compute orphanhood. See Note [Orphans] in IfaceSyn
+ -- Compute orphanhood. See Note [Orphans] in IfaceSyn
(_, _, cls, tys) = tcSplitDFunTy (idType dfun_id)
- -- Slightly awkward: we need the Class to get the fundeps
+ -- Slightly awkward: we need the Class to get the fundeps
(tvs, fds) = classTvsFds cls
arg_names = [filterNameSet is_local (orphNamesOfType ty) | ty <- tys]
orph | is_local cls_name = Just (nameOccName cls_name)
- | all isJust mb_ns = ASSERT( not (null mb_ns) ) head mb_ns
- | otherwise = Nothing
+ | all isJust mb_ns = ASSERT( not (null mb_ns) ) head mb_ns
+ | otherwise = Nothing
- mb_ns :: [Maybe OccName] -- One for each fundep; a locally-defined name
- -- that is not in the "determined" arguments
+ mb_ns :: [Maybe OccName] -- One for each fundep; a locally-defined name
+ -- that is not in the "determined" arguments
mb_ns | null fds = [choose_one arg_names]
- | otherwise = map do_one fds
+ | otherwise = map do_one fds
do_one (_ltvs, rtvs) = choose_one [ns | (tv,ns) <- tvs `zip` arg_names
, not (tv `elem` rtvs)]
choose_one :: [NameSet] -> Maybe OccName
choose_one nss = case nameSetToList (unionManyNameSets nss) of
- [] -> Nothing
- (n : _) -> Just (nameOccName n)
+ [] -> Nothing
+ (n : _) -> Just (nameOccName n)
--------------------------
famInstToIfaceFamInst :: FamInst -> IfaceFamInst
@@ -1517,8 +1560,8 @@ famInstToIfaceFamInst (FamInst { fi_tycon = tycon,
fi_fam = fam,
fi_tcs = mb_tcs })
= IfaceFamInst { ifFamInstTyCon = toIfaceTyCon tycon
- , ifFamInstFam = fam
- , ifFamInstTys = map do_rough mb_tcs }
+ , ifFamInstFam = fam
+ , ifFamInstTys = map do_rough mb_tcs }
where
do_rough Nothing = Nothing
do_rough (Just n) = Just (toIfaceTyCon_name n)
@@ -1526,50 +1569,50 @@ famInstToIfaceFamInst (FamInst { fi_tycon = tycon,
--------------------------
toIfaceLetBndr :: Id -> IfaceLetBndr
toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id))
- (toIfaceType (idType id))
- (toIfaceIdInfo (idInfo id))
+ (toIfaceType (idType id))
+ (toIfaceIdInfo (idInfo id))
-- Put into the interface file any IdInfo that CoreTidy.tidyLetBndr
-- has left on the Id. See Note [IdInfo on nested let-bindings] in IfaceSyn
--------------------------
toIfaceIdDetails :: IdDetails -> IfaceIdDetails
-toIfaceIdDetails VanillaId = IfVanillaId
+toIfaceIdDetails VanillaId = IfVanillaId
toIfaceIdDetails (DFunId {}) = IfDFunId
toIfaceIdDetails (RecSelId { sel_naughty = n
- , sel_tycon = tc }) = IfRecSelId (toIfaceTyCon tc) n
-toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other)
+ , sel_tycon = tc }) = IfRecSelId (toIfaceTyCon tc) n
+toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other)
IfVanillaId -- Unexpected
toIfaceIdInfo :: IdInfo -> IfaceIdInfo
toIfaceIdInfo id_info
= case catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo,
- inline_hsinfo, unfold_hsinfo] of
+ inline_hsinfo, unfold_hsinfo] of
[] -> NoInfo
infos -> HasInfo infos
- -- NB: strictness must appear in the list before unfolding
- -- See TcIface.tcUnfolding
+ -- NB: strictness must appear in the list before unfolding
+ -- See TcIface.tcUnfolding
where
------------ Arity --------------
arity_info = arityInfo id_info
arity_hsinfo | arity_info == 0 = Nothing
- | otherwise = Just (HsArity arity_info)
+ | otherwise = Just (HsArity arity_info)
------------ Caf Info --------------
caf_info = cafInfo id_info
caf_hsinfo = case caf_info of
- NoCafRefs -> Just HsNoCafRefs
- _other -> Nothing
+ NoCafRefs -> Just HsNoCafRefs
+ _other -> Nothing
------------ Strictness --------------
- -- No point in explicitly exporting TopSig
+ -- No point in explicitly exporting TopSig
strict_hsinfo = case strictnessInfo id_info of
- Just sig | not (isTopSig sig) -> Just (HsStrictness sig)
- _other -> Nothing
+ Just sig | not (isTopSig sig) -> Just (HsStrictness sig)
+ _other -> Nothing
------------ Unfolding --------------
unfold_hsinfo = toIfUnfolding loop_breaker (unfoldingInfo id_info)
loop_breaker = isStrongLoopBreaker (occInfo id_info)
-
+
------------ Inline prag --------------
inline_prag = inlinePragInfo id_info
inline_hsinfo | isDefaultInlinePragma inline_prag = Nothing
@@ -1581,20 +1624,20 @@ toIfUnfolding lb (CoreUnfolding { uf_tmpl = rhs, uf_arity = arity
, uf_src = src, uf_guidance = guidance })
= Just $ HsUnfold lb $
case src of
- InlineStable
+ InlineStable
-> case guidance of
UnfWhen unsat_ok boring_ok -> IfInlineRule arity unsat_ok boring_ok if_rhs
_other -> IfCoreUnfold True if_rhs
- InlineWrapper w | isExternalName n -> IfExtWrapper arity n
- | otherwise -> IfLclWrapper arity (getFS n)
- where
+ InlineWrapper w | isExternalName n -> IfExtWrapper arity n
+ | otherwise -> IfLclWrapper arity (getFS n)
+ where
n = idName w
InlineCompulsory -> IfCompulsory if_rhs
InlineRhs -> IfCoreUnfold False if_rhs
- -- Yes, even if guidance is UnfNever, expose the unfolding
- -- If we didn't want to expose the unfolding, TidyPgm would
- -- have stuck in NoUnfolding. For supercompilation we want
- -- to see that unfolding!
+ -- Yes, even if guidance is UnfNever, expose the unfolding
+ -- If we didn't want to expose the unfolding, TidyPgm would
+ -- have stuck in NoUnfolding. For supercompilation we want
+ -- to see that unfolding!
where
if_rhs = toIfaceExpr rhs
@@ -1614,39 +1657,39 @@ coreRuleToIfaceRule _ (BuiltinRule { ru_fn = fn})
coreRuleToIfaceRule mod rule@(Rule { ru_name = name, ru_fn = fn,
ru_act = act, ru_bndrs = bndrs,
- ru_args = args, ru_rhs = rhs,
+ ru_args = args, ru_rhs = rhs,
ru_auto = auto })
= IfaceRule { ifRuleName = name, ifActivation = act,
- ifRuleBndrs = map toIfaceBndr bndrs,
- ifRuleHead = fn,
- ifRuleArgs = map do_arg args,
- ifRuleRhs = toIfaceExpr rhs,
+ ifRuleBndrs = map toIfaceBndr bndrs,
+ ifRuleHead = fn,
+ ifRuleArgs = map do_arg args,
+ ifRuleRhs = toIfaceExpr rhs,
ifRuleAuto = auto,
- ifRuleOrph = orph }
+ ifRuleOrph = orph }
where
- -- For type args we must remove synonyms from the outermost
- -- level. Reason: so that when we read it back in we'll
- -- construct the same ru_rough field as we have right now;
- -- see tcIfaceRule
+ -- For type args we must remove synonyms from the outermost
+ -- level. Reason: so that when we read it back in we'll
+ -- construct the same ru_rough field as we have right now;
+ -- see tcIfaceRule
do_arg (Type ty) = IfaceType (toIfaceType (deNoteType ty))
do_arg (Coercion co) = IfaceType (coToIfaceType co)
do_arg arg = toIfaceExpr arg
- -- Compute orphanhood. See Note [Orphans] in IfaceSyn
- -- A rule is an orphan only if none of the variables
- -- mentioned on its left-hand side are locally defined
+ -- Compute orphanhood. See Note [Orphans] in IfaceSyn
+ -- A rule is an orphan only if none of the variables
+ -- mentioned on its left-hand side are locally defined
lhs_names = nameSetToList (ruleLhsOrphNames rule)
orph = case filter (nameIsLocalOrFrom mod) lhs_names of
- (n : _) -> Just (nameOccName n)
- [] -> Nothing
+ (n : _) -> Just (nameOccName n)
+ [] -> Nothing
bogusIfaceRule :: Name -> IfaceRule
bogusIfaceRule id_name
= IfaceRule { ifRuleName = fsLit "bogus", ifActivation = NeverActive,
- ifRuleBndrs = [], ifRuleHead = id_name, ifRuleArgs = [],
- ifRuleRhs = IfaceExt id_name, ifRuleOrph = Nothing, ifRuleAuto = True }
+ ifRuleBndrs = [], ifRuleHead = id_name, ifRuleArgs = [],
+ ifRuleRhs = IfaceExt id_name, ifRuleOrph = Nothing, ifRuleAuto = True }
---------------------
toIfaceExpr :: CoreExpr -> IfaceExpr
@@ -1688,14 +1731,14 @@ toIfaceApp :: Expr CoreBndr -> [Arg CoreBndr] -> IfaceExpr
toIfaceApp (App f a) as = toIfaceApp f (a:as)
toIfaceApp (Var v) as
= case isDataConWorkId_maybe v of
- -- We convert the *worker* for tuples into IfaceTuples
- Just dc | isTupleTyCon tc && saturated
- -> IfaceTuple (tupleTyConSort tc) tup_args
- where
- val_args = dropWhile isTypeArg as
- saturated = val_args `lengthIs` idArity v
- tup_args = map toIfaceExpr val_args
- tc = dataConTyCon dc
+ -- We convert the *worker* for tuples into IfaceTuples
+ Just dc | isTupleTyCon tc && saturated
+ -> IfaceTuple (tupleTyConSort tc) tup_args
+ where
+ val_args = dropWhile isTypeArg as
+ saturated = val_args `lengthIs` idArity v
+ tup_args = map toIfaceExpr val_args
+ tc = dataConTyCon dc
_ -> mkIfaceApps (toIfaceVar v) as
@@ -1709,7 +1752,7 @@ toIfaceVar :: Id -> IfaceExpr
toIfaceVar v
| Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType (idType v))
-- Foreign calls have special syntax
- | isExternalName name = IfaceExt name
+ | isExternalName name = IfaceExt name
| otherwise = IfaceLcl (getFS name)
where name = idName v
\end{code}
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index a11051b65f..d17b90d7f3 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -41,7 +41,7 @@ import TyCon
import DataCon
import PrelNames
import TysWiredIn
-import TysPrim ( anyTyConOfKind )
+import TysPrim ( tySuperKindTyCon )
import BasicTypes ( Arity, strongLoopBreaker )
import Literal
import qualified Var
@@ -273,7 +273,7 @@ typecheckIface iface
; anns <- tcIfaceAnnotations (mi_anns iface)
-- Vectorisation information
- ; vect_info <- tcIfaceVectInfo (mi_module iface) (mi_vect_info iface)
+ ; vect_info <- tcIfaceVectInfo (mi_module iface) type_env (mi_vect_info iface)
-- Exports
; exports <- ifaceExportNames (mi_exports iface)
@@ -502,7 +502,9 @@ tc_iface_decl _parent ignore_prags
return tc
tc_iface_at_def (IfaceATD tvs pat_tys ty) =
- bindIfaceTyVars_AT tvs $ \tvs' -> liftM2 (ATD tvs') (mapM tcIfaceType pat_tys) (tcIfaceType ty)
+ bindIfaceTyVars_AT tvs $
+ \tvs' -> liftM2 (\pats tys -> ATD tvs' pats tys noSrcSpan)
+ (mapM tcIfaceType pat_tys) (tcIfaceType ty)
mk_doc op_name op_ty = ptext (sLit "Class op") <+> sep [ppr op_name, ppr op_ty]
@@ -710,14 +712,21 @@ tcIfaceAnnTarget (ModuleTarget mod) = do
%************************************************************************
\begin{code}
-tcIfaceVectInfo :: Module -> IfaceVectInfo -> IfL VectInfo
-tcIfaceVectInfo mod (IfaceVectInfo
- { ifaceVectInfoVar = vars
- , ifaceVectInfoTyCon = tycons
- , ifaceVectInfoTyConReuse = tyconsReuse
- , ifaceVectInfoScalarVars = scalarVars
- , ifaceVectInfoScalarTyCons = scalarTyCons
- })
+-- We need access to the type environment as we need to look up information about type constructors
+-- (i.e., their data constructors and whether they are class type constructors). If a vectorised
+-- type constructor or class is defined in the same module as where it is vectorised, we cannot
+-- look that information up from the type constructor that we obtained via a 'forkM'ed
+-- 'tcIfaceTyCon' without recursively loading the interface that we are already type checking again
+-- and again and again...
+--
+tcIfaceVectInfo :: Module -> TypeEnv -> IfaceVectInfo -> IfL VectInfo
+tcIfaceVectInfo mod typeEnv (IfaceVectInfo
+ { ifaceVectInfoVar = vars
+ , ifaceVectInfoTyCon = tycons
+ , ifaceVectInfoTyConReuse = tyconsReuse
+ , ifaceVectInfoScalarVars = scalarVars
+ , ifaceVectInfoScalarTyCons = scalarTyCons
+ })
= do { let scalarTyConsSet = mkNameSet scalarTyCons
; vVars <- mapM vectVarMapping vars
; tyConRes1 <- mapM vectTyConMapping tycons
@@ -750,8 +759,18 @@ tcIfaceVectInfo mod (IfaceVectInfo
vectTyConMapping name
= do { vName <- lookupOrig mod (mkLocalisedOccName mod mkVectTyConOcc name)
- ; tycon <- forkM (text ("vect tycon") <+> ppr name) $
- tcIfaceTyCon (IfaceTc name)
+
+ -- we need a fully defined version of the type constructor to be able to extract
+ -- its data constructors etc.
+ ; tycon <- do { let mb_tycon = lookupTypeEnv typeEnv name
+ ; case mb_tycon of
+ -- tycon is local
+ Just (ATyCon tycon) -> return tycon
+ -- name is not a tycon => internal inconsistency
+ Just _ -> notATyConErr
+ -- tycon is external
+ Nothing -> tcIfaceTyCon (IfaceTc name)
+ }
; vTycon <- forkM (text ("vect vTycon") <+> ppr vName) $
tcIfaceTyCon (IfaceTc vName)
@@ -764,6 +783,8 @@ tcIfaceVectInfo mod (IfaceVectInfo
, vDataCons -- list of (Ci, Ci_v)
)
}
+ where
+ notATyConErr = pprPanic "TcIface.tcIfaceVectInfo: not a tycon" (ppr name)
vectTyConReuseMapping scalarNames name
= do { tycon <- forkM (text ("vect reuse tycon") <+> ppr name) $
@@ -1235,9 +1256,15 @@ tcIfaceGlobal name
-- emasculated form (e.g. lacking data constructors).
tcIfaceTyCon :: IfaceTyCon -> IfL TyCon
-tcIfaceTyCon (IfaceAnyTc kind) = do { tc_kind <- tcIfaceType kind
- ; tcWiredInTyCon (anyTyConOfKind tc_kind) }
-tcIfaceTyCon (IfaceTc name) = do { thing <- tcIfaceGlobal name
+tcIfaceTyCon IfaceIntTc = tcWiredInTyCon intTyCon
+tcIfaceTyCon IfaceBoolTc = tcWiredInTyCon boolTyCon
+tcIfaceTyCon IfaceCharTc = tcWiredInTyCon charTyCon
+tcIfaceTyCon IfaceListTc = tcWiredInTyCon listTyCon
+tcIfaceTyCon IfacePArrTc = tcWiredInTyCon parrTyCon
+tcIfaceTyCon (IfaceTupTc bx ar) = tcWiredInTyCon (tupleTyCon bx ar)
+tcIfaceTyCon (IfaceIPTc n) = do { n' <- newIPName n
+ ; tcWiredInTyCon (ipTyCon n') }
+tcIfaceTyCon (IfaceTc name) = do { thing <- tcIfaceGlobal name
; return (check_tc (tyThingTyCon thing)) }
where
check_tc tc
@@ -1245,6 +1272,14 @@ tcIfaceTyCon (IfaceTc name) = do { thing <- tcIfaceGlobal name
IfaceTc _ -> tc
_ -> pprTrace "check_tc" (ppr tc) tc
| otherwise = tc
+-- we should be okay just returning Kind constructors without extra loading
+tcIfaceTyCon IfaceLiftedTypeKindTc = return liftedTypeKindTyCon
+tcIfaceTyCon IfaceOpenTypeKindTc = return openTypeKindTyCon
+tcIfaceTyCon IfaceUnliftedTypeKindTc = return unliftedTypeKindTyCon
+tcIfaceTyCon IfaceArgTypeKindTc = return argTypeKindTyCon
+tcIfaceTyCon IfaceUbxTupleKindTc = return ubxTupleKindTyCon
+tcIfaceTyCon IfaceConstraintKindTc = return constraintKindTyCon
+tcIfaceTyCon IfaceSuperKindTc = return tySuperKindTyCon
-- Even though we are in an interface file, we want to make
-- sure the instances and RULES of this tycon are loaded
@@ -1310,12 +1345,22 @@ bindIfaceTyVar (occ,kind) thing_inside
bindIfaceTyVars :: [IfaceTvBndr] -> ([TyVar] -> IfL a) -> IfL a
bindIfaceTyVars bndrs thing_inside
- = do { names <- newIfaceNames (map mkTyVarOccFS occs)
- ; tyvars <- zipWithM mk_iface_tyvar names kinds
- ; extendIfaceTyVarEnv tyvars (thing_inside tyvars) }
+ = do { names <- newIfaceNames (map mkTyVarOccFS occs)
+ ; let (kis_kind, tys_kind) = span isSuperIfaceKind kinds
+ (kis_name, tys_name) = splitAt (length kis_kind) names
+ -- We need to bring the kind variables in scope since type
+ -- variables may mention them.
+ ; kvs <- zipWithM mk_iface_tyvar kis_name kis_kind
+ ; extendIfaceTyVarEnv kvs $ do
+ { tvs <- zipWithM mk_iface_tyvar tys_name tys_kind
+ ; extendIfaceTyVarEnv tvs (thing_inside (kvs ++ tvs)) } }
where
(occs,kinds) = unzip bndrs
+isSuperIfaceKind :: IfaceKind -> Bool
+isSuperIfaceKind (IfaceTyConApp IfaceSuperKindTc []) = True
+isSuperIfaceKind _ = False
+
mk_iface_tyvar :: Name -> IfaceKind -> IfL TyVar
mk_iface_tyvar name ifKind
= do { kind <- tcIfaceType ifKind
@@ -1328,12 +1373,14 @@ bindIfaceTyVars_AT :: [IfaceTvBndr] -> ([TyVar] -> IfL a) -> IfL a
-- Here 'a' is in scope when we look at the 'data T'
bindIfaceTyVars_AT [] thing_inside
= thing_inside []
-bindIfaceTyVars_AT (b@(tv_occ,_) : bs) thing_inside
- = bindIfaceTyVars_AT bs $ \ bs' ->
- do { mb_tv <- lookupIfaceTyVar tv_occ
- ; case mb_tv of
- Just b' -> thing_inside (b':bs')
- Nothing -> bindIfaceTyVar b $ \ b' ->
- thing_inside (b':bs') }
-\end{code}
+bindIfaceTyVars_AT (b@(tv_occ,_) : bs) thing_inside
+ = do { mb_tv <- lookupIfaceTyVar tv_occ
+ ; let bind_b :: (TyVar -> IfL a) -> IfL a
+ bind_b = case mb_tv of
+ Just b' -> \k -> k b'
+ Nothing -> bindIfaceTyVar b
+ ; bind_b $ \b' ->
+ bindIfaceTyVars_AT bs $ \bs' ->
+ thing_inside (b':bs') }
+\end{code}
diff --git a/compiler/iface/TcIface.lhs-boot b/compiler/iface/TcIface.lhs-boot
index fd2b647046..a9684a6a91 100644
--- a/compiler/iface/TcIface.lhs-boot
+++ b/compiler/iface/TcIface.lhs-boot
@@ -7,13 +7,13 @@ import TcRnTypes ( IfL )
import InstEnv ( Instance )
import FamInstEnv ( FamInst )
import CoreSyn ( CoreRule )
-import HscTypes ( VectInfo, IfaceVectInfo )
+import HscTypes ( TypeEnv, VectInfo, IfaceVectInfo )
import Module ( Module )
import Annotations ( Annotation )
tcIfaceDecl :: Bool -> IfaceDecl -> IfL TyThing
tcIfaceRules :: Bool -> [IfaceRule] -> IfL [CoreRule]
-tcIfaceVectInfo :: Module -> IfaceVectInfo -> IfL VectInfo
+tcIfaceVectInfo :: Module -> TypeEnv -> IfaceVectInfo -> IfL VectInfo
tcIfaceInst :: IfaceInst -> IfL Instance
tcIfaceFamInst :: IfaceFamInst -> IfL FamInst
tcIfaceAnnotations :: [IfaceAnnotation] -> IfL [Annotation]
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 8037cfb21f..8c0f3a6098 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -138,7 +138,8 @@ compile' (nothingCompiler, interactiveCompiler, batchCompiler)
-- This is needed when we try to compile the .hc file later, if it
-- imports a _stub.h file that we created here.
let current_dir = case takeDirectory basename of
- "" -> "." -- XXX Hack
+ "" -> "." -- XXX Hack required for filepath-1.1 and earlier
+ -- (GHC 6.12 and earlier)
d -> d
old_paths = includePaths dflags0
dflags = dflags0 { includePaths = current_dir : old_paths }
@@ -839,8 +840,9 @@ runPhase (Hsc src_flavour) input_fn dflags0
-- the .hs files resides) to the include path, since this is
-- what gcc does, and it's probably what you want.
let current_dir = case takeDirectory basename of
- "" -> "." -- XXX Hack
- d -> d
+ "" -> "." -- XXX Hack required for filepath-1.1 and earlier
+ -- (GHC 6.12 and earlier)
+ d -> d
paths = includePaths dflags0
dflags = dflags0 { includePaths = current_dir : paths }
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 2ece4763c5..2c0cccb0ba 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -37,7 +37,6 @@ module DynFlags (
Option(..), showOpt,
DynLibLoader(..),
fFlags, fWarningFlags, fLangFlags, xFlags,
- DPHBackend(..), dphPackageMaybe,
wayNames, dynFlagDependencies,
-- ** Safe Haskell
@@ -341,6 +340,7 @@ data WarningFlag =
deriving (Eq, Show)
data Language = Haskell98 | Haskell2010
+ deriving Enum
-- | The various Safe Haskell modes
data SafeHaskellMode
@@ -393,7 +393,8 @@ data ExtensionFlag
| Opt_DoAndIfThenElse
| Opt_RebindableSyntax
| Opt_ConstraintKinds
-
+ | Opt_PolyKinds -- Kind polymorphism
+
| Opt_StandaloneDeriving
| Opt_DeriveDataTypeable
| Opt_DeriveFunctor
@@ -436,7 +437,7 @@ data ExtensionFlag
| Opt_NondecreasingIndentation
| Opt_RelaxedLayout
| Opt_TraditionalRecordSyntax
- deriving (Eq, Show)
+ deriving (Eq, Enum, Show)
-- | Contains not only a collection of 'DynFlag's but also a plethora of
-- information relating to the compilation of a single file or GHC session
@@ -467,8 +468,6 @@ data DynFlags = DynFlags {
mainFunIs :: Maybe String,
ctxtStkDepth :: Int, -- ^ Typechecker context stack depth
- dphBackend :: DPHBackend,
-
thisPackage :: PackageId, -- ^ name of package currently being compiled
-- ways
@@ -841,8 +840,6 @@ defaultDynFlags mySettings =
mainFunIs = Nothing,
ctxtStkDepth = mAX_CONTEXT_REDUCTION_DEPTH,
- dphBackend = DPHNone,
-
thisPackage = mainPackageId,
objectDir = Nothing,
@@ -1622,13 +1619,6 @@ dynamic_flags = [
, Flag "fprof-auto-exported" (noArg (\d -> d { profAuto = ProfAutoExports } ))
, Flag "fno-prof-auto" (noArg (\d -> d { profAuto = NoProfAuto } ))
- ------ DPH flags ----------------------------------------------------
-
- , Flag "fdph-seq" (NoArg (setDPHBackend DPHSeq))
- , Flag "fdph-par" (NoArg (setDPHBackend DPHPar))
- , Flag "fdph-this" (NoArg (setDPHBackend DPHThis))
- , Flag "fdph-none" (NoArg (setDPHBackend DPHNone))
-
------ Compiler flags -----------------------------------------------
, Flag "fasm" (NoArg (setObjTarget HscAsm))
@@ -1915,7 +1905,8 @@ xFlags = [
( "DoAndIfThenElse", Opt_DoAndIfThenElse, nop ),
( "RebindableSyntax", Opt_RebindableSyntax, nop ),
( "ConstraintKinds", Opt_ConstraintKinds, nop ),
- ( "MonoPatBinds", Opt_MonoPatBinds,
+ ( "PolyKinds", Opt_PolyKinds, nop ),
+ ( "MonoPatBinds", Opt_MonoPatBinds,
\ turn_on -> when turn_on $ deprecate "Experimental feature now removed; has no effect" ),
( "ExplicitForAll", Opt_ExplicitForAll, nop ),
( "AlternativeLayoutRule", Opt_AlternativeLayoutRule, nop ),
@@ -1999,7 +1990,9 @@ impliedFlags
, (Opt_TypeFamilies, turnOn, Opt_MonoLocalBinds)
, (Opt_TypeFamilies, turnOn, Opt_KindSignatures) -- Type families use kind signatures
- -- all over the place
+ -- all over the place
+
+ , (Opt_PolyKinds, turnOn, Opt_KindSignatures)
, (Opt_ImpredicativeTypes, turnOn, Opt_RankNTypes)
@@ -2358,29 +2351,6 @@ setDPHOpt dflags = setOptLevel 2 (dflags { maxSimplIterations = 20
, simplPhases = 3
})
--- Determines the package used by the vectoriser for the symbols of the vectorised code.
--- 'DPHNone' indicates that no data-parallel backend library is available; hence, the
--- vectoriser cannot be used.
---
-data DPHBackend = DPHPar -- "dph-par"
- | DPHSeq -- "dph-seq"
- | DPHThis -- the currently compiled package
- | DPHNone -- no DPH library available
- deriving(Eq, Ord, Enum, Show)
-
-setDPHBackend :: DPHBackend -> DynP ()
-setDPHBackend backend = upd $ \dflags -> dflags { dphBackend = backend }
-
--- Query the DPH backend package to be used by the vectoriser and desugaring of DPH syntax.
---
-dphPackageMaybe :: DynFlags -> Maybe PackageId
-dphPackageMaybe dflags
- = case dphBackend dflags of
- DPHPar -> Just dphParPackageId
- DPHSeq -> Just dphSeqPackageId
- DPHThis -> Just (thisPackage dflags)
- DPHNone -> Nothing
-
setMainIs :: String -> DynP ()
setMainIs arg
| not (null main_fn) && isLower (head main_fn)
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs
index 039e8f15ba..d60e6d7f59 100644
--- a/compiler/main/GHC.hs
+++ b/compiler/main/GHC.hs
@@ -264,7 +264,7 @@ import RdrName
import qualified HsSyn -- hack as we want to reexport the whole module
import HsSyn hiding ((<.>))
import Type hiding( typeKind )
-import Coercion ( synTyConResKind )
+import Kind ( synTyConResKind )
import TcType hiding( typeKind )
import Id
import TysPrim ( alphaTyVars )
@@ -881,7 +881,7 @@ compileCore simplify fn = do
gutsToCoreModule (Right mg) = CoreModule {
cm_module = mg_module mg,
cm_types = typeEnvFromEntities (bindersOfBinds (mg_binds mg))
- (mg_tcs mg) (mg_clss mg)
+ (mg_tcs mg)
(mg_fam_insts mg),
cm_binds = mg_binds mg
}
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index 753f044b71..ca524aa24b 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -83,7 +83,6 @@ import DsMeta ( templateHaskellNames )
import VarSet
import VarEnv ( emptyTidyEnv )
import Panic
-import Class
import Data.List
#endif
@@ -1384,8 +1383,7 @@ hscDeclsWithLocation hsc_env str source linenumber = runHsc hsc_env $ do
hsc_env <- getHscEnv
liftIO $ linkDecls hsc_env src_span cbc
- let tcs = filter (not . isImplicitTyCon) $ mg_tcs simpl_mg
- clss = mg_clss simpl_mg
+ let tcs = filter (not . isImplicitTyCon) $ (mg_tcs simpl_mg)
ext_vars = filter (isExternalName . idName) $
bindersOfBinds core_binds
@@ -1400,7 +1398,6 @@ hscDeclsWithLocation hsc_env str source linenumber = runHsc hsc_env $ do
tythings = map AnId user_vars
++ map ATyCon tcs
- ++ map (ATyCon . classTyCon) clss
let ictxt1 = extendInteractiveContext icontext tythings
ictxt = ictxt1 { ic_sys_vars = sys_vars ++ ic_sys_vars ictxt1,
@@ -1506,7 +1503,6 @@ mkModGuts mod binds =
mg_rdr_env = emptyGlobalRdrEnv,
mg_fix_env = emptyFixityEnv,
mg_tcs = [],
- mg_clss = [],
mg_insts = [],
mg_fam_insts = [],
mg_rules = [],
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index 14d1469ebe..3391f6a5ed 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -114,15 +114,15 @@ import {-# SOURCE #-} InteractiveEval ( Resume )
import HsSyn
import RdrName
-import Name
import Avail
-import NameEnv
-import NameSet
import Module
import InstEnv ( InstEnv, Instance )
import FamInstEnv
import Rules ( RuleBase )
import CoreSyn ( CoreProgram )
+import Name
+import NameEnv
+import NameSet
import VarEnv
import VarSet
import Var
@@ -135,7 +135,7 @@ import Class
import TyCon
import DataCon
import PrelNames ( gHC_PRIM )
-import Packages hiding ( Version(..) )
+import Packages hiding ( Version(..) )
import DynFlags
import DriverPhases
import BasicTypes
@@ -157,15 +157,15 @@ import Bag
import ErrUtils
import Util
-import System.FilePath
-import System.Time ( ClockTime )
-import Data.IORef
+import Control.Monad ( mplus, guard, liftM, when )
import Data.Array ( Array, array )
+import Data.IORef
import Data.Map ( Map )
import Data.Word
-import Control.Monad ( mplus, guard, liftM, when )
-import Exception
import Data.Typeable ( Typeable )
+import Exception
+import System.FilePath
+import System.Time ( ClockTime )
-- -----------------------------------------------------------------------------
-- Source Errors
@@ -174,8 +174,13 @@ import Data.Typeable ( Typeable )
-- exception in the IO monad.
mkSrcErr :: ErrorMessages -> SourceError
+mkSrcErr = SourceError
+
srcErrorMessages :: SourceError -> ErrorMessages
+srcErrorMessages (SourceError msgs) = msgs
+
mkApiErr :: SDoc -> GhcApiError
+mkApiErr = GhcApiError
throwOneError :: MonadIO m => ErrMsg -> m ab
throwOneError err = liftIO $ throwIO $ mkSrcErr $ unitBag err
@@ -201,12 +206,9 @@ newtype SourceError = SourceError ErrorMessages
instance Show SourceError where
show (SourceError msgs) = unlines . map show . bagToList $ msgs
- -- ToDo: is there some nicer way to print this?
instance Exception SourceError
-mkSrcErr = SourceError
-
-- | Perform the given action and call the exception handler if the action
-- throws a 'SourceError'. See 'SourceError' for more information.
handleSourceError :: (ExceptionMonad m) =>
@@ -216,19 +218,15 @@ handleSourceError :: (ExceptionMonad m) =>
handleSourceError handler act =
gcatch act (\(e :: SourceError) -> handler e)
-srcErrorMessages (SourceError msgs) = msgs
-
--- | XXX: what exactly is an API error?
+-- | An error thrown if the GHC API is used in an incorrect fashion.
newtype GhcApiError = GhcApiError SDoc
- deriving Typeable
+ deriving Typeable
instance Show GhcApiError where
show (GhcApiError msg) = showSDoc msg
instance Exception GhcApiError
-mkApiErr = GhcApiError
-
-- | Given a bag of warnings, turn them into an exception if
-- -Werror is enabled, or print them out otherwise.
printOrThrowWarnings :: DynFlags -> Bag WarnMsg -> IO ()
@@ -250,7 +248,14 @@ handleFlagWarnings dflags warns
printOrThrowWarnings dflags bag
\end{code}
+%************************************************************************
+%* *
+\subsection{HscEnv}
+%* *
+%************************************************************************
+
\begin{code}
+
-- | Hscenv is like 'Session', except that some of the fields are immutable.
-- An HscEnv is used to compile a single module from plain Haskell source
-- code (after preprocessing) to either C, assembly or C--. Things like
@@ -280,10 +285,10 @@ data HscEnv
-- home-package modules, /excluding/ the module we
-- are compiling right now.
-- (In one-shot mode the current module is the only
- -- home-package module, so hsc_HPT is empty. All other
- -- modules count as \"external-package\" modules.
- -- However, even in GHCi mode, hi-boot interfaces are
- -- demand-loaded into the external-package table.)
+ -- home-package module, so hsc_HPT is empty. All other
+ -- modules count as \"external-package\" modules.
+ -- However, even in GHCi mode, hi-boot interfaces are
+ -- demand-loaded into the external-package table.)
--
-- 'hsc_HPT' is not mutable because we only demand-load
-- external packages; the home package is eagerly
@@ -292,7 +297,7 @@ data HscEnv
-- The HPT may contain modules compiled earlier by @--make@
-- but not actually below the current module in the dependency
-- graph.
-
+ --
-- (This changes a previous invariant: changed Jan 05.)
hsc_EPS :: {-# UNPACK #-} !(IORef ExternalPackageState),
@@ -344,12 +349,13 @@ hscEPS hsc_env = readIORef (hsc_EPS hsc_env)
-- module. If so, use this instead of the file contents (this
-- is for use in an IDE where the file hasn't been saved by
-- the user yet).
-data Target = Target
- { targetId :: TargetId -- ^ module or filename
- , targetAllowObjCode :: Bool -- ^ object code allowed?
- , targetContents :: Maybe (StringBuffer,ClockTime)
+data Target
+ = Target {
+ targetId :: TargetId, -- ^ module or filename
+ targetAllowObjCode :: Bool, -- ^ object code allowed?
+ targetContents :: Maybe (StringBuffer,ClockTime)
-- ^ in-memory text buffer?
- }
+ }
data TargetId
= TargetModule ModuleName
@@ -363,7 +369,7 @@ data TargetId
pprTarget :: Target -> SDoc
pprTarget (Target id obj _) =
- (if obj then char '*' else empty) <> pprTargetId id
+ (if obj then char '*' else empty) <> pprTargetId id
instance Outputable Target where
ppr = pprTarget
@@ -374,7 +380,15 @@ pprTargetId (TargetFile f _) = text f
instance Outputable TargetId where
ppr = pprTargetId
+\end{code}
+%************************************************************************
+%* *
+\subsection{Package and Module Tables}
+%* *
+%************************************************************************
+
+\begin{code}
-- | Helps us find information about modules in the home package
type HomePackageTable = ModuleNameEnv HomeModInfo
-- Domain = modules in the home package that have been fully compiled
@@ -384,9 +398,11 @@ type HomePackageTable = ModuleNameEnv HomeModInfo
type PackageIfaceTable = ModuleEnv ModIface
-- Domain = modules in the imported packages
+-- | Constructs an empty HomePackageTable
emptyHomePackageTable :: HomePackageTable
emptyHomePackageTable = emptyUFM
+-- | Constructs an empty PackageIfaceTable
emptyPackageIfaceTable :: PackageIfaceTable
emptyPackageIfaceTable = emptyModuleEnv
@@ -428,10 +444,10 @@ lookupIfaceByModule
-> Maybe ModIface
lookupIfaceByModule dflags hpt pit mod
| modulePackageId mod == thisPackage dflags
- = -- The module comes from the home package, so look first
+ -- The module comes from the home package, so look first
-- in the HPT. If it's not from the home package it's wrong to look
-- in the HPT, because the HPT is indexed by *ModuleName* not Module
- fmap hm_iface (lookupUFM hpt (moduleName mod))
+ = fmap hm_iface (lookupUFM hpt (moduleName mod))
`mplus` lookupModuleEnv pit mod
| otherwise = lookupModuleEnv pit mod -- Look in PIT only
@@ -442,15 +458,13 @@ lookupIfaceByModule dflags hpt pit mod
-- module is in the PIT, namely GHC.Prim when compiling the base package.
-- We could eliminate (b) if we wanted, by making GHC.Prim belong to a package
-- of its own, but it doesn't seem worth the bother.
-\end{code}
-\begin{code}
-hptInstances :: HscEnv -> (ModuleName -> Bool) -> ([Instance], [FamInst])
--- ^ Find all the instance declarations (of classes and families) that are in
+-- | Find all the instance declarations (of classes and families) that are in
-- modules imported by this one, directly or indirectly, and are in the Home
-- Package Table. This ensures that we don't see instances from modules @--make@
-- compiled before this one, but which are not below this one.
+hptInstances :: HscEnv -> (ModuleName -> Bool) -> ([Instance], [FamInst])
hptInstances hsc_env want_this_module
= let (insts, famInsts) = unzip $ flip hptAllThings hsc_env $ \mod_info -> do
guard (want_this_module (moduleName (mi_module (hm_iface mod_info))))
@@ -458,34 +472,34 @@ hptInstances hsc_env want_this_module
return (md_insts details, md_fam_insts details)
in (concat insts, concat famInsts)
-hptVectInfo :: HscEnv -> VectInfo
--- ^ Get the combined VectInfo of all modules in the home package table. In
+-- | Get the combined VectInfo of all modules in the home package table. In
-- contrast to instances and rules, we don't care whether the modules are
--- \"below\" us in the dependency sense. The VectInfo of those modules not \"below\"
+-- "below" us in the dependency sense. The VectInfo of those modules not "below"
-- us does not affect the compilation of the current module.
+hptVectInfo :: HscEnv -> VectInfo
hptVectInfo = concatVectInfo . hptAllThings ((: []) . md_vect_info . hm_details)
+-- | Get rules from modules "below" this one (in the dependency sense)
hptRules :: HscEnv -> [(ModuleName, IsBootInterface)] -> [CoreRule]
--- ^ Get rules from modules \"below\" this one (in the dependency sense)
hptRules = hptSomeThingsBelowUs (md_rules . hm_details) False
+-- | Get annotations from modules "below" this one (in the dependency sense)
hptAnns :: HscEnv -> Maybe [(ModuleName, IsBootInterface)] -> [Annotation]
--- ^ Get annotations from modules \"below\" this one (in the dependency sense)
hptAnns hsc_env (Just deps) = hptSomeThingsBelowUs (md_anns . hm_details) False hsc_env deps
hptAnns hsc_env Nothing = hptAllThings (md_anns . hm_details) hsc_env
hptAllThings :: (HomeModInfo -> [a]) -> HscEnv -> [a]
hptAllThings extract hsc_env = concatMap extract (eltsUFM (hsc_HPT hsc_env))
-hptSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> [(ModuleName, IsBootInterface)] -> [a]
--- Get things from modules \"below\" this one (in the dependency sense)
+-- | Get things from modules "below" this one (in the dependency sense)
-- C.f Inst.hptInstances
+hptSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> [(ModuleName, IsBootInterface)] -> [a]
hptSomeThingsBelowUs extract include_hi_boot hsc_env deps
- | isOneShot (ghcMode (hsc_dflags hsc_env)) = []
+ | isOneShot (ghcMode (hsc_dflags hsc_env)) = []
+
| otherwise
- = let
- hpt = hsc_HPT hsc_env
+ = let hpt = hsc_HPT hsc_env
in
[ thing
| -- Find each non-hi-boot module below me
@@ -493,10 +507,9 @@ hptSomeThingsBelowUs extract include_hi_boot hsc_env deps
, include_hi_boot || not is_boot_mod
-- unsavoury: when compiling the base package with --make, we
- -- sometimes try to look up RULES etc for GHC.Prim. GHC.Prim won't
+ -- sometimes try to look up RULES etc for GHC.Prim. GHC.Prim won't
-- be in the HPT, because we never compile it; it's in the EPT
- -- instead. ToDo: clean up, and remove this slightly bogus
- -- filter:
+ -- instead. ToDo: clean up, and remove this slightly bogus filter:
, mod /= moduleName gHC_PRIM
-- Look it up in the HPT
@@ -521,23 +534,22 @@ hptObjs hpt = concat (map (maybe [] linkableObjs . hm_linkable) (eltsUFM hpt))
%************************************************************************
\begin{code}
-prepareAnnotations :: HscEnv -> Maybe ModGuts -> IO AnnEnv
--- ^ Deal with gathering annotations in from all possible places
+-- | Deal with gathering annotations in from all possible places
-- and combining them into a single 'AnnEnv'
-prepareAnnotations hsc_env mb_guts
- = do { eps <- hscEPS hsc_env
- ; let -- Extract annotations from the module being compiled if supplied one
- mb_this_module_anns = fmap (mkAnnEnv . mg_anns) mb_guts
+prepareAnnotations :: HscEnv -> Maybe ModGuts -> IO AnnEnv
+prepareAnnotations hsc_env mb_guts = do
+ eps <- hscEPS hsc_env
+ let -- Extract annotations from the module being compiled if supplied one
+ mb_this_module_anns = fmap (mkAnnEnv . mg_anns) mb_guts
-- Extract dependencies of the module if we are supplied one,
-- otherwise load annotations from all home package table
-- entries regardless of dependency ordering.
- home_pkg_anns = (mkAnnEnv . hptAnns hsc_env) $ fmap (dep_mods . mg_deps) mb_guts
- other_pkg_anns = eps_ann_env eps
- ann_env = foldl1' plusAnnEnv $ catMaybes [mb_this_module_anns,
- Just home_pkg_anns,
- Just other_pkg_anns]
-
- ; return ann_env }
+ home_pkg_anns = (mkAnnEnv . hptAnns hsc_env) $ fmap (dep_mods . mg_deps) mb_guts
+ other_pkg_anns = eps_ann_env eps
+ ann_env = foldl1' plusAnnEnv $ catMaybes [mb_this_module_anns,
+ Just home_pkg_anns,
+ Just other_pkg_anns]
+ return ann_env
\end{code}
%************************************************************************
@@ -548,11 +560,11 @@ prepareAnnotations hsc_env mb_guts
\begin{code}
-- | The 'FinderCache' maps home module names to the result of
--- searching for that module. It records the results of searching for
--- modules along the search path. On @:load@, we flush the entire
+-- searching for that module. It records the results of searching for
+-- modules along the search path. On @:load@, we flush the entire
-- contents of this cache.
--
--- Although the @FinderCache@ range is 'FindResult' for convenience ,
+-- Although the @FinderCache@ range is 'FindResult' for convenience,
-- in fact it will only ever contain 'Found' or 'NotFound' entries.
--
type FinderCache = ModuleNameEnv FindResult
@@ -565,8 +577,9 @@ data FindResult
-- ^ The requested package was not found
| FoundMultiple [PackageId]
-- ^ _Error_: both in multiple packages
-
- | NotFound -- Not found
+
+ -- | Not found
+ | NotFound
{ fr_paths :: [FilePath] -- Places where I looked
, fr_pkg :: Maybe PackageId -- Just p => module is in this package's
@@ -605,14 +618,16 @@ type ModLocationCache = ModuleEnv ModLocation
-- as when reading we consolidate the declarations etc. into a number of indexed
-- maps and environments in the 'ExternalPackageState'.
data ModIface
- = ModIface {
- mi_module :: !Module, -- ^ Name of the module we are for
- mi_iface_hash :: !Fingerprint, -- ^ Hash of the whole interface
- mi_mod_hash :: !Fingerprint, -- ^ Hash of the ABI only
+ = ModIface {
+ mi_module :: !Module, -- ^ Name of the module we are for
+ mi_iface_hash :: !Fingerprint, -- ^ Hash of the whole interface
+ mi_mod_hash :: !Fingerprint, -- ^ Hash of the ABI only
+ mi_flag_hash :: !Fingerprint, -- ^ Hash of the important flags
+ -- used when compiling this module
- mi_orphan :: !WhetherHasOrphans, -- ^ Whether this module has orphans
- mi_finsts :: !WhetherHasFamInst, -- ^ Whether this module has family instances
- mi_boot :: !IsBootInterface, -- ^ Read from an hi-boot file?
+ mi_orphan :: !WhetherHasOrphans, -- ^ Whether this module has orphans
+ mi_finsts :: !WhetherHasFamInst, -- ^ Whether this module has family instances
+ mi_boot :: !IsBootInterface, -- ^ Read from an hi-boot file?
mi_deps :: Dependencies,
-- ^ The dependencies of the module. This is
@@ -623,41 +638,41 @@ data ModIface
-- ^ Usages; kept sorted so that it's easy to decide
-- whether to write a new iface file (changing usages
-- doesn't affect the hash of this module)
-
-- NOT STRICT! we read this field lazily from the interface file
-- It is *only* consulted by the recompilation checker
- -- Exports
- -- Kept sorted by (mod,occ), to make version comparisons easier
mi_exports :: ![IfaceExport],
- -- ^ Records the modules that are the declaration points for things
+ -- ^ Exports
+ -- Kept sorted by (mod,occ), to make version comparisons easier
+ -- Records the modules that are the declaration points for things
-- exported by this module, and the 'OccName's of those things
- mi_exp_hash :: !Fingerprint, -- ^ Hash of export list
+ mi_exp_hash :: !Fingerprint,
+ -- ^ Hash of export list
- mi_used_th :: !Bool, -- ^ Module required TH splices when it was compiled. This disables recompilation avoidance (see #481).
+ mi_used_th :: !Bool,
+ -- ^ Module required TH splices when it was compiled.
+ -- This disables recompilation avoidance (see #481).
mi_fixities :: [(OccName,Fixity)],
-- ^ Fixities
-
-- NOT STRICT! we read this field lazily from the interface file
- mi_warns :: Warnings,
+ mi_warns :: Warnings,
-- ^ Warnings
-
-- NOT STRICT! we read this field lazily from the interface file
- mi_anns :: [IfaceAnnotation],
+ mi_anns :: [IfaceAnnotation],
-- ^ Annotations
-
-- NOT STRICT! we read this field lazily from the interface file
- -- Type, class and variable declarations
+
+ mi_decls :: [(Fingerprint,IfaceDecl)],
+ -- ^ Type, class and variable declarations
-- The hash of an Id changes if its fixity or deprecations change
-- (as well as its type of course)
-- Ditto data constructors, class operations, except that
-- the hash of the parent class/tycon changes
- mi_decls :: [(Fingerprint,IfaceDecl)], -- ^ Sorted type, variable, class etc. declarations
mi_globals :: !(Maybe GlobalRdrEnv),
-- ^ Binds all the things defined at the top level in
@@ -675,30 +690,32 @@ data ModIface
-- 'HomeModInfo', but that leads to more plumbing.
-- Instance declarations and rules
- mi_insts :: [IfaceInst], -- ^ Sorted class instance
- mi_fam_insts :: [IfaceFamInst], -- ^ Sorted family instances
- mi_rules :: [IfaceRule], -- ^ Sorted rules
- mi_orphan_hash :: !Fingerprint, -- ^ Hash for orphan rules and
- -- class and family instances
- -- combined
+ mi_insts :: [IfaceInst], -- ^ Sorted class instance
+ mi_fam_insts :: [IfaceFamInst], -- ^ Sorted family instances
+ mi_rules :: [IfaceRule], -- ^ Sorted rules
+ mi_orphan_hash :: !Fingerprint, -- ^ Hash for orphan rules and class
+ -- and family instances combined
- mi_vect_info :: !IfaceVectInfo, -- ^ Vectorisation information
+ mi_vect_info :: !IfaceVectInfo, -- ^ Vectorisation information
-- Cached environments for easy lookup
-- These are computed (lazily) from other fields
-- and are not put into the interface file
- mi_warn_fn :: Name -> Maybe WarningTxt, -- ^ Cached lookup for 'mi_warns'
- mi_fix_fn :: OccName -> Fixity, -- ^ Cached lookup for 'mi_fixities'
- mi_hash_fn :: OccName -> Maybe (OccName, Fingerprint),
- -- ^ Cached lookup for 'mi_decls'.
- -- The @Nothing@ in 'mi_hash_fn' means that the thing
- -- isn't in decls. It's useful to know that when
- -- seeing if we are up to date wrt. the old interface.
- -- The 'OccName' is the parent of the name, if it has one.
- mi_hpc :: !AnyHpcUsage,
+ mi_warn_fn :: Name -> Maybe WarningTxt, -- ^ Cached lookup for 'mi_warns'
+ mi_fix_fn :: OccName -> Fixity, -- ^ Cached lookup for 'mi_fixities'
+ mi_hash_fn :: OccName -> Maybe (OccName, Fingerprint),
+ -- ^ Cached lookup for 'mi_decls'.
+ -- The @Nothing@ in 'mi_hash_fn' means that the thing
+ -- isn't in decls. It's useful to know that when
+ -- seeing if we are up to date wrt. the old interface.
+ -- The 'OccName' is the parent of the name, if it has one.
+
+ mi_hpc :: !AnyHpcUsage,
-- ^ True if this program uses Hpc at any point in the program.
- mi_trust :: !IfaceTrustInfo,
+
+ mi_trust :: !IfaceTrustInfo,
-- ^ Safe Haskell Trust information for this module.
+
mi_trust_pkg :: !Bool
-- ^ Do we require the package this module resides in be trusted
-- to trust this module? This is used for the situation where a
@@ -711,11 +728,43 @@ data ModIface
-- | The original names declared of a certain module that are exported
type IfaceExport = AvailInfo
+-- | Constructs an empty ModIface
+emptyModIface :: Module -> ModIface
+emptyModIface mod
+ = ModIface { mi_module = mod,
+ mi_iface_hash = fingerprint0,
+ mi_mod_hash = fingerprint0,
+ mi_flag_hash = fingerprint0,
+ mi_orphan = False,
+ mi_finsts = False,
+ mi_boot = False,
+ mi_deps = noDependencies,
+ mi_usages = [],
+ mi_exports = [],
+ mi_exp_hash = fingerprint0,
+ mi_used_th = False,
+ mi_fixities = [],
+ mi_warns = NoWarnings,
+ mi_anns = [],
+ mi_insts = [],
+ mi_fam_insts = [],
+ mi_rules = [],
+ mi_decls = [],
+ mi_globals = Nothing,
+ mi_orphan_hash = fingerprint0,
+ mi_vect_info = noIfaceVectInfo,
+ mi_warn_fn = emptyIfaceWarnCache,
+ mi_fix_fn = emptyIfaceFixCache,
+ mi_hash_fn = emptyIfaceHashCache,
+ mi_hpc = False,
+ mi_trust = noIfaceTrustInfo,
+ mi_trust_pkg = False }
+
-- | The 'ModDetails' is essentially a cache for information in the 'ModIface'
-- for home modules only. Information relating to packages will be loaded into
-- global environments in 'ExternalPackageState'.
data ModDetails
- = ModDetails {
+ = ModDetails {
-- The next two fields are created by the typechecker
md_exports :: [AvailInfo],
md_types :: !TypeEnv, -- ^ Local type environment for this particular module
@@ -727,23 +776,21 @@ data ModDetails
md_vect_info :: !VectInfo -- ^ Module vectorisation information
}
+-- | Constructs an empty ModDetails
emptyModDetails :: ModDetails
-emptyModDetails = ModDetails { md_types = emptyTypeEnv,
- md_exports = [],
- md_insts = [],
- md_rules = [],
- md_fam_insts = [],
- md_anns = [],
- md_vect_info = noVectInfo
- }
+emptyModDetails
+ = ModDetails { md_types = emptyTypeEnv,
+ md_exports = [],
+ md_insts = [],
+ md_rules = [],
+ md_fam_insts = [],
+ md_anns = [],
+ md_vect_info = noVectInfo }
-- | Records the modules directly imported by a module for extracting e.g. usage information
type ImportedMods = ModuleEnv [ImportedModsVal]
type ImportedModsVal = (ModuleName, Bool, SrcSpan, IsSafeImport)
--- TODO: we are not actually using the codomain of this type at all, so it can be
--- replaced with ModuleEnv ()
-
-- | A ModGuts is carried through the compiler, accumulating stuff as it goes
-- There is only one ModGuts at any time, the one for the module
-- being compiled right now. Once it is compiled, a 'ModIface' and
@@ -764,9 +811,9 @@ data ModGuts
-- These fields all describe the things **declared in this module**
mg_fix_env :: !FixityEnv, -- ^ Fixities declared in this module
- -- TODO: I'm unconvinced this is actually used anywhere
+ -- ToDo: I'm unconvinced this is actually used anywhere
mg_tcs :: ![TyCon], -- ^ TyCons declared in this module
- mg_clss :: ![Class], -- ^ Classes declared in this module
+ -- (includes TyCons for classes)
mg_insts :: ![Instance], -- ^ Class instances declared in this module
mg_fam_insts :: ![FamInst], -- ^ Family instances declared in this module
mg_rules :: ![CoreRule], -- ^ Before the core pipeline starts, contains
@@ -792,7 +839,7 @@ data ModGuts
mg_fam_inst_env :: FamInstEnv,
-- ^ Type-family instance enviroment for /home-package/ modules
-- (including this one); c.f. 'tcg_fam_inst_env'
- mg_trust_pkg :: Bool,
+ mg_trust_pkg :: Bool,
-- ^ Do we need to trust our own package for Safe Haskell?
-- See Note [RnNames . Trust Own Package]
mg_dependent_files :: [FilePath] -- ^ dependencies from addDependentFile
@@ -814,81 +861,48 @@ data ModGuts
-- | A restricted form of 'ModGuts' for code generation purposes
data CgGuts
= CgGuts {
- cg_module :: !Module, -- ^ Module being compiled
+ cg_module :: !Module,
+ -- ^ Module being compiled
- cg_tycons :: [TyCon],
+ cg_tycons :: [TyCon],
-- ^ Algebraic data types (including ones that started
-- life as classes); generate constructors and info
-- tables. Includes newtypes, just for the benefit of
-- External Core
- cg_binds :: CoreProgram,
+ cg_binds :: CoreProgram,
-- ^ The tidied main bindings, including
-- previously-implicit bindings for record and class
-- selectors, and data construtor wrappers. But *not*
-- data constructor workers; reason: we we regard them
-- as part of the code-gen of tycons
- cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs
- cg_dep_pkgs :: ![PackageId], -- ^ Dependent packages, used to
- -- generate #includes for C code gen
- cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information
- cg_modBreaks :: !ModBreaks -- ^ Module breakpoints
+ cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs
+ cg_dep_pkgs :: ![PackageId], -- ^ Dependent packages, used to
+ -- generate #includes for C code gen
+ cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information
+ cg_modBreaks :: !ModBreaks -- ^ Module breakpoints
}
-----------------------------------
-- | Foreign export stubs
-data ForeignStubs = NoStubs -- ^ We don't have any stubs
- | ForeignStubs
- SDoc
- SDoc
- -- ^ There are some stubs. Parameters:
- --
- -- 1) Header file prototypes for
- -- "foreign exported" functions
- --
- -- 2) C stubs to use when calling
- -- "foreign exported" functions
+data ForeignStubs
+ = NoStubs
+ -- ^ We don't have any stubs
+ | ForeignStubs SDoc SDoc
+ -- ^ There are some stubs. Parameters:
+ --
+ -- 1) Header file prototypes for
+ -- "foreign exported" functions
+ --
+ -- 2) C stubs to use when calling
+ -- "foreign exported" functions
appendStubC :: ForeignStubs -> SDoc -> ForeignStubs
appendStubC NoStubs c_code = ForeignStubs empty c_code
appendStubC (ForeignStubs h c) c_code = ForeignStubs h (c $$ c_code)
\end{code}
-\begin{code}
-emptyModIface :: Module -> ModIface
-emptyModIface mod
- = ModIface { mi_module = mod,
- mi_iface_hash = fingerprint0,
- mi_mod_hash = fingerprint0,
- mi_orphan = False,
- mi_finsts = False,
- mi_boot = False,
- mi_deps = noDependencies,
- mi_usages = [],
- mi_exports = [],
- mi_exp_hash = fingerprint0,
- mi_used_th = False,
- mi_fixities = [],
- mi_warns = NoWarnings,
- mi_anns = [],
- mi_insts = [],
- mi_fam_insts = [],
- mi_rules = [],
- mi_decls = [],
- mi_globals = Nothing,
- mi_orphan_hash = fingerprint0,
- mi_vect_info = noIfaceVectInfo,
- mi_warn_fn = emptyIfaceWarnCache,
- mi_fix_fn = emptyIfaceFixCache,
- mi_hash_fn = emptyIfaceHashCache,
- mi_hpc = False,
- mi_trust = noIfaceTrustInfo,
- mi_trust_pkg = False
- }
-\end{code}
-
-
%************************************************************************
%* *
\subsection{The interactive context}
@@ -898,29 +912,29 @@ emptyModIface mod
\begin{code}
-- | Interactive context, recording information about the state of the
-- context in which statements are executed in a GHC session.
---
data InteractiveContext
= InteractiveContext {
- -- This field is only stored here so that the client
- -- can retrieve it with GHC.getContext. GHC itself doesn't
- -- use it, but does reset it to empty sometimes (such
- -- as before a GHC.load). The context is set with GHC.setContext.
- ic_imports :: [InteractiveImport],
+ ic_imports :: [InteractiveImport],
-- ^ The GHCi context is extended with these imports
+ --
+ -- This field is only stored here so that the client
+ -- can retrieve it with GHC.getContext. GHC itself doesn't
+ -- use it, but does reset it to empty sometimes (such
+ -- as before a GHC.load). The context is set with GHC.setContext.
ic_rn_gbl_env :: GlobalRdrEnv,
-- ^ The cached 'GlobalRdrEnv', built by
-- 'InteractiveEval.setContext' and updated regularly
- ic_tythings :: [TyThing],
+ ic_tythings :: [TyThing],
-- ^ TyThings defined by the user, in reverse order of
-- definition.
- ic_sys_vars :: [Id],
+ ic_sys_vars :: [Id],
-- ^ Variables defined automatically by the system (e.g.
-- record field selectors). See Notes [ic_sys_vars]
- ic_instances :: ([Instance], [FamInst]),
+ ic_instances :: ([Instance], [FamInst]),
-- ^ All instances and family instances created during
-- this session. These are grabbed en masse after each
-- update to be sure that proper overlapping is retained.
@@ -939,7 +953,7 @@ data InteractiveContext
{-
Note [ic_sys_vars]
-
+~~~~~~~~~~~~~~~~~~
This list constains any Ids that arise from TyCons, Classes or
instances defined interactively, but that are not given by
'implicitTyThings'. This includes record selectors, default methods,
@@ -960,16 +974,16 @@ hscDeclsWithLocation) and save them in ic_sys_vars.
-- | Constructs an empty InteractiveContext.
emptyInteractiveContext :: InteractiveContext
-emptyInteractiveContext = InteractiveContext {
- ic_imports = [],
- ic_rn_gbl_env = emptyGlobalRdrEnv,
- ic_tythings = [],
- ic_sys_vars = [],
- ic_instances = ([],[]),
+emptyInteractiveContext
+ = InteractiveContext { ic_imports = [],
+ ic_rn_gbl_env = emptyGlobalRdrEnv,
+ ic_tythings = [],
+ ic_sys_vars = [],
+ ic_instances = ([],[]),
#ifdef GHCI
- ic_resume = [],
+ ic_resume = [],
#endif
- ic_cwd = Nothing }
+ ic_cwd = Nothing }
-- | This function returns the list of visible TyThings (useful for
-- e.g. showBindings)
@@ -987,47 +1001,46 @@ icPrintUnqual dflags InteractiveContext{ ic_rn_gbl_env = grenv } =
-- whether they are entirely shadowed, but as you could still have references
-- to them (e.g. instances for classes or values of the type for TyCons), it's
-- not clear whether removing them is even the appropriate behavior.
-extendInteractiveContext
- :: InteractiveContext
- -> [TyThing]
- -> InteractiveContext
+extendInteractiveContext :: InteractiveContext -> [TyThing] -> InteractiveContext
extendInteractiveContext ictxt new_tythings
- = ictxt { ic_tythings = new_tythings ++ old_tythings
+ = ictxt { ic_tythings = new_tythings ++ old_tythings
, ic_rn_gbl_env = new_tythings `icPlusGblRdrEnv` ic_rn_gbl_env ictxt
}
where
old_tythings = filter (not . shadowed) (ic_tythings ictxt)
shadowed (AnId id) = ((`elem` new_names) . nameOccName . idName) id
- shadowed _ = False
+ shadowed _ = False
new_names = [ nameOccName (getName id) | AnId id <- new_tythings ]
- -- XXX should not add Ids to the gbl env here
+ -- ToDo: should not add Ids to the gbl env here
--- | Add TyThings to the GlobalRdrEnv, earlier ones in the list
--- shadowing later ones, and shadowing existing entries in the
--- GlobalRdrEnv.
+-- | Add TyThings to the GlobalRdrEnv, earlier ones in the list shadowing
+-- later ones, and shadowing existing entries in the GlobalRdrEnv.
icPlusGblRdrEnv :: [TyThing] -> GlobalRdrEnv -> GlobalRdrEnv
icPlusGblRdrEnv tythings env = extendOccEnvList env list
where new_gres = gresFromAvails LocalDef (map tyThingAvailInfo tythings)
list = [ (nameOccName (gre_name gre), [gre]) | gre <- new_gres ]
substInteractiveContext :: InteractiveContext -> TvSubst -> InteractiveContext
-substInteractiveContext ictxt subst | isEmptyTvSubst subst = ictxt
+substInteractiveContext ictxt subst
+ | isEmptyTvSubst subst = ictxt
+
substInteractiveContext ictxt@InteractiveContext{ ic_tythings = tts } subst
- = ictxt { ic_tythings = map subst_ty tts }
- where
- subst_ty (AnId id) = AnId $ id `setIdType` substTy subst (idType id)
- subst_ty tt = tt
+ = ictxt { ic_tythings = map subst_ty tts }
+ where subst_ty (AnId id) = AnId $ id `setIdType` substTy subst (idType id)
+ subst_ty tt = tt
data InteractiveImport
- = IIDecl (ImportDecl RdrName) -- Bring the exports of a particular module
- -- (filtered by an import decl) into scope
+ = IIDecl (ImportDecl RdrName)
+ -- ^ Bring the exports of a particular module
+ -- (filtered by an import decl) into scope
- | IIModule Module -- Bring into scope the entire top-level envt of
- -- of this module, including the things imported
- -- into it.
+ | IIModule Module
+ -- ^ Bring into scope the entire top-level envt of
+ -- of this module, including the things imported
+ -- into it.
instance Outputable InteractiveImport where
ppr (IIModule m) = char '*' <> ppr m
@@ -1125,7 +1138,7 @@ mkPrintUnqualified dflags env = (qual_name, qual_mod)
where lookup = lookupModuleInAllPackages dflags (moduleName mod)
-- Note [Outputable Orig RdrName]
---
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- This is a Grotesque Hack. The Outputable instance for RdrEnv wants
-- to print Orig names, which are just pairs of (Module,OccName). But
-- we want to use full Names here, because in GHCi we might have Ids
@@ -1211,9 +1224,6 @@ implicitCoTyCon tc
-- Just if family instance, Nothing if not
tyConFamilyCoercion_maybe tc]
--- sortByOcc = sortBy (\ x -> \ y -> getOccName x < getOccName y)
-
-
-- | Returns @True@ if there should be no interface-file declaration
-- for this thing on its own: either it is built-in, or it is part
-- of some other declaration, or it is generated implicitly by some
@@ -1224,13 +1234,13 @@ isImplicitTyThing (AnId id) = isImplicitId id
isImplicitTyThing (ATyCon tc) = isImplicitTyCon tc
isImplicitTyThing (ACoAxiom {}) = True
-tyThingParent_maybe :: TyThing -> Maybe TyThing
--- (tyThingParent_maybe x) returns (Just p)
+-- | tyThingParent_maybe x returns (Just p)
-- when pprTyThingInContext sould print a declaration for p
-- (albeit with some "..." in it) when asked to show x
-- It returns the *immediate* parent. So a datacon returns its tycon
-- but the tycon could be the associated type of a class, so it in turn
-- might have a parent.
+tyThingParent_maybe :: TyThing -> Maybe TyThing
tyThingParent_maybe (ADataCon dc) = Just (ATyCon (dataConTyCon dc))
tyThingParent_maybe (ATyCon tc) = case tyConAssoc_maybe tc of
Just cls -> Just (ATyCon (classTyCon cls))
@@ -1307,14 +1317,14 @@ mkTypeEnvWithImplicits things =
`plusNameEnv`
mkTypeEnv (concatMap implicitTyThings things)
-typeEnvFromEntities :: [Id] -> [TyCon] -> [Class] -> [FamInst] -> TypeEnv
-typeEnvFromEntities ids tcs clss faminsts =
+typeEnvFromEntities :: [Id] -> [TyCon] -> [FamInst] -> TypeEnv
+typeEnvFromEntities ids tcs faminsts =
mkTypeEnv ( map AnId ids
++ map ATyCon all_tcs
++ concatMap implicitTyConThings all_tcs
)
where
- all_tcs = tcs ++ map classTyCon clss ++ map famInstTyCon faminsts
+ all_tcs = tcs ++ map famInstTyCon faminsts
lookupTypeEnv = lookupNameEnv
@@ -1561,7 +1571,7 @@ data Dependencies
-- instances are from the home or an external package)
}
deriving( Eq )
- -- Equality used only for old/new comparison in MkIface.addVersionInfo
+ -- Equality used only for old/new comparison in MkIface.addFingerprints
-- See 'TcRnTypes.ImportAvails' for details on dependencies.
noDependencies :: Dependencies
@@ -2051,7 +2061,7 @@ data Linkable = LM {
-- If this list is empty, the Linkable represents a fake linkable, which
-- is generated in HscNothing mode to avoid recompiling modules.
--
- -- XXX: Do items get removed from this list when they get linked?
+ -- ToDo: Do items get removed from this list when they get linked?
}
isObjectLinkable :: Linkable -> Bool
@@ -2143,10 +2153,11 @@ data ModBreaks
-- ^ An array giving the names of the declarations enclosing each breakpoint.
}
+-- | Construct an empty ModBreaks
emptyModBreaks :: ModBreaks
emptyModBreaks = ModBreaks
{ modBreaks_flags = error "ModBreaks.modBreaks_array not initialised"
- -- Todo: can we avoid this?
+ -- ToDo: can we avoid this?
, modBreaks_locs = array (0,-1) []
, modBreaks_vars = array (0,-1) []
, modBreaks_decls = array (0,-1) []
diff --git a/compiler/main/Packages.lhs b/compiler/main/Packages.lhs
index 9c291e817b..d7dc6bc764 100644
--- a/compiler/main/Packages.lhs
+++ b/compiler/main/Packages.lhs
@@ -724,13 +724,7 @@ mkPackageState dflags pkgs0 preload0 this_package = do
-}
let
- flags = reverse (packageFlags dflags) ++ dphPackage
- -- expose the appropriate DPH backend library
- dphPackage = case dphBackend dflags of
- DPHPar -> [ExposePackage "dph-prim-par", ExposePackage "dph-par"]
- DPHSeq -> [ExposePackage "dph-prim-seq", ExposePackage "dph-seq"]
- DPHThis -> []
- DPHNone -> []
+ flags = reverse (packageFlags dflags)
-- pkgs0 with duplicate packages filtered out. This is
-- important: it is possible for a package in the global package
diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs
index b2a6b5bb67..ef17f3120a 100644
--- a/compiler/main/TidyPgm.lhs
+++ b/compiler/main/TidyPgm.lhs
@@ -129,7 +129,6 @@ mkBootModDetailsTc hsc_env
TcGblEnv{ tcg_exports = exports,
tcg_type_env = type_env, -- just for the Ids
tcg_tcs = tcs,
- tcg_clss = clss,
tcg_insts = insts,
tcg_fam_insts = fam_insts
}
@@ -139,7 +138,7 @@ mkBootModDetailsTc hsc_env
; let { insts' = tidyInstances globaliseAndTidyId insts
; dfun_ids = map instanceDFunId insts'
; type_env1 = mkBootTypeEnv (availsToNameSet exports)
- (typeEnvIds type_env) tcs clss fam_insts
+ (typeEnvIds type_env) tcs fam_insts
; type_env' = extendTypeEnvWithIds type_env1 dfun_ids
}
; return (ModDetails { md_types = type_env'
@@ -153,10 +152,10 @@ mkBootModDetailsTc hsc_env
}
where
-mkBootTypeEnv :: NameSet -> [Id] -> [TyCon] -> [Class] -> [FamInst] -> TypeEnv
-mkBootTypeEnv exports ids tcs clss fam_insts
+mkBootTypeEnv :: NameSet -> [Id] -> [TyCon] -> [FamInst] -> TypeEnv
+mkBootTypeEnv exports ids tcs fam_insts
= tidyTypeEnv True False exports $
- typeEnvFromEntities final_ids tcs clss fam_insts
+ typeEnvFromEntities final_ids tcs fam_insts
where
-- Find the LocalIds in the type env that are exported
-- Make them into GlobalIds, and tidy their types
@@ -294,7 +293,6 @@ tidyProgram :: HscEnv -> ModGuts -> IO (CgGuts, ModDetails)
tidyProgram hsc_env (ModGuts { mg_module = mod
, mg_exports = exports
, mg_tcs = tcs
- , mg_clss = clss
, mg_insts = insts
, mg_fam_insts = fam_insts
, mg_binds = binds
@@ -314,7 +312,7 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
}
; showPass dflags CoreTidy
- ; let { type_env = typeEnvFromEntities [] tcs clss fam_insts
+ ; let { type_env = typeEnvFromEntities [] tcs fam_insts
; implicit_binds
= concatMap getClassImplicitBinds (typeEnvClasses type_env) ++
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x
index 9ae312c363..b32dd8a675 100644
--- a/compiler/parser/Lexer.x
+++ b/compiler/parser/Lexer.x
@@ -477,6 +477,7 @@ data Token
| ITgenerated_prag
| ITcore_prag -- hdaume: core annotations
| ITunpack_prag
+ | ITnounpack_prag
| ITann_prag
| ITclose_prag
| IToptions_prag String
@@ -523,6 +524,7 @@ data Token
| ITcomma
| ITunderscore
| ITbackquote
+ | ITsimpleQuote -- '
| ITvarid FastString -- identifiers
| ITconid FastString
@@ -557,7 +559,6 @@ data Token
| ITcloseQuote -- |]
| ITidEscape FastString -- $x
| ITparenEscape -- $(
- | ITvarQuote -- '
| ITtyQuote -- ''
| ITquasiQuote (FastString,FastString,RealSrcSpan) -- [:...|...|]
@@ -1228,7 +1229,7 @@ lex_stringgap s = do
lex_char_tok :: Action
-- Here we are basically parsing character literals, such as 'x' or '\n'
-- but, when Template Haskell is on, we additionally spot
--- 'x and ''T, returning ITvarQuote and ITtyQuote respectively,
+-- 'x and ''T, returning ITsimpleQuote and ITtyQuote respectively,
-- but WITHOUT CONSUMING the x or T part (the parser does that).
-- So we have to do two characters of lookahead: when we see 'x we need to
-- see if there's a trailing quote
@@ -1239,11 +1240,8 @@ lex_char_tok span _buf _len = do -- We've seen '
Nothing -> lit_error i1
Just ('\'', i2@(AI end2 _)) -> do -- We've seen ''
- th_exts <- extension thEnabled
- if th_exts then do
- setInput i2
- return (L (mkRealSrcSpan loc end2) ITtyQuote)
- else lit_error i1
+ setInput i2
+ return (L (mkRealSrcSpan loc end2) ITtyQuote)
Just ('\\', i2@(AI _end2 _)) -> do -- We've seen 'backslash
setInput i2
@@ -1266,10 +1264,8 @@ lex_char_tok span _buf _len = do -- We've seen '
_other -> do -- We've seen 'x not followed by quote
-- (including the possibility of EOF)
-- If TH is on, just parse the quote only
- th_exts <- extension thEnabled
let (AI end _) = i1
- if th_exts then return (L (mkRealSrcSpan loc end) ITvarQuote)
- else lit_error i2
+ return (L (mkRealSrcSpan loc end) ITsimpleQuote)
finish_char_tok :: RealSrcLoc -> Char -> P (RealLocated Token)
finish_char_tok loc ch -- We've already seen the closing quote
@@ -2267,6 +2263,7 @@ oneWordPrags = Map.fromList([("rules", rulePrag),
("generated", token ITgenerated_prag),
("core", token ITcore_prag),
("unpack", token ITunpack_prag),
+ ("nounpack", token ITnounpack_prag),
("ann", token ITann_prag),
("vectorize", token ITvect_prag),
("novectorize", token ITnovect_prag)])
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp
index 62075e724b..b390009fbf 100644
--- a/compiler/parser/Parser.y.pp
+++ b/compiler/parser/Parser.y.pp
@@ -32,7 +32,7 @@ import RdrHsSyn
import HscTypes ( IsBootInterface, WarningTxt(..) )
import Lexer
import RdrName
-import TysPrim ( eqPrimTyCon )
+import TysPrim ( liftedTypeKindTyConName, eqPrimTyCon )
import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleCon, nilDataCon,
unboxedSingletonTyCon, unboxedSingletonDataCon,
listTyCon_RDR, parrTyCon_RDR, consDataCon_RDR, eqTyCon_RDR )
@@ -45,8 +45,7 @@ import DataCon ( DataCon, dataConName )
import SrcLoc
import Module
import StaticFlags ( opt_SccProfilingOn, opt_Hpc )
-import Type ( Kind, liftedTypeKind, unliftedTypeKind )
-import Coercion ( mkArrowKind )
+import Kind ( Kind, liftedTypeKind, unliftedTypeKind, mkArrowKind )
import Class ( FunDep )
import BasicTypes
import DynFlags
@@ -263,6 +262,7 @@ incorrect.
'{-# DEPRECATED' { L _ ITdeprecated_prag }
'{-# WARNING' { L _ ITwarning_prag }
'{-# UNPACK' { L _ ITunpack_prag }
+ '{-# NOUNPACK' { L _ ITnounpack_prag }
'{-# ANN' { L _ ITann_prag }
'{-# VECTORISE' { L _ ITvect_prag }
'{-# VECTORISE_SCALAR' { L _ ITvect_scalar_prag }
@@ -309,6 +309,7 @@ incorrect.
';' { L _ ITsemi }
',' { L _ ITcomma }
'`' { L _ ITbackquote }
+ SIMPLEQUOTE { L _ ITsimpleQuote } -- 'x
VARID { L _ (ITvarid _) } -- identifiers
CONID { L _ (ITconid _) }
@@ -348,7 +349,6 @@ incorrect.
'|]' { L _ ITcloseQuote }
TH_ID_SPLICE { L _ (ITidEscape _) } -- $x
'$(' { L _ ITparenEscape } -- $( exp )
-TH_VAR_QUOTE { L _ ITvarQuote } -- 'x
TH_TY_QUOTE { L _ ITtyQuote } -- ''T
TH_QUASIQUOTE { L _ (ITquasiQuote _) }
@@ -717,9 +717,9 @@ data_or_newtype :: { Located NewOrData }
: 'data' { L1 DataType }
| 'newtype' { L1 NewType }
-opt_kind_sig :: { Located (Maybe Kind) }
+opt_kind_sig :: { Located (Maybe (LHsKind RdrName)) }
: { noLoc Nothing }
- | '::' kind { LL (Just (unLoc $2)) }
+ | '::' kind { LL (Just $2) }
-- tycl_hdr parses the header of a class or data type decl,
-- which takes the form
@@ -967,12 +967,13 @@ sigtypes1 :: { [LHsType RdrName] } -- Always HsForAllTys
-- Types
infixtype :: { LHsType RdrName }
- : btype qtyconop type { LL $ HsOpTy $1 $2 $3 }
- | btype tyvarop type { LL $ HsOpTy $1 $2 $3 }
+ : btype qtyconop type { LL $ mkHsOpTy $1 $2 $3 }
+ | btype tyvarop type { LL $ mkHsOpTy $1 $2 $3 }
strict_mark :: { Located HsBang }
: '!' { L1 HsStrict }
| '{-# UNPACK' '#-}' '!' { LL HsUnpack }
+ | '{-# NOUNPACK' '#-}' '!' { LL HsNoUnpack }
-- A ctype is a for-all type
ctype :: { LHsType RdrName }
@@ -1018,18 +1019,21 @@ context :: { LHsContext RdrName }
type :: { LHsType RdrName }
: btype { $1 }
- | btype qtyconop type { LL $ HsOpTy $1 $2 $3 }
- | btype tyvarop type { LL $ HsOpTy $1 $2 $3 }
+ | btype qtyconop type { LL $ mkHsOpTy $1 $2 $3 }
+ | btype tyvarop type { LL $ mkHsOpTy $1 $2 $3 }
| btype '->' ctype { LL $ HsFunTy $1 $3 }
| btype '~' btype { LL $ HsEqTy $1 $3 }
+ -- see Note [Promotion]
+ | btype SIMPLEQUOTE qconop type { LL $ mkHsOpTy $1 $3 $4 }
+ | btype SIMPLEQUOTE varop type { LL $ mkHsOpTy $1 $3 $4 }
typedoc :: { LHsType RdrName }
: btype { $1 }
| btype docprev { LL $ HsDocTy $1 $2 }
- | btype qtyconop type { LL $ HsOpTy $1 $2 $3 }
- | btype qtyconop type docprev { LL $ HsDocTy (L (comb3 $1 $2 $3) (HsOpTy $1 $2 $3)) $4 }
- | btype tyvarop type { LL $ HsOpTy $1 $2 $3 }
- | btype tyvarop type docprev { LL $ HsDocTy (L (comb3 $1 $2 $3) (HsOpTy $1 $2 $3)) $4 }
+ | btype qtyconop type { LL $ mkHsOpTy $1 $2 $3 }
+ | btype qtyconop type docprev { LL $ HsDocTy (L (comb3 $1 $2 $3) (mkHsOpTy $1 $2 $3)) $4 }
+ | btype tyvarop type { LL $ mkHsOpTy $1 $2 $3 }
+ | btype tyvarop type docprev { LL $ HsDocTy (L (comb3 $1 $2 $3) (mkHsOpTy $1 $2 $3)) $4 }
| btype '->' ctypedoc { LL $ HsFunTy $1 $3 }
| btype docprev '->' ctypedoc { LL $ HsFunTy (L (comb2 $1 $2) (HsDocTy $1 $2)) $4 }
| btype '~' btype { LL $ HsEqTy $1 $3 }
@@ -1048,11 +1052,17 @@ atype :: { LHsType RdrName }
| '[' ctype ']' { LL $ HsListTy $2 }
| '[:' ctype ':]' { LL $ HsPArrTy $2 }
| '(' ctype ')' { LL $ HsParTy $2 }
- | '(' ctype '::' kind ')' { LL $ HsKindSig $2 (unLoc $4) }
+ | '(' ctype '::' kind ')' { LL $ HsKindSig $2 $4 }
| quasiquote { L1 (HsQuasiQuoteTy (unLoc $1)) }
| '$(' exp ')' { LL $ mkHsSpliceTy $2 }
- | TH_ID_SPLICE { LL $ mkHsSpliceTy $ L1 $ HsVar $
+ | TH_ID_SPLICE { LL $ mkHsSpliceTy $ L1 $ HsVar $
mkUnqual varName (getTH_ID_SPLICE $1) }
+ -- see Note [Promotion] for the followings
+ | SIMPLEQUOTE qconid { LL $ HsTyVar $ unLoc $2 }
+ | SIMPLEQUOTE '(' ')' { LL $ HsTyVar $ getRdrName unitDataCon }
+ | SIMPLEQUOTE '(' ctype ',' comma_types1 ')' { LL $ HsExplicitTupleTy [] ($3 : $5) }
+ | SIMPLEQUOTE '[' comma_types0 ']' { LL $ HsExplicitListTy placeHolderKind $3 }
+ | '[' ctype ',' comma_types1 ']' { LL $ HsExplicitListTy placeHolderKind ($2 : $4) }
-- An inst_type is what occurs in the head of an instance decl
-- e.g. (Foo a, Gaz b) => Wibble a b
@@ -1079,8 +1089,7 @@ tv_bndrs :: { [LHsTyVarBndr RdrName] }
tv_bndr :: { LHsTyVarBndr RdrName }
: tyvar { L1 (UserTyVar (unLoc $1) placeHolderKind) }
- | '(' tyvar '::' kind ')' { LL (KindedTyVar (unLoc $2)
- (unLoc $4)) }
+ | '(' tyvar '::' kind ')' { LL (KindedTyVar (unLoc $2) $4 placeHolderKind) }
fds :: { Located [Located (FunDep RdrName)] }
: {- empty -} { noLoc [] }
@@ -1101,15 +1110,55 @@ varids0 :: { Located [RdrName] }
-----------------------------------------------------------------------------
-- Kinds
-kind :: { Located Kind }
- : akind { $1 }
- | akind '->' kind { LL (mkArrowKind (unLoc $1) (unLoc $3)) }
+kind :: { LHsKind RdrName }
+ : bkind { $1 }
+ | bkind '->' kind { LL $ HsFunTy $1 $3 }
+
+bkind :: { LHsKind RdrName }
+ : akind { $1 }
+ | bkind akind { LL $ HsAppTy $1 $2 }
+
+akind :: { LHsKind RdrName }
+ : '*' { L1 $ HsTyVar (nameRdrName liftedTypeKindTyConName) }
+ | '(' kind ')' { LL $ HsParTy $2 }
+ | pkind { $1 }
+
+pkind :: { LHsKind RdrName } -- promoted type, see Note [Promotion]
+ : qtycon { L1 $ HsTyVar $ unLoc $1 }
+ | '(' ')' { LL $ HsTyVar $ getRdrName unitTyCon }
+ | '(' kind ',' comma_kinds1 ')' { LL $ HsTupleTy (HsBoxyTuple placeHolderKind) ($2 : $4) }
+ | '[' kind ']' { LL $ HsListTy $2 }
+
+comma_kinds1 :: { [LHsKind RdrName] }
+ : kind { [$1] }
+ | kind ',' comma_kinds1 { $1 : $3 }
+
+{- Note [Promotion]
+ ~~~~~~~~~~~~~~~~
+
+- Syntax of promoted qualified names
+We write 'Nat.Zero instead of Nat.'Zero when dealing with qualified
+names. Moreover ticks are only allowed in types, not in kinds, for a
+few reasons:
+ 1. we don't need quotes since we cannot define names in kinds
+ 2. if one day we merge types and kinds, tick would mean look in DataName
+ 3. we don't have a kind namespace anyway
+
+- Syntax of explicit kind polymorphism (IA0_TODO: not yet implemented)
+Kind abstraction is implicit. We write
+> data SList (s :: k -> *) (as :: [k]) where ...
+because it looks like what we do in terms
+> id (x :: a) = x
+
+- Name resolution
+When the user write Zero instead of 'Zero in types, we parse it a
+HsTyVar ("Zero", TcClsName) instead of HsTyVar ("Zero", DataName). We
+deal with this in the renamer. If a HsTyVar ("Zero", TcClsName) is not
+bounded in the type level, then we look for it in the term level (we
+change its namespace to DataName, see Note [Demotion] in OccName). And
+both become a HsTyVar ("Zero", DataName) after the renamer.
-akind :: { Located Kind }
- : '*' { L1 liftedTypeKind }
- | '!' { L1 unliftedTypeKind }
- | CONID {% checkKindName (L1 (getCONID $1)) }
- | '(' kind ')' { LL (unLoc $2) }
+-}
-----------------------------------------------------------------------------
@@ -1409,10 +1458,10 @@ aexp2 :: { LHsExpr RdrName }
| '$(' exp ')' { LL $ HsSpliceE (mkHsSplice $2) }
- | TH_VAR_QUOTE qvar { LL $ HsBracket (VarBr (unLoc $2)) }
- | TH_VAR_QUOTE qcon { LL $ HsBracket (VarBr (unLoc $2)) }
- | TH_TY_QUOTE tyvar { LL $ HsBracket (VarBr (unLoc $2)) }
- | TH_TY_QUOTE gtycon { LL $ HsBracket (VarBr (unLoc $2)) }
+ | SIMPLEQUOTE qvar { LL $ HsBracket (VarBr True (unLoc $2)) }
+ | SIMPLEQUOTE qcon { LL $ HsBracket (VarBr True (unLoc $2)) }
+ | TH_TY_QUOTE tyvar { LL $ HsBracket (VarBr False (unLoc $2)) }
+ | TH_TY_QUOTE gtycon { LL $ HsBracket (VarBr False (unLoc $2)) }
| '[|' exp '|]' { LL $ HsBracket (ExpBr $2) }
| '[t|' ctype '|]' { LL $ HsBracket (TypBr $2) }
| '[p|' infixexp '|]' {% checkPattern $2 >>= \p ->
diff --git a/compiler/parser/ParserCore.y b/compiler/parser/ParserCore.y
index 99efa7a4ae..3a786ea04b 100644
--- a/compiler/parser/ParserCore.y
+++ b/compiler/parser/ParserCore.y
@@ -20,7 +20,7 @@ import Type ( Kind,
liftedTypeKindTyCon, openTypeKindTyCon, unliftedTypeKindTyCon,
argTypeKindTyCon, ubxTupleKindTyCon, mkTyConApp
)
-import Coercion( mkArrowKind )
+import Kind( mkArrowKind )
import Name( Name, nameOccName, nameModule, mkExternalName, wiredInNameTyThing_maybe )
import Module
import ParserCoreUtils
@@ -346,7 +346,7 @@ eqTc (IfaceTc name) tycon = name == tyConName tycon
-- Tiresomely, we have to generate both HsTypes (in type/class decls)
-- and IfaceTypes (in Core expressions). So we parse them as IfaceTypes,
-- and convert to HsTypes here. But the IfaceTypes we can see here
--- are very limited (see the productions for 'ty', so the translation
+-- are very limited (see the productions for 'ty'), so the translation
-- isn't hard
toHsType :: IfaceType -> LHsType RdrName
toHsType (IfaceTyVar v) = noLoc $ HsTyVar (mkRdrUnqual (mkTyVarOccFS v))
@@ -355,12 +355,12 @@ toHsType (IfaceFunTy t1 t2) = noLoc $ HsFunTy (toHsType t1) (toHsType t2)
toHsType (IfaceTyConApp (IfaceTc tc) ts) = foldl mkHsAppTy (noLoc $ HsTyVar (ifaceExtRdrName tc)) (map toHsType ts)
toHsType (IfaceForAllTy tv t) = add_forall (toHsTvBndr tv) (toHsType t)
--- We also need to convert IfaceKinds to Kinds (now that they are different).
-- Only a limited form of kind will be encountered... hopefully
-toKind :: IfaceKind -> Kind
-toKind (IfaceFunTy ifK1 ifK2) = mkArrowKind (toKind ifK1) (toKind ifK2)
-toKind (IfaceTyConApp ifKc []) = mkTyConApp (toKindTc ifKc) []
-toKind other = pprPanic "toKind" (ppr other)
+toHsKind :: IfaceKind -> LHsKind RdrName
+-- IA0_NOTE: Shouldn't we add kind variables?
+toHsKind (IfaceFunTy ifK1 ifK2) = noLoc $ HsFunTy (toHsKind ifK1) (toHsKind ifK2)
+toHsKind (IfaceTyConApp ifKc []) = noLoc $ HsTyVar (nameRdrName (tyConName (toKindTc ifKc)))
+toHsKind other = pprPanic "toHsKind" (ppr other)
toKindTc :: IfaceTyCon -> TyCon
toKindTc (IfaceTc n) | Just (ATyCon tc) <- wiredInNameTyThing_maybe n = tc
@@ -375,7 +375,7 @@ ifaceUnliftedTypeKind = ifaceTcType (IfaceTc unliftedTypeKindTyConName)
ifaceArrow ifT1 ifT2 = IfaceFunTy ifT1 ifT2
toHsTvBndr :: IfaceTvBndr -> LHsTyVarBndr RdrName
-toHsTvBndr (tv,k) = noLoc $ KindedTyVar (mkRdrUnqual (mkTyVarOccFS tv)) (toKind k)
+toHsTvBndr (tv,k) = noLoc $ KindedTyVar (mkRdrUnqual (mkTyVarOccFS tv)) (toHsKind k) placeHolderKind
ifaceExtRdrName :: Name -> RdrName
ifaceExtRdrName name = mkOrig (nameModule name) (nameOccName name)
diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs
index 20055e3b7d..8ab71f3885 100644
--- a/compiler/parser/RdrHsSyn.lhs
+++ b/compiler/parser/RdrHsSyn.lhs
@@ -42,7 +42,6 @@ module RdrHsSyn (
checkValDef, -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
checkValSig, -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
checkDoAndIfThenElse,
- checkKindName,
checkRecordSyntax,
parseError,
parseErrorSDoc,
@@ -50,16 +49,13 @@ module RdrHsSyn (
import HsSyn -- Lots of it
import Class ( FunDep )
-import TypeRep ( Kind )
-import RdrName ( RdrName, isRdrTyVar, isRdrTc, mkUnqual, rdrNameOcc,
+import RdrName ( RdrName, isRdrTyVar, isRdrTc, mkUnqual, rdrNameOcc,
isRdrDataCon, isUnqual, getRdrName, setRdrNameSpace )
-import OccName ( occNameFS )
-import Name ( Name, nameOccName )
+import Name ( Name )
import BasicTypes ( maxPrecedence, Activation(..), RuleMatchInfo,
InlinePragma(..), InlineSpec(..) )
import Lexer
import TysWiredIn ( unitTyCon )
-import TysPrim ( constraintKindTyConName, constraintKind )
import ForeignCall
import OccName ( srcDataName, varName, isDataOcc, isTcOcc,
occNameString )
@@ -110,6 +106,8 @@ extract_lctxt ctxt acc = foldr extract_lty acc (unLoc ctxt)
extract_ltys :: [LHsType RdrName] -> [Located RdrName] -> [Located RdrName]
extract_ltys tys acc = foldr extract_lty acc tys
+-- IA0_NOTE: Should this function also return kind variables?
+-- (explicit kind poly)
extract_lty :: LHsType RdrName -> [Located RdrName] -> [Located RdrName]
extract_lty (L loc ty) acc
= case ty of
@@ -123,7 +121,7 @@ extract_lty (L loc ty) acc
HsFunTy ty1 ty2 -> extract_lty ty1 (extract_lty ty2 acc)
HsIParamTy _ ty -> extract_lty ty acc
HsEqTy ty1 ty2 -> extract_lty ty1 (extract_lty ty2 acc)
- HsOpTy ty1 (L loc tv) ty2 -> extract_tv loc tv (extract_lty ty1 (extract_lty ty2 acc))
+ HsOpTy ty1 (_, (L loc tv)) ty2 -> extract_tv loc tv (extract_lty ty1 (extract_lty ty2 acc))
HsParTy ty -> extract_lty ty acc
HsCoreTy {} -> acc -- The type is closed
HsQuasiQuoteTy {} -> acc -- Quasi quotes mention no type variables
@@ -135,6 +133,9 @@ extract_lty (L loc ty) acc
where
locals = hsLTyVarNames tvs
HsDocTy ty _ -> extract_lty ty acc
+ HsExplicitListTy _ tys -> extract_ltys tys acc
+ HsExplicitTupleTy _ tys -> extract_ltys tys acc
+ HsWrapTy _ _ -> panic "extract_lty"
extract_tv :: SrcSpan -> RdrName -> [Located RdrName] -> [Located RdrName]
extract_tv loc tv acc | isRdrTyVar tv = L loc tv : acc
@@ -191,7 +192,7 @@ mkTyData :: SrcSpan
-> NewOrData
-> Bool -- True <=> data family instance
-> Located (Maybe (LHsContext RdrName), LHsType RdrName)
- -> Maybe Kind
+ -> Maybe (LHsKind RdrName)
-> [LConDecl RdrName]
-> Maybe [LHsType RdrName]
-> P (LTyClDecl RdrName)
@@ -219,7 +220,7 @@ mkTySynonym loc is_family lhs rhs
mkTyFamily :: SrcSpan
-> FamilyFlavour
-> LHsType RdrName -- LHS
- -> Maybe Kind -- Optional kind signature
+ -> Maybe (LHsKind RdrName) -- Optional kind signature
-> P (LTyClDecl RdrName)
mkTyFamily loc flavour lhs ksig
= do { (tc, tparams) <- checkTyClHdr lhs
@@ -493,7 +494,7 @@ checkTyVars tycl_hdr tparms = mapM chk tparms
where
-- Check that the name space is correct!
chk (L l (HsKindSig (L _ (HsTyVar tv)) k))
- | isRdrTyVar tv = return (L l (KindedTyVar tv k))
+ | isRdrTyVar tv = return (L l (KindedTyVar tv k placeHolderKind))
chk (L l (HsTyVar tv))
| isRdrTyVar tv = return (L l (UserTyVar tv placeHolderKind))
chk t@(L l _)
@@ -532,10 +533,10 @@ checkTyClHdr ty
where
goL (L l ty) acc = go l ty acc
- go l (HsTyVar tc) acc
+ go l (HsTyVar tc) acc
| isRdrTc tc = return (L l tc, acc)
-
- go _ (HsOpTy t1 ltc@(L _ tc) t2) acc
+
+ go _ (HsOpTy t1 (_, ltc@(L _ tc)) t2) acc
| isRdrTc tc = return (ltc, t1:t2:acc)
go _ (HsParTy ty) acc = goL ty acc
go _ (HsAppTy t1 t2) acc = goL t1 (t2:acc)
@@ -776,17 +777,6 @@ checkDoAndIfThenElse guardExpr semiThen thenExpr semiElse elseExpr
expr = text "if" <+> ppr guardExpr <> pprOptSemi semiThen <+>
text "then" <+> ppr thenExpr <> pprOptSemi semiElse <+>
text "else" <+> ppr elseExpr
-
-checkKindName :: Located FastString -> P (Located Kind)
-checkKindName (L l fs) = do
- pState <- getPState
- let ext_enabled = xopt Opt_ConstraintKinds (dflags pState)
- is_kosher = fs == occNameFS (nameOccName constraintKindTyConName)
- if not ext_enabled || not is_kosher
- then parseErrorSDoc l (text "Unexpected named kind:"
- $$ nest 4 (ppr fs)
- $$ if (not ext_enabled && is_kosher) then text "Perhaps you meant to use -XConstraintKinds?" else empty)
- else return (L l constraintKind)
\end{code}
diff --git a/compiler/prelude/PrelNames.lhs b/compiler/prelude/PrelNames.lhs
index 7eacbd5388..cd6a621868 100644
--- a/compiler/prelude/PrelNames.lhs
+++ b/compiler/prelude/PrelNames.lhs
@@ -156,7 +156,6 @@ basicKnownKeyNames :: [Name]
basicKnownKeyNames
= genericTyConNames
++ typeableClassNames
- ++ dphKnownKeyNames dphSeqPackageId ++ dphKnownKeyNames dphParPackageId
++ [ -- Type constructors (synonyms especially)
ioTyConName, ioDataConName,
runMainIOName,
@@ -306,20 +305,6 @@ genericTyConNames = [
d1TyConName, c1TyConName, s1TyConName, noSelTyConName,
repTyConName, rep1TyConName
]
-
--- Know names from the DPH package which vary depending on the selected DPH backend.
---
-dphKnownKeyNames :: PackageId -> [Name]
-dphKnownKeyNames dphPkg
- = map ($ dphPkg)
- [
- -- Parallel array operations
- nullPName, lengthPName, replicatePName, singletonPName, mapPName,
- filterPName, zipPName, crossMapPName, indexPName,
- toPName, emptyPName, appPName,
- enumFromToPName, enumFromThenToPName
-
- ]
\end{code}
@@ -399,12 +384,6 @@ rANDOM = mkBaseModule (fsLit "System.Random")
gHC_EXTS = mkBaseModule (fsLit "GHC.Exts")
cONTROL_EXCEPTION_BASE = mkBaseModule (fsLit "Control.Exception.Base")
-dATA_ARRAY_PARALLEL_PRIM :: PackageId -> Module
-dATA_ARRAY_PARALLEL_PRIM pkg = mkModule pkg (mkModuleNameFS (fsLit "Data.Array.Parallel.Prim"))
-
-gHC_PARR :: PackageId -> Module
-gHC_PARR pkg = mkModule pkg (mkModuleNameFS (fsLit "Data.Array.Parallel"))
-
gHC_PARR' :: Module
gHC_PARR' = mkBaseModule (fsLit "GHC.PArr")
@@ -423,6 +402,10 @@ pRELUDE_NAME, mAIN_NAME :: ModuleName
pRELUDE_NAME = mkModuleNameFS (fsLit "Prelude")
mAIN_NAME = mkModuleNameFS (fsLit "Main")
+dATA_ARRAY_PARALLEL_NAME, dATA_ARRAY_PARALLEL_PRIM_NAME :: ModuleName
+dATA_ARRAY_PARALLEL_NAME = mkModuleNameFS (fsLit "Data.Array.Parallel")
+dATA_ARRAY_PARALLEL_PRIM_NAME = mkModuleNameFS (fsLit "Data.Array.Parallel.Prim")
+
mkPrimModule :: FastString -> Module
mkPrimModule m = mkModule primPackageId (mkModuleNameFS m)
@@ -964,26 +947,6 @@ datatypeClassName = clsQual gHC_GENERICS (fsLit "Datatype") datatypeClassKey
constructorClassName = clsQual gHC_GENERICS (fsLit "Constructor") constructorClassKey
selectorClassName = clsQual gHC_GENERICS (fsLit "Selector") selectorClassKey
--- parallel array types and functions
-enumFromToPName, enumFromThenToPName, nullPName, lengthPName,
- singletonPName, replicatePName, mapPName, filterPName,
- zipPName, crossMapPName, indexPName, toPName,
- emptyPName, appPName :: PackageId -> Name
-enumFromToPName pkg = varQual (gHC_PARR pkg) (fsLit "enumFromToP") enumFromToPIdKey
-enumFromThenToPName pkg = varQual (gHC_PARR pkg) (fsLit "enumFromThenToP") enumFromThenToPIdKey
-nullPName pkg = varQual (gHC_PARR pkg) (fsLit "nullP") nullPIdKey
-lengthPName pkg = varQual (gHC_PARR pkg) (fsLit "lengthP") lengthPIdKey
-singletonPName pkg = varQual (gHC_PARR pkg) (fsLit "singletonP") singletonPIdKey
-replicatePName pkg = varQual (gHC_PARR pkg) (fsLit "replicateP") replicatePIdKey
-mapPName pkg = varQual (gHC_PARR pkg) (fsLit "mapP") mapPIdKey
-filterPName pkg = varQual (gHC_PARR pkg) (fsLit "filterP") filterPIdKey
-zipPName pkg = varQual (gHC_PARR pkg) (fsLit "zipP") zipPIdKey
-crossMapPName pkg = varQual (gHC_PARR pkg) (fsLit "crossMapP") crossMapPIdKey
-indexPName pkg = varQual (gHC_PARR pkg) (fsLit "!:") indexPIdKey
-toPName pkg = varQual (gHC_PARR pkg) (fsLit "toP") toPIdKey
-emptyPName pkg = varQual (gHC_PARR pkg) (fsLit "emptyP") emptyPIdKey
-appPName pkg = varQual (gHC_PARR pkg) (fsLit "+:+") appPIdKey
-
-- IO things
ioTyConName, ioDataConName, thenIOName, bindIOName, returnIOName,
failIOName :: Name
@@ -1278,11 +1241,13 @@ eitherTyConKey = mkPreludeTyConUnique 84
-- Super Kinds constructors
tySuperKindTyConKey :: Unique
-tySuperKindTyConKey = mkPreludeTyConUnique 85
+tySuperKindTyConKey = mkPreludeTyConUnique 85
-- Kind constructors
-liftedTypeKindTyConKey, openTypeKindTyConKey, unliftedTypeKindTyConKey,
- ubxTupleKindTyConKey, argTypeKindTyConKey, constraintKindTyConKey :: Unique
+liftedTypeKindTyConKey, anyKindTyConKey, openTypeKindTyConKey,
+ unliftedTypeKindTyConKey, ubxTupleKindTyConKey, argTypeKindTyConKey,
+ constraintKindTyConKey :: Unique
+anyKindTyConKey = mkPreludeTyConUnique 86
liftedTypeKindTyConKey = mkPreludeTyConUnique 87
openTypeKindTyConKey = mkPreludeTyConUnique 88
unliftedTypeKindTyConKey = mkPreludeTyConUnique 89
@@ -1539,25 +1504,6 @@ dollarIdKey = mkPreludeMiscIdUnique 123
coercionTokenIdKey :: Unique
coercionTokenIdKey = mkPreludeMiscIdUnique 124
--- Parallel array functions
-singletonPIdKey, nullPIdKey, lengthPIdKey, replicatePIdKey, mapPIdKey,
- filterPIdKey, zipPIdKey, crossMapPIdKey, indexPIdKey, toPIdKey,
- enumFromToPIdKey, enumFromThenToPIdKey, emptyPIdKey, appPIdKey :: Unique
-singletonPIdKey = mkPreludeMiscIdUnique 130
-nullPIdKey = mkPreludeMiscIdUnique 131
-lengthPIdKey = mkPreludeMiscIdUnique 132
-replicatePIdKey = mkPreludeMiscIdUnique 133
-mapPIdKey = mkPreludeMiscIdUnique 134
-filterPIdKey = mkPreludeMiscIdUnique 135
-zipPIdKey = mkPreludeMiscIdUnique 136
-crossMapPIdKey = mkPreludeMiscIdUnique 137
-indexPIdKey = mkPreludeMiscIdUnique 138
-toPIdKey = mkPreludeMiscIdUnique 139
-enumFromToPIdKey = mkPreludeMiscIdUnique 140
-enumFromThenToPIdKey = mkPreludeMiscIdUnique 141
-emptyPIdKey = mkPreludeMiscIdUnique 142
-appPIdKey = mkPreludeMiscIdUnique 143
-
-- dotnet interop
unmarshalObjectIdKey, marshalObjectIdKey, marshalStringIdKey,
unmarshalStringIdKey, checkDotnetResNameIdKey :: Unique
@@ -1647,6 +1593,24 @@ mzipIdKey = mkPreludeMiscIdUnique 197
%************************************************************************
%* *
+\subsection{Standard groups of types}
+%* *
+%************************************************************************
+
+\begin{code}
+kindKeys :: [Unique]
+kindKeys = [ anyKindTyConKey
+ , liftedTypeKindTyConKey
+ , openTypeKindTyConKey
+ , unliftedTypeKindTyConKey
+ , ubxTupleKindTyConKey
+ , argTypeKindTyConKey
+ , constraintKindTyConKey ]
+\end{code}
+
+
+%************************************************************************
+%* *
\subsection[Class-std-groups]{Standard groups of Prelude classes}
%* *
%************************************************************************
diff --git a/compiler/prelude/TysPrim.lhs b/compiler/prelude/TysPrim.lhs
index 202d48e018..5cb07a14da 100644
--- a/compiler/prelude/TysPrim.lhs
+++ b/compiler/prelude/TysPrim.lhs
@@ -21,20 +21,21 @@ module TysPrim(
tyVarList, alphaTyVars, betaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
alphaTy, betaTy, gammaTy, deltaTy,
openAlphaTy, openBetaTy, openAlphaTyVar, openBetaTyVar, openAlphaTyVars,
- argAlphaTyVars, argAlphaTyVar, argAlphaTy, argBetaTy, argBetaTyVar,
+ argAlphaTy, argAlphaTyVar, argAlphaTyVars, argBetaTy, argBetaTyVar,
+ kKiVar,
-- Kind constructors...
- tySuperKindTyCon, tySuperKind,
+ tySuperKindTyCon, tySuperKind, anyKindTyCon,
liftedTypeKindTyCon, openTypeKindTyCon, unliftedTypeKindTyCon,
argTypeKindTyCon, ubxTupleKindTyCon, constraintKindTyCon,
- tySuperKindTyConName, liftedTypeKindTyConName,
+ tySuperKindTyConName, anyKindTyConName, liftedTypeKindTyConName,
openTypeKindTyConName, unliftedTypeKindTyConName,
ubxTupleKindTyConName, argTypeKindTyConName,
constraintKindTyConName,
-- Kinds
- liftedTypeKind, unliftedTypeKind, openTypeKind,
+ anyKind, liftedTypeKind, unliftedTypeKind, openTypeKind,
argTypeKind, ubxTupleKind, constraintKind,
mkArrowKind, mkArrowKinds,
@@ -74,21 +75,20 @@ module TysPrim(
eqPrimTyCon, -- ty1 ~# ty2
-- * Any
- anyTy, anyTyCon, anyTyConOfKind, anyTypeOfKind
+ anyTy, anyTyCon, anyTypeOfKind
) where
#include "HsVersions.h"
-import Var ( TyVar, mkTyVar )
+import Var ( TyVar, KindVar, mkTyVar )
import Name ( Name, BuiltInSyntax(..), mkInternalName, mkWiredInName )
-import OccName ( mkTcOcc,mkTyVarOccFS, mkTcOccFS )
+import OccName ( mkTyVarOccFS, mkTcOccFS )
import TyCon
import TypeRep
import SrcLoc
import Unique ( mkAlphaTyVarUnique )
import PrelNames
import FastString
-import Outputable
import Data.Char
\end{code}
@@ -127,6 +127,7 @@ primTyCons
, word32PrimTyCon
, word64PrimTyCon
, anyTyCon
+ , anyKindTyCon
, eqPrimTyCon
, liftedTypeKindTyCon
@@ -223,6 +224,10 @@ argAlphaTyVars@(argAlphaTyVar : argBetaTyVar : _) = tyVarList argTypeKind
argAlphaTy, argBetaTy :: Type
argAlphaTy = mkTyVarTy argAlphaTyVar
argBetaTy = mkTyVarTy argBetaTyVar
+
+kKiVar :: KindVar
+kKiVar = (tyVarList tySuperKind) !! 10
+
\end{code}
@@ -239,9 +244,6 @@ funTyConName = mkPrimTyConName (fsLit "(->)") funTyConKey funTyCon
funTyCon :: TyCon
funTyCon = mkFunTyCon funTyConName $
mkArrowKinds [liftedTypeKind, liftedTypeKind] liftedTypeKind
--- DV: used to be (mkArrowKinds [argTypeKind, openTypeKind] liftedTypeKind)
--- but I am modifying this in-flight for the GHC kinds merge
-
-- You might think that (->) should have type (?? -> ? -> *), and you'd be right
-- But if we do that we get kind errors when saying
-- instance Control.Arrow (->)
@@ -250,6 +252,20 @@ funTyCon = mkFunTyCon funTyConName $
-- the kind sub-typing does. Sigh. It really only matters if you use (->) in
-- a prefix way, thus: (->) Int# Int#. And this is unusual.
-- because they are never in scope in the source
+
+-- One step to remove subkinding.
+-- (->) :: * -> * -> *
+-- but we should have (and want) the following typing rule for fully applied arrows
+-- Gamma |- tau :: k1 k1 in {*, #}
+-- Gamma |- sigma :: k2 k2 in {*, #, (#)}
+-- -----------------------------------------
+-- Gamma |- tau -> sigma :: *
+-- Currently we have the following rule which achieves more or less the same effect
+-- Gamma |- tau :: ??
+-- Gamma |- sigma :: ?
+-- --------------------------
+-- Gamma |- tau -> sigma :: *
+-- In the end we don't want subkinding at all.
\end{code}
@@ -261,18 +277,19 @@ funTyCon = mkFunTyCon funTyConName $
\begin{code}
-- | See "Type#kind_subtyping" for details of the distinction between the 'Kind' 'TyCon's
-tySuperKindTyCon, liftedTypeKindTyCon,
+tySuperKindTyCon, anyKindTyCon, liftedTypeKindTyCon,
openTypeKindTyCon, unliftedTypeKindTyCon,
ubxTupleKindTyCon, argTypeKindTyCon,
constraintKindTyCon
:: TyCon
-tySuperKindTyConName, liftedTypeKindTyConName,
+tySuperKindTyConName, anyKindTyConName, liftedTypeKindTyConName,
openTypeKindTyConName, unliftedTypeKindTyConName,
ubxTupleKindTyConName, argTypeKindTyConName,
constraintKindTyConName
:: Name
tySuperKindTyCon = mkSuperKindTyCon tySuperKindTyConName
+anyKindTyCon = mkKindTyCon anyKindTyConName tySuperKind
liftedTypeKindTyCon = mkKindTyCon liftedTypeKindTyConName tySuperKind
openTypeKindTyCon = mkKindTyCon openTypeKindTyConName tySuperKind
unliftedTypeKindTyCon = mkKindTyCon unliftedTypeKindTyConName tySuperKind
@@ -284,6 +301,7 @@ constraintKindTyCon = mkKindTyCon constraintKindTyConName tySuperKind
-- ... and now their names
tySuperKindTyConName = mkPrimTyConName (fsLit "BOX") tySuperKindTyConKey tySuperKindTyCon
+anyKindTyConName = mkPrimTyConName (fsLit "AnyK") anyKindTyConKey anyKindTyCon
liftedTypeKindTyConName = mkPrimTyConName (fsLit "*") liftedTypeKindTyConKey liftedTypeKindTyCon
openTypeKindTyConName = mkPrimTyConName (fsLit "?") openTypeKindTyConKey openTypeKindTyCon
unliftedTypeKindTyConName = mkPrimTyConName (fsLit "#") unliftedTypeKindTyConKey unliftedTypeKindTyCon
@@ -306,13 +324,15 @@ kindTyConType :: TyCon -> Type
kindTyConType kind = TyConApp kind []
-- | See "Type#kind_subtyping" for details of the distinction between these 'Kind's
-liftedTypeKind, unliftedTypeKind, openTypeKind, argTypeKind, ubxTupleKind, constraintKind :: Kind
+anyKind, liftedTypeKind, unliftedTypeKind, openTypeKind, argTypeKind, ubxTupleKind, constraintKind :: Kind
+-- See Note [Any kinds]
+anyKind = kindTyConType anyKindTyCon
liftedTypeKind = kindTyConType liftedTypeKindTyCon
unliftedTypeKind = kindTyConType unliftedTypeKindTyCon
openTypeKind = kindTyConType openTypeKindTyCon
argTypeKind = kindTyConType argTypeKindTyCon
-ubxTupleKind = kindTyConType ubxTupleKindTyCon
+ubxTupleKind = kindTyConType ubxTupleKindTyCon
constraintKind = kindTyConType constraintKindTyCon
-- | Given two kinds @k1@ and @k2@, creates the 'Kind' @k1 -> k2@
@@ -410,15 +430,13 @@ Note [The ~# TyCon)
~~~~~~~~~~~~~~~~~~~~
There is a perfectly ordinary type constructor ~# that represents the type
of coercions (which, remember, are values). For example
- Refl Int :: ~# Int Int
+ Refl Int :: ~# * Int Int
-Atcually it is not quite "perfectly ordinary" because it is kind-polymorphic:
- Refl Maybe :: ~# Maybe Maybe
+It is a kind-polymorphic type constructor like Any:
+ Refl Maybe :: ~# (* -> *) Maybe Maybe
-So the true kind of ~# :: forall k. k -> k -> #. But we don't have
-polymorphic kinds (yet). However, (~) really only appears saturated in
-which case there is no problem in finding the kind of (ty1 ~# ty2). So
-we check that in CoreLint (and, in an assertion, in Kind.typeKind).
+(~) only appears saturated. So we check that in CoreLint (and, in an
+assertion, in Kind.typeKind).
Note [The State# TyCon]
~~~~~~~~~~~~~~~~~~~~~~~
@@ -440,7 +458,10 @@ statePrimTyCon = pcPrimTyCon statePrimTyConName 1 VoidRep
eqPrimTyCon :: TyCon -- The representation type for equality predicates
-- See Note [The ~# TyCon]
-eqPrimTyCon = pcPrimTyCon eqPrimTyConName 2 VoidRep
+eqPrimTyCon = mkPrimTyCon eqPrimTyConName kind 3 VoidRep
+ where kind = ForAllTy kv $ mkArrowKinds [k, k] unliftedTypeKind
+ kv = kKiVar
+ k = mkTyVarTy kv
\end{code}
RealWorld is deeply magical. It is *primitive*, but it is not
@@ -610,7 +631,7 @@ threadIdPrimTyCon = pcPrimTyCon0 threadIdPrimTyConName PtrRep
Note [Any types]
~~~~~~~~~~~~~~~~
-The type constructor Any::* has these properties
+The type constructor Any of kind forall k. k -> k has these properties:
* It is defined in module GHC.Prim, and exported so that it is
available to users. For this reason it's treated like any other
@@ -633,31 +654,18 @@ The type constructor Any::* has these properties
For example length Any []
See Note [Strangely-kinded void TyCons]
-In addition, we have a potentially-infinite family of types, one for
-each kind /other than/ *, needed to instantiate otherwise
-un-constrained type variables of kinds other than *. This is a bit
-like tuples; there is a potentially-infinite family. They have slightly
-different characteristics to Any::*:
-
- * They are built with TyCon.AnyTyCon
- * They have non-user-writable names like "Any(*->*)"
- * They are not exported by GHC.Prim
- * They are uninhabited (of course; not kind *)
- * They have a unique derived from their OccName (see Note [Uniques of Any])
- * Their Names do not live in the global name cache
-
-Note [Uniques of Any]
-~~~~~~~~~~~~~~~~~~~~~
-Although Any(*->*), say, doesn't have a binding site, it still needs
-to have a Unique. Unlike tuples (which are also an infinite family)
-there is no convenient way to index them, so we use the Unique from
-their OccName instead. That should be unique,
- - both wrt each other, because their strings differ
-
- - and wrt any other Name, because Names get uniques with
- various 'char' tags, but the OccName of Any will
- get a Unique built with mkTcOccUnique, which has a particular 'char'
- tag; see Unique.mkTcOccUnique!
+Note [Any kinds]
+~~~~~~~~~~~~~~~~
+
+The type constructor AnyK (of sort BOX) is used internally only to zonk kind
+variables with no constraints on them. It appears in similar circumstances to
+Any, but at the kind level. For example:
+
+ type family Length (l :: [k]) :: Nat
+ type instance Length [] = Zero
+
+Length is kind-polymorphic, and when applied to the empty (promoted) list it
+will be supplied the kind AnyL: Length AnyK [].
Note [Strangely-kinded void TyCons]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -687,25 +695,9 @@ anyTy :: Type
anyTy = mkTyConTy anyTyCon
anyTyCon :: TyCon
-anyTyCon = mkLiftedPrimTyCon anyTyConName liftedTypeKind 0 PtrRep
+anyTyCon = mkLiftedPrimTyCon anyTyConName kind 1 PtrRep
+ where kind = ForAllTy kKiVar (mkTyVarTy kKiVar)
anyTypeOfKind :: Kind -> Type
-anyTypeOfKind kind = mkTyConApp (anyTyConOfKind kind) []
-
-anyTyConOfKind :: Kind -> TyCon
--- Map all superkinds of liftedTypeKind to liftedTypeKind
-anyTyConOfKind kind
- | isLiftedTypeKind kind = anyTyCon
- | otherwise = tycon
- where
- -- Derive the name from the kind, thus:
- -- Any(*->*), Any(*->*->*)
- -- These are names that can't be written by the user,
- -- and are not allocated in the global name cache
- str = "Any" ++ showSDoc (pprParendKind kind)
-
- occ = mkTcOcc str
- uniq = getUnique occ -- See Note [Uniques of Any]
- name = mkWiredInName gHC_PRIM occ uniq (ATyCon tycon) UserSyntax
- tycon = mkAnyTyCon name kind
+anyTypeOfKind kind = mkTyConApp anyTyCon [kind]
\end{code}
diff --git a/compiler/prelude/TysWiredIn.lhs b/compiler/prelude/TysWiredIn.lhs
index 54acefc087..c6991e1591 100644
--- a/compiler/prelude/TysWiredIn.lhs
+++ b/compiler/prelude/TysWiredIn.lhs
@@ -420,16 +420,25 @@ mkIPName ip tycon_u datacon_u dc_wrk_u co_ax_u = name_ip
\begin{code}
eqTyCon :: TyCon
eqTyCon = mkAlgTyCon eqTyConName
- (mkArrowKinds [openTypeKind, openTypeKind] constraintKind)
- [alphaTyVar, betaTyVar]
+ (ForAllTy kv $ mkArrowKinds [k, k] constraintKind)
+ [kv, a, b]
[] -- No stupid theta
(DataTyCon [eqBoxDataCon] False)
NoParentTyCon
NonRecursive
False
-
+ where
+ kv = kKiVar
+ k = mkTyVarTy kv
+ a:b:_ = tyVarList k
+
eqBoxDataCon :: DataCon
-eqBoxDataCon = pcDataCon eqBoxDataConName [alphaTyVar, betaTyVar] [TyConApp eqPrimTyCon [mkTyVarTy alphaTyVar, mkTyVarTy betaTyVar]] eqTyCon
+eqBoxDataCon = pcDataCon eqBoxDataConName args [TyConApp eqPrimTyCon (map mkTyVarTy args)] eqTyCon
+ where
+ kv = kKiVar
+ k = mkTyVarTy kv
+ a:b:_ = tyVarList k
+ args = [kv, a, b]
\end{code}
\begin{code}
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 5d53713225..fa3a287432 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -1762,13 +1762,13 @@ primtype BCO#
{Primitive bytecode type.}
primop AddrToAnyOp "addrToAny#" GenPrimOp
- Addr# -> (# Any #)
+ Addr# -> (# a #)
{Convert an {\tt Addr\#} to a followable Any type.}
with
code_size = 0
primop MkApUpd0_Op "mkApUpd0#" GenPrimOp
- BCO# -> (# Any #)
+ BCO# -> (# a #)
with
out_of_line = True
@@ -1849,7 +1849,7 @@ pseudoop "lazy"
Like {\tt seq}, the argument of {\tt lazy} can have an unboxed type. }
-primtype Any
+primtype Any a
{ The type constructor {\tt Any} is type to which you can unsafely coerce any
lifted type, and back.
@@ -1880,6 +1880,9 @@ primtype Any
into interface files, we'll get a crash; at least until we add interface-file
syntax to support them. }
+primtype AnyK
+ { JPM Todo }
+
pseudoop "unsafeCoerce#"
a -> b
{ The function {\tt unsafeCoerce\#} allows you to side-step the typechecker entirely. That
diff --git a/compiler/rename/RnBinds.lhs b/compiler/rename/RnBinds.lhs
index faecd40b53..51cd09fb07 100644
--- a/compiler/rename/RnBinds.lhs
+++ b/compiler/rename/RnBinds.lhs
@@ -696,7 +696,7 @@ renameSig ctxt sig@(GenericSig vs ty)
; return (GenericSig new_v new_ty) }
renameSig _ (SpecInstSig ty)
- = do { new_ty <- rnLHsType (text "In a SPECIALISE instance pragma") ty
+ = do { new_ty <- rnLHsType SpecInstSigCtx ty
; return (SpecInstSig new_ty) }
-- {-# SPECIALISE #-} pragmas can refer to imported Ids
diff --git a/compiler/rename/RnEnv.lhs b/compiler/rename/RnEnv.lhs
index c6ab6bb592..c919e46972 100644
--- a/compiler/rename/RnEnv.lhs
+++ b/compiler/rename/RnEnv.lhs
@@ -14,7 +14,7 @@
module RnEnv (
newTopSrcBinder,
lookupLocatedTopBndrRn, lookupTopBndrRn,
- lookupLocatedOccRn, lookupOccRn, lookupLocalOccRn_maybe,
+ lookupLocatedOccRn, lookupOccRn, lookupLocalOccRn_maybe, lookupPromotedOccRn,
lookupGlobalOccRn, lookupGlobalOccRn_maybe,
HsSigCtxt(..), lookupLocalDataTcNames, lookupSigOccRn,
@@ -32,14 +32,16 @@ module RnEnv (
addLocalFixities,
bindLocatedLocalsFV, bindLocatedLocalsRn,
bindSigTyVarsFV, bindPatSigTyVars, bindPatSigTyVarsFV,
- bindTyVarsRn, bindTyVarsFV, extendTyVarEnvFVRn,
+ extendTyVarEnvFVRn,
checkDupRdrNames, checkDupAndShadowedRdrNames,
checkDupNames, checkDupAndShadowedNames,
addFvRn, mapFvRn, mapMaybeFvRn, mapFvRnCPS,
warnUnusedMatches,
warnUnusedTopBinds, warnUnusedLocalBinds,
- dataTcOccs, unknownNameErr, kindSigErr, perhapsForallMsg
+ dataTcOccs, unknownNameErr, kindSigErr, polyKindsErr, perhapsForallMsg,
+
+ HsDocContext(..), docOfHsDocContext
) where
#include "HsVersions.h"
@@ -444,31 +446,61 @@ lookupLocalOccRn_maybe rdr_name
; return (lookupLocalRdrEnv local_env rdr_name) }
-- lookupOccRn looks up an occurrence of a RdrName
+lookupOccRn :: RdrName -> RnM Name
+lookupOccRn rdr_name = do
+ opt_name <- lookupOccRn_maybe rdr_name
+ maybe (unboundName WL_Any rdr_name) return opt_name
+
+-- lookupPromotedOccRn looks up an optionally promoted RdrName.
+lookupPromotedOccRn :: RdrName -> RnM Name
+-- see Note [Demotion] in OccName
+lookupPromotedOccRn rdr_name = do {
+ -- 1. lookup the name
+ opt_name <- lookupOccRn_maybe rdr_name
+ ; case opt_name of
+ -- 1.a. we found it!
+ Just name -> return name
+ -- 1.b. we did not find it -> 2
+ Nothing -> do {
+ ; -- 2. maybe it was implicitly promoted
+ case demoteRdrName rdr_name of
+ -- 2.a it was not in a promoted namespace
+ Nothing -> err
+ -- 2.b let's try every thing again -> 3
+ Just demoted_rdr_name -> do {
+ ; poly_kinds <- xoptM Opt_PolyKinds
+ -- 3. lookup again
+ ; opt_demoted_name <- lookupOccRn_maybe demoted_rdr_name ;
+ ; case opt_demoted_name of
+ -- 3.a. it was implicitly promoted, but confirm that we can promote
+ -- JPM: We could try to suggest turning on PolyKinds here
+ Just demoted_name -> if poly_kinds then return demoted_name else err
+ -- 3.b. use rdr_name to have a correct error message
+ Nothing -> err } } }
+ where err = unboundName WL_Any rdr_name
+
+-- lookupOccRn looks up an occurrence of a RdrName
lookupOccRn_maybe :: RdrName -> RnM (Maybe Name)
lookupOccRn_maybe rdr_name
= do { local_env <- getLocalRdrEnv
- ; case lookupLocalRdrEnv local_env rdr_name of
- Just name -> return (Just name)
- Nothing -> lookupGlobalOccRn_maybe rdr_name }
-
-lookupOccRn :: RdrName -> RnM Name
-lookupOccRn rdr_name
- = do { mb_name <- lookupOccRn_maybe rdr_name
+ ; case lookupLocalRdrEnv local_env rdr_name of {
+ Just name -> return (Just name) ;
+ Nothing -> do
+ { mb_name <- lookupGlobalOccRn_maybe rdr_name
; case mb_name of {
- Just n -> return n ;
- Nothing -> do
-
- { -- We allow qualified names on the command line to refer to
- -- *any* name exported by any module in scope, just as if there
- -- was an "import qualified M" declaration for every module.
- allow_qual <- doptM Opt_ImplicitImportQualified
+ Just name -> return (Just name) ;
+ Nothing -> do
+ { -- We allow qualified names on the command line to refer to
+ -- *any* name exported by any module in scope, just as if there
+ -- was an "import qualified M" declaration for every module.
+ allow_qual <- doptM Opt_ImplicitImportQualified
; is_ghci <- getIsGHCi
-- This test is not expensive,
-- and only happens for failed lookups
; if isQual rdr_name && allow_qual && is_ghci
then lookupQualifiedName rdr_name
else do { traceRn (text "lookupOccRn" <+> ppr rdr_name)
- ; unboundName WL_Any rdr_name } } } }
+ ; return Nothing } } } } } }
lookupGlobalOccRn :: RdrName -> RnM Name
@@ -564,7 +596,7 @@ addUsedRdrNames rdrs
-- A qualified name on the command line can refer to any module at all: we
-- try to load the interface if we don't already have it.
-lookupQualifiedName :: RdrName -> RnM Name
+lookupQualifiedName :: RdrName -> RnM (Maybe Name)
lookupQualifiedName rdr_name
| Just (mod,occ) <- isQual_maybe rdr_name
-- Note: we want to behave as we would for a source file import here,
@@ -575,9 +607,9 @@ lookupQualifiedName rdr_name
| avail <- mi_exports iface,
name <- availNames avail,
nameOccName name == occ ] of
- (n:ns) -> ASSERT (null ns) return n
+ (n:ns) -> ASSERT (null ns) return (Just n)
_ -> do { traceRn (text "lookupQualified" <+> ppr rdr_name)
- ; unboundName WL_Any rdr_name }
+ ; return Nothing }
| otherwise
= pprPanic "RnEnv.lookupQualifiedName" (ppr rdr_name)
@@ -962,28 +994,6 @@ bindLocatedLocalsFV rdr_names enclosed_scope
return (thing, delFVs names fvs)
-------------------------------------
-bindTyVarsFV :: [LHsTyVarBndr RdrName]
- -> ([LHsTyVarBndr Name] -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-bindTyVarsFV tyvars thing_inside
- = bindTyVarsRn tyvars $ \ tyvars' ->
- do { (res, fvs) <- thing_inside tyvars'
- ; return (res, delFVs (map hsLTyVarName tyvars') fvs) }
-
-bindTyVarsRn :: [LHsTyVarBndr RdrName]
- -> ([LHsTyVarBndr Name] -> RnM a)
- -> RnM a
--- Haskell-98 binding of type variables; e.g. within a data type decl
-bindTyVarsRn tyvar_names enclosed_scope
- = bindLocatedLocalsRn located_tyvars $ \ names ->
- do { kind_sigs_ok <- xoptM Opt_KindSignatures
- ; unless (null kinded_tyvars || kind_sigs_ok)
- (mapM_ (addErr . kindSigErr) kinded_tyvars)
- ; enclosed_scope (zipWith replaceLTyVarName tyvar_names names) }
- where
- located_tyvars = hsLTyVarLocNames tyvar_names
- kinded_tyvars = [n | L _ (KindedTyVar n _) <- tyvar_names]
-
bindPatSigTyVars :: [LHsType RdrName] -> ([Name] -> RnM a) -> RnM a
-- Find the type variables in the pattern type
-- signatures that must be brought into scope
@@ -1402,6 +1412,11 @@ kindSigErr thing
= hang (ptext (sLit "Illegal kind signature for") <+> quotes (ppr thing))
2 (ptext (sLit "Perhaps you intended to use -XKindSignatures"))
+polyKindsErr :: Outputable a => a -> SDoc
+polyKindsErr thing
+ = hang (ptext (sLit "Illegal kind:") <+> quotes (ppr thing))
+ 2 (ptext (sLit "Perhaps you intended to use -XPolyKinds"))
+
badQualBndrErr :: RdrName -> SDoc
badQualBndrErr rdr_name
@@ -1412,3 +1427,56 @@ opDeclErr n
= hang (ptext (sLit "Illegal declaration of a type or class operator") <+> quotes (ppr n))
2 (ptext (sLit "Use -XTypeOperators to declare operators in type and declarations"))
\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Contexts for renaming errors}
+%* *
+%************************************************************************
+
+\begin{code}
+
+data HsDocContext
+ = TypeSigCtx SDoc
+ | PatCtx
+ | SpecInstSigCtx
+ | DefaultDeclCtx
+ | ForeignDeclCtx (Located RdrName)
+ | DerivDeclCtx
+ | RuleCtx FastString
+ | TyDataCtx (Located RdrName)
+ | TySynCtx (Located RdrName)
+ | TyFamilyCtx (Located RdrName)
+ | ConDeclCtx (Located RdrName)
+ | ClassDeclCtx (Located RdrName)
+ | ExprWithTySigCtx
+ | TypBrCtx
+ | HsTypeCtx
+ | GHCiCtx
+ | SpliceTypeCtx (LHsType RdrName)
+ | ClassInstanceCtx
+ | VectDeclCtx (Located RdrName)
+
+docOfHsDocContext :: HsDocContext -> SDoc
+docOfHsDocContext (TypeSigCtx doc) = text "In the type signature for" <+> doc
+docOfHsDocContext PatCtx = text "In a pattern type-signature"
+docOfHsDocContext SpecInstSigCtx = text "In a SPECIALISE instance pragma"
+docOfHsDocContext DefaultDeclCtx = text "In a `default' declaration"
+docOfHsDocContext (ForeignDeclCtx name) = ptext (sLit "In the foreign declaration for") <+> ppr name
+docOfHsDocContext DerivDeclCtx = text "In a deriving declaration"
+docOfHsDocContext (RuleCtx name) = text "In the transformation rule" <+> ftext name
+docOfHsDocContext (TyDataCtx tycon) = text "In the data type declaration for" <+> quotes (ppr tycon)
+docOfHsDocContext (TySynCtx name) = text "In the declaration for type synonym" <+> quotes (ppr name)
+docOfHsDocContext (TyFamilyCtx name) = text "In the declaration for type family" <+> quotes (ppr name)
+docOfHsDocContext (ConDeclCtx name) = text "In the definition of data constructor" <+> quotes (ppr name)
+docOfHsDocContext (ClassDeclCtx name) = text "In the declaration for class" <+> ppr name
+docOfHsDocContext ExprWithTySigCtx = text "In an expression type signature"
+docOfHsDocContext TypBrCtx = ptext (sLit "In a Template-Haskell quoted type")
+docOfHsDocContext HsTypeCtx = text "In a type argument"
+docOfHsDocContext GHCiCtx = ptext (sLit "In GHCi input")
+docOfHsDocContext (SpliceTypeCtx hs_ty) = ptext (sLit "In the spliced type") <+> ppr hs_ty
+docOfHsDocContext ClassInstanceCtx = ptext (sLit "TcSplice.reifyInstances")
+docOfHsDocContext (VectDeclCtx tycon) = ptext (sLit "In the VECTORISE pragma for type constructor") <+> quotes (ppr tycon)
+
+\end{code}
diff --git a/compiler/rename/RnExpr.lhs b/compiler/rename/RnExpr.lhs
index f57998ef44..7f863808eb 100644
--- a/compiler/rename/RnExpr.lhs
+++ b/compiler/rename/RnExpr.lhs
@@ -169,8 +169,13 @@ rnExpr (NegApp e _)
-- Don't ifdef-GHCI them because we want to fail gracefully
-- (not with an rnExpr crash) in a stage-1 compiler.
rnExpr e@(HsBracket br_body)
- = checkTH e "bracket" `thenM_`
- rnBracket br_body `thenM` \ (body', fvs_e) ->
+ = do
+ thEnabled <- xoptM Opt_TemplateHaskell
+ unless thEnabled $
+ failWith ( vcat [ ptext (sLit "Syntax error on") <+> ppr e
+ , ptext (sLit "Perhaps you intended to use -XTemplateHaskell") ] )
+ checkTH e "bracket"
+ (body', fvs_e) <- rnBracket br_body
return (HsBracket body', fvs_e)
rnExpr (HsSpliceE splice)
@@ -265,12 +270,10 @@ rnExpr (RecordUpd expr rbinds _ _ _)
fvExpr `plusFV` fvRbinds) }
rnExpr (ExprWithTySig expr pty)
- = do { (pty', fvTy) <- rnHsTypeFVs doc pty
+ = do { (pty', fvTy) <- rnHsTypeFVs ExprWithTySigCtx pty
; (expr', fvExpr) <- bindSigTyVarsFV (hsExplicitTvs pty') $
rnLExpr expr
; return (ExprWithTySig expr' pty', fvExpr `plusFV` fvTy) }
- where
- doc = text "In an expression type signature"
rnExpr (HsIf _ p b1 b2)
= do { (p', fvP) <- rnLExpr p
@@ -280,10 +283,8 @@ rnExpr (HsIf _ p b1 b2)
; return (HsIf mb_ite p' b1' b2', plusFVs [fvITE, fvP, fvB1, fvB2]) }
rnExpr (HsType a)
- = rnHsTypeFVs doc a `thenM` \ (t, fvT) ->
+ = rnHsTypeFVs HsTypeCtx a `thenM` \ (t, fvT) ->
return (HsType t, fvT)
- where
- doc = text "In a type argument"
rnExpr (ArithSeq _ seq)
= rnArithSeq seq `thenM` \ (new_seq, fvs) ->
@@ -590,14 +591,14 @@ rnArithSeq (FromThenTo expr1 expr2 expr3)
\begin{code}
rnBracket :: HsBracket RdrName -> RnM (HsBracket Name, FreeVars)
-rnBracket (VarBr n)
+rnBracket (VarBr flg n)
= do { name <- lookupOccRn n
; this_mod <- getModule
; unless (nameIsLocalOrFrom this_mod name) $ -- Reason: deprecation checking assumes
do { _ <- loadInterfaceForName msg name -- the home interface is loaded, and
; return () } -- this is the only way that is going
-- to happen
- ; return (VarBr name, unitFV name) }
+ ; return (VarBr flg name, unitFV name) }
where
msg = ptext (sLit "Need interface for Template Haskell quoted Name")
@@ -606,10 +607,8 @@ rnBracket (ExpBr e) = do { (e', fvs) <- rnLExpr e
rnBracket (PatBr p) = rnPat ThPatQuote p $ \ p' -> return (PatBr p', emptyFVs)
-rnBracket (TypBr t) = do { (t', fvs) <- rnHsTypeFVs doc t
+rnBracket (TypBr t) = do { (t', fvs) <- rnHsTypeFVs TypBrCtx t
; return (TypBr t', fvs) }
- where
- doc = ptext (sLit "In a Template-Haskell quoted type")
rnBracket (DecBrL decls)
= do { (group, mb_splice) <- findSplice decls
diff --git a/compiler/rename/RnExpr.lhs-boot b/compiler/rename/RnExpr.lhs-boot
index 2d59537b95..5ca81d6db4 100644
--- a/compiler/rename/RnExpr.lhs-boot
+++ b/compiler/rename/RnExpr.lhs-boot
@@ -1,4 +1,4 @@
-\begin{code}
+\begin{code}
{-# OPTIONS -fno-warn-tabs #-}
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and
@@ -6,19 +6,19 @@
-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
-- for details
-module RnExpr where
-import HsSyn
-import Name ( Name )
-import NameSet ( FreeVars )
-import RdrName ( RdrName )
-import TcRnTypes
-
-rnLExpr :: LHsExpr RdrName
- -> RnM (LHsExpr Name, FreeVars)
-
-rnStmts :: --forall thing.
- HsStmtContext Name -> [LStmt RdrName]
- -> ([Name] -> RnM (thing, FreeVars))
- -> RnM (([LStmt Name], thing), FreeVars)
-\end{code}
-
+module RnExpr where
+import HsSyn
+import Name ( Name )
+import NameSet ( FreeVars )
+import RdrName ( RdrName )
+import TcRnTypes
+
+rnLExpr :: LHsExpr RdrName
+ -> RnM (LHsExpr Name, FreeVars)
+
+rnStmts :: --forall thing.
+ HsStmtContext Name -> [LStmt RdrName]
+ -> ([Name] -> RnM (thing, FreeVars))
+ -> RnM (([LStmt Name], thing), FreeVars)
+\end{code}
+
diff --git a/compiler/rename/RnHsSyn.lhs b/compiler/rename/RnHsSyn.lhs
index 7b0591dd19..e2369bb776 100644
--- a/compiler/rename/RnHsSyn.lhs
+++ b/compiler/rename/RnHsSyn.lhs
@@ -16,6 +16,7 @@ module RnHsSyn(
charTyCon_name, listTyCon_name, parrTyCon_name, tupleTyCon_name,
extractHsTyVars, extractHsTyNames, extractHsTyNames_s,
extractFunDepNames, extractHsCtxtTyNames,
+ extractHsTyVarBndrNames, extractHsTyVarBndrNames_s,
-- Free variables
hsSigsFVs, hsSigFVs, conDeclFVs, bangTyFVs
@@ -30,6 +31,7 @@ import Name ( Name, getName, isTyVarName )
import NameSet
import BasicTypes ( TupleSort )
import SrcLoc
+import Panic ( panic )
\end{code}
%************************************************************************
@@ -56,6 +58,7 @@ extractFunDepNames :: FunDep Name -> NameSet
extractFunDepNames (ns1, ns2) = mkNameSet ns1 `unionNameSets` mkNameSet ns2
extractHsTyNames :: LHsType Name -> NameSet
+-- Also extract names in kinds.
extractHsTyNames ty
= getl ty
where
@@ -68,22 +71,24 @@ extractHsTyNames ty
get (HsFunTy ty1 ty2) = getl ty1 `unionNameSets` getl ty2
get (HsIParamTy _ ty) = getl ty
get (HsEqTy ty1 ty2) = getl ty1 `unionNameSets` getl ty2
- get (HsOpTy ty1 op ty2) = getl ty1 `unionNameSets` getl ty2 `unionNameSets` unitNameSet (unLoc op)
+ get (HsOpTy ty1 (_, op) ty2) = getl ty1 `unionNameSets` getl ty2 `unionNameSets` unitNameSet (unLoc op)
get (HsParTy ty) = getl ty
get (HsBangTy _ ty) = getl ty
get (HsRecTy flds) = extractHsTyNames_s (map cd_fld_type flds)
get (HsTyVar tv) = unitNameSet tv
get (HsSpliceTy _ fvs _) = fvs
get (HsQuasiQuoteTy {}) = emptyNameSet
- get (HsKindSig ty _) = getl ty
+ get (HsKindSig ty ki) = getl ty `unionNameSets` getl ki
get (HsForAllTy _ tvs
- ctxt ty) = (extractHsCtxtTyNames ctxt
- `unionNameSets` getl ty)
- `minusNameSet`
- mkNameSet (hsLTyVarNames tvs)
+ ctxt ty) = extractHsTyVarBndrNames_s tvs
+ (extractHsCtxtTyNames ctxt
+ `unionNameSets` getl ty)
get (HsDocTy ty _) = getl ty
get (HsCoreTy {}) = emptyNameSet -- This probably isn't quite right
-- but I don't think it matters
+ get (HsExplicitListTy _ tys) = extractHsTyNames_s tys
+ get (HsExplicitTupleTy _ tys) = extractHsTyNames_s tys
+ get (HsWrapTy {}) = panic "extractHsTyNames"
extractHsTyNames_s :: [LHsType Name] -> NameSet
extractHsTyNames_s tys = foldr (unionNameSets . extractHsTyNames) emptyNameSet tys
@@ -91,6 +96,18 @@ extractHsTyNames_s tys = foldr (unionNameSets . extractHsTyNames) emptyNameSet t
extractHsCtxtTyNames :: LHsContext Name -> NameSet
extractHsCtxtTyNames (L _ ctxt)
= foldr (unionNameSets . extractHsTyNames) emptyNameSet ctxt
+
+extractHsTyVarBndrNames :: LHsTyVarBndr Name -> NameSet
+extractHsTyVarBndrNames (L _ (UserTyVar _ _)) = emptyNameSet
+extractHsTyVarBndrNames (L _ (KindedTyVar _ ki _)) = extractHsTyNames ki
+
+extractHsTyVarBndrNames_s :: [LHsTyVarBndr Name] -> NameSet -> NameSet
+-- Update the name set 'body' by adding the names in the binders
+-- kinds and handling scoping.
+extractHsTyVarBndrNames_s [] body = body
+extractHsTyVarBndrNames_s (b:bs) body =
+ (extractHsTyVarBndrNames_s bs body `delFromNameSet` hsTyVarName (unLoc b))
+ `unionNameSets` extractHsTyVarBndrNames b
\end{code}
@@ -125,7 +142,7 @@ hsSigFVs _ = emptyFVs
conDeclFVs :: LConDecl Name -> FreeVars
conDeclFVs (L _ (ConDecl { con_qvars = tyvars, con_cxt = context,
con_details = details, con_res = res_ty}))
- = delFVs (map hsLTyVarName tyvars) $
+ = extractHsTyVarBndrNames_s tyvars $
extractHsCtxtTyNames context `plusFV`
conDetailsFVs details `plusFV`
conResTyFVs res_ty
diff --git a/compiler/rename/RnPat.lhs b/compiler/rename/RnPat.lhs
index 5c28f73a56..740acc42c5 100644
--- a/compiler/rename/RnPat.lhs
+++ b/compiler/rename/RnPat.lhs
@@ -314,12 +314,11 @@ rnPatAndThen mk (SigPatIn pat ty)
= do { patsigs <- liftCps (xoptM Opt_ScopedTypeVariables)
; if patsigs
then do { pat' <- rnLPatAndThen mk pat
- ; ty' <- liftCpsFV (rnHsTypeFVs tvdoc ty)
+ ; ty' <- liftCpsFV (rnHsTypeFVs PatCtx ty)
; return (SigPatIn pat' ty') }
else do { liftCps (addErr (patSigErr ty))
; rnPatAndThen mk (unLoc pat) } }
- where
- tvdoc = text "In a pattern type-signature"
+
rnPatAndThen mk (LitPat lit)
| HsString s <- lit
diff --git a/compiler/rename/RnSource.lhs b/compiler/rename/RnSource.lhs
index 8b34fb4e5b..b6247d449b 100644
--- a/compiler/rename/RnSource.lhs
+++ b/compiler/rename/RnSource.lhs
@@ -50,7 +50,7 @@ import SrcLoc
import DynFlags
import HscTypes ( HscEnv, hsc_dflags )
import ListSetOps ( findDupsEq )
-import Digraph ( SCC, flattenSCC, stronglyConnCompFromEdgedVertices )
+import Digraph ( SCC, flattenSCCs, stronglyConnCompFromEdgedVertices )
import Control.Monad
import Maybes( orElse )
@@ -359,7 +359,7 @@ rnDefaultDecl (DefaultDecl tys)
= do { (tys', fvs) <- mapFvRn (rnHsTypeFVs doc_str) tys
; return (DefaultDecl tys', fvs) }
where
- doc_str = text "In a `default' declaration"
+ doc_str = DefaultDeclCtx
\end{code}
%*********************************************************
@@ -373,7 +373,7 @@ rnHsForeignDecl :: ForeignDecl RdrName -> RnM (ForeignDecl Name, FreeVars)
rnHsForeignDecl (ForeignImport name ty _ spec)
= do { topEnv :: HscEnv <- getTopEnv
; name' <- lookupLocatedTopBndrRn name
- ; (ty', fvs) <- rnHsTypeFVs (fo_decl_msg name) ty
+ ; (ty', fvs) <- rnHsTypeFVs (ForeignDeclCtx name) ty
-- Mark any PackageTarget style imports as coming from the current package
; let packageId = thisPackage $ hsc_dflags topEnv
@@ -383,16 +383,12 @@ rnHsForeignDecl (ForeignImport name ty _ spec)
rnHsForeignDecl (ForeignExport name ty _ spec)
= do { name' <- lookupLocatedOccRn name
- ; (ty', fvs) <- rnHsTypeFVs (fo_decl_msg name) ty
+ ; (ty', fvs) <- rnHsTypeFVs (ForeignDeclCtx name) ty
; return (ForeignExport name' ty' noForeignExportCoercionYet spec, fvs `addOneFV` unLoc name') }
-- NB: a foreign export is an *occurrence site* for name, so
-- we add it to the free-variable list. It might, for example,
-- be imported from another module
-fo_decl_msg :: Located RdrName -> SDoc
-fo_decl_msg name = ptext (sLit "In the foreign declaration for") <+> ppr name
-
-
-- | For Windows DLLs we need to know what packages imported symbols are from
-- to generate correct calls. Imported symbols are tagged with the current
-- package, so if they get inlined across a package boundry we'll still
@@ -546,7 +542,7 @@ rnHsRuleDecl (HsRule rule_name act vars lhs _fv_lhs rhs _fv_rhs)
; return (HsRule rule_name act vars' lhs' fv_lhs' rhs' fv_rhs',
fv_vars `plusFV` fv_lhs' `plusFV` fv_rhs') }
where
- doc = text "In the transformation rule" <+> ftext rule_name
+ doc = RuleCtx rule_name
get_var (RuleBndr v) = v
get_var (RuleBndrSig v _) = v
@@ -715,7 +711,13 @@ rnTyClDecls tycl_ds
all_fvs = foldr (plusFV . snd) emptyFVs ds_w_fvs
- ; return (map flattenSCC sccs, all_fvs) }
+ ; return ([flattenSCCs sccs], all_fvs) }
+-- JPM: This is wrong. We are calculating the SCCs but then ignore them and
+-- merge into a single, big group. This is a quick fix to allow
+-- mutually-recursive types across modules to work, given the new way of kind
+-- checking and type checking declarations in groups (see
+-- Note [Grouping of type and class declarations] in TcTyClsDecls). This "fix"
+-- fully breaks promotion; we will fix that later.
rnTyClDecl :: Maybe Name -- Just cls => this TyClDecl is nested
-- inside an *instance decl* for cls
@@ -731,12 +733,16 @@ rnTyClDecl _ (ForeignType {tcdLName = name, tcdExtName = ext_name})
-- and "data family"), both top level and (for an associated type)
-- in a class decl
rnTyClDecl mb_cls (TyFamily { tcdLName = tycon, tcdTyVars = tyvars
- , tcdFlavour = flav, tcdKind = kind })
- = bindQTvs mb_cls tyvars $ \tyvars' ->
+ , tcdFlavour = flav, tcdKind = kind })
+ = bindQTvs fmly_doc mb_cls tyvars $ \tyvars' ->
do { tycon' <- lookupLocatedTopBndrRn tycon
+ ; kind' <- rnLHsMaybeKind fmly_doc kind
+ ; let fv_kind = maybe emptyFVs extractHsTyNames kind'
+ fvs = extractHsTyVarBndrNames_s tyvars' fv_kind
; return ( TyFamily { tcdLName = tycon', tcdTyVars = tyvars'
- , tcdFlavour = flav, tcdKind = kind }
- , emptyFVs) }
+ , tcdFlavour = flav, tcdKind = kind' }
+ , fvs) }
+ where fmly_doc = TyFamilyCtx tycon
-- "data", "newtype", "data instance, and "newtype instance" declarations
-- both top level and (for an associated type) in an instance decl
@@ -745,17 +751,19 @@ rnTyClDecl mb_cls tydecl@TyData {tcdND = new_or_data, tcdCtxt = context,
tcdTyPats = typats, tcdCons = condecls,
tcdKindSig = sig, tcdDerivs = derivs}
= do { tycon' <- lookupTcdName mb_cls tydecl
+ ; sig' <- rnLHsMaybeKind data_doc sig
; checkTc (h98_style || null (unLoc context))
(badGadtStupidTheta tycon)
; ((tyvars', context', typats', derivs'), stuff_fvs)
- <- bindQTvs mb_cls tyvars $ \ tyvars' -> do
+ <- bindQTvs data_doc mb_cls tyvars $ \ tyvars' -> do
-- Checks for distinct tyvars
{ context' <- rnContext data_doc context
; (typats', fvs1) <- rnTyPats data_doc tycon' typats
; (derivs', fvs2) <- rn_derivs derivs
; let fvs = fvs1 `plusFV` fvs2 `plusFV`
extractHsCtxtTyNames context'
+ `plusFV` maybe emptyFVs extractHsTyNames sig'
; return ((tyvars', context', typats', derivs'), fvs) }
-- For the constructor declarations, bring into scope the tyvars
@@ -772,7 +780,7 @@ rnTyClDecl mb_cls tydecl@TyData {tcdND = new_or_data, tcdCtxt = context,
; return (TyData {tcdND = new_or_data, tcdCtxt = context',
tcdLName = tycon', tcdTyVars = tyvars',
- tcdTyPats = typats', tcdKindSig = sig,
+ tcdTyPats = typats', tcdKindSig = sig',
tcdCons = condecls', tcdDerivs = derivs'},
con_fvs `plusFV` stuff_fvs)
}
@@ -780,8 +788,8 @@ rnTyClDecl mb_cls tydecl@TyData {tcdND = new_or_data, tcdCtxt = context,
h98_style = case condecls of -- Note [Stupid theta]
L _ (ConDecl { con_res = ResTyGADT {} }) : _ -> False
_ -> True
-
- data_doc = text "In the data type declaration for" <+> quotes (ppr tycon)
+
+ data_doc = TyDataCtx tycon
rn_derivs Nothing = return (Nothing, emptyFVs)
rn_derivs (Just ds) = do { ds' <- rnLHsTypes data_doc ds
@@ -790,16 +798,16 @@ rnTyClDecl mb_cls tydecl@TyData {tcdND = new_or_data, tcdCtxt = context,
-- "type" and "type instance" declarations
rnTyClDecl mb_cls tydecl@(TySynonym { tcdTyVars = tyvars, tcdLName = name,
tcdTyPats = typats, tcdSynRhs = ty})
- = bindQTvs mb_cls tyvars $ \ tyvars' -> do
+ = bindQTvs syn_doc mb_cls tyvars $ \ tyvars' -> do
{ -- Checks for distinct tyvars
name' <- lookupTcdName mb_cls tydecl
; (typats',fvs1) <- rnTyPats syn_doc name' typats
; (ty', fvs2) <- rnHsTypeFVs syn_doc ty
- ; return (TySynonym { tcdLName = name', tcdTyVars = tyvars'
- , tcdTyPats = typats', tcdSynRhs = ty'},
- fvs1 `plusFV` fvs2) }
+ ; return (TySynonym { tcdLName = name', tcdTyVars = tyvars'
+ , tcdTyPats = typats', tcdSynRhs = ty'}
+ , extractHsTyVarBndrNames_s tyvars' (fvs1 `plusFV` fvs2)) }
where
- syn_doc = text "In the declaration for type synonym" <+> quotes (ppr name)
+ syn_doc = TySynCtx name
rnTyClDecl _ (ClassDecl {tcdCtxt = context, tcdLName = lcls,
tcdTyVars = tyvars, tcdFDs = fds, tcdSigs = sigs,
@@ -810,10 +818,10 @@ rnTyClDecl _ (ClassDecl {tcdCtxt = context, tcdLName = lcls,
-- Tyvars scope over superclass context and method signatures
; ((tyvars', context', fds', ats', at_defs', sigs'), stuff_fvs)
- <- bindTyVarsFV tyvars $ \ tyvars' -> do
+ <- bindTyVarsFV cls_doc tyvars $ \ tyvars' -> do
-- Checks for distinct tyvars
{ context' <- rnContext cls_doc context
- ; fds' <- rnFds cls_doc fds
+ ; fds' <- rnFds (docOfHsDocContext cls_doc) fds
; let rn_at = rnTyClDecl (Just cls')
; (ats', fv_ats) <- mapAndUnzipM (wrapLocFstM rn_at) ats
; sigs' <- renameSigs (ClsDeclCtxt cls') sigs
@@ -859,21 +867,20 @@ rnTyClDecl _ (ClassDecl {tcdCtxt = context, tcdLName = lcls,
tcdTyVars = tyvars', tcdFDs = fds', tcdSigs = sigs',
tcdMeths = mbinds', tcdATs = ats', tcdATDefs = at_defs',
tcdDocs = docs'},
- meth_fvs `plusFV` stuff_fvs) }
+ extractHsTyVarBndrNames_s tyvars' (meth_fvs `plusFV` stuff_fvs)) }
where
- cls_doc = text "In the declaration for class" <+> ppr lcls
+ cls_doc = ClassDeclCtx lcls
-bindQTvs :: Maybe Name -> [LHsTyVarBndr RdrName]
+bindQTvs :: HsDocContext -> Maybe Name -> [LHsTyVarBndr RdrName]
-> ([LHsTyVarBndr Name] -> RnM (a, FreeVars))
-> RnM (a, FreeVars)
--- For *associated* type/data family instances (in an instance decl)
--- don't quantify over the already-in-scope type variables
-bindQTvs mb_cls tyvars thing_inside
+bindQTvs doc mb_cls tyvars thing_inside
| isNothing mb_cls -- Not associated
- = bindTyVarsFV tyvars thing_inside
+ = bindTyVarsFV doc tyvars thing_inside
| otherwise -- Associated
= do { let tv_rdr_names = map hsLTyVarLocName tyvars
+ -- *All* the free vars of the family patterns
-- Check for duplicated bindings
-- This test is irrelevant for data/type *instances*, where the tyvars
@@ -882,9 +889,10 @@ bindQTvs mb_cls tyvars thing_inside
; mapM_ dupBoundTyVar (findDupRdrNames tv_rdr_names)
; rdr_env <- getLocalRdrEnv
+
; tv_ns <- mapM (mk_tv_name rdr_env) tv_rdr_names
- ; (thing, fvs) <- bindLocalNamesFV tv_ns $
- thing_inside (zipWith replaceLTyVarName tyvars tv_ns)
+ ; tyvars' <- zipWithM (\old new -> replaceLTyVarName old new (rnLHsKind doc)) tyvars tv_ns
+ ; (thing, fvs) <- bindLocalNamesFV tv_ns $ thing_inside tyvars'
-- Check that the RHS of the decl mentions only type variables
-- bound on the LHS. For example, this is not ok
@@ -942,10 +950,21 @@ depAnalTyClDecls ds_w_fvs
edges = [ (d, tcdName (unLoc d), map get_assoc (nameSetToList fvs))
| (d, fvs) <- ds_w_fvs ]
get_assoc n = lookupNameEnv assoc_env n `orElse` n
- assoc_env = mkNameEnv [ (tcdName assoc_decl, cls_name)
- | (L _ (ClassDecl { tcdLName = L _ cls_name
- , tcdATs = ats }) ,_) <- ds_w_fvs
- , L _ assoc_decl <- ats ]
+ assoc_env = mkNameEnv assoc_env_list
+ -- We also need to consider data constructor names since they may
+ -- appear in types because of promotion.
+ assoc_env_list = do
+ (L _ d, _) <- ds_w_fvs
+ case d of
+ ClassDecl { tcdLName = L _ cls_name
+ , tcdATs = ats } -> do
+ L _ assoc_decl <- ats
+ return (tcdName assoc_decl, cls_name)
+ TyData { tcdLName = L _ data_name
+ , tcdCons = cons } -> do
+ L _ dc <- cons
+ return (unLoc (con_name dc), data_name)
+ _ -> []
\end{code}
Note [Dependency analysis of type and class decls]
@@ -969,7 +988,7 @@ is jolly confusing. See Trac #4875
%*********************************************************
\begin{code}
-rnTyPats :: SDoc -> Located Name -> Maybe [LHsType RdrName] -> RnM (Maybe [LHsType Name], FreeVars)
+rnTyPats :: HsDocContext -> Located Name -> Maybe [LHsType RdrName] -> RnM (Maybe [LHsType Name], FreeVars)
-- Although, we are processing type patterns here, all type variables will
-- already be in scope (they are the same as in the 'tcdTyVars' field of the
-- type declaration to which these patterns belong)
@@ -1009,22 +1028,22 @@ rnConDecl decl@(ConDecl { con_name = name, con_qvars = tvs
-- With Implicit, find the mentioned ones, and use them as binders
; new_tvs <- case expl of
Implicit -> return (userHsTyVarBndrs mentioned_tvs)
- Explicit -> do { warnUnusedForAlls doc tvs mentioned_tvs
+ Explicit -> do { warnUnusedForAlls (docOfHsDocContext doc) tvs mentioned_tvs
; return tvs }
; mb_doc' <- rnMbLHsDoc mb_doc
- ; bindTyVarsRn new_tvs $ \new_tyvars -> do
+ ; bindTyVarsRn doc new_tvs $ \new_tyvars -> do
{ new_context <- rnContext doc cxt
; new_details <- rnConDeclDetails doc details
; (new_details', new_res_ty) <- rnConResult doc new_details res_ty
; return (decl { con_name = new_name, con_qvars = new_tyvars, con_cxt = new_context
, con_details = new_details', con_res = new_res_ty, con_doc = mb_doc' }) }}
where
- doc = text "In the definition of data constructor" <+> quotes (ppr name)
+ doc = ConDeclCtx name
get_rdr_tvs tys = extractHsRhoRdrTyVars cxt (noLoc (HsTupleTy (HsBoxyTuple liftedTypeKind) tys))
-rnConResult :: SDoc
+rnConResult :: HsDocContext
-> HsConDetails (LHsType Name) [ConDeclField Name]
-> ResType RdrName
-> RnM (HsConDetails (LHsType Name) [ConDeclField Name],
@@ -1044,10 +1063,10 @@ rnConResult doc details (ResTyGADT ty)
-- See Note [Sorting out the result type] in RdrHsSyn
; when (not (null arg_tys) && case details of { RecCon {} -> True; _ -> False })
- (addErr (badRecResTy doc))
+ (addErr (badRecResTy (docOfHsDocContext doc)))
; return (details', ResTyGADT res_ty) }
-rnConDeclDetails :: SDoc
+rnConDeclDetails :: HsDocContext
-> HsConDetails (LHsType RdrName) [ConDeclField RdrName]
-> RnM (HsConDetails (LHsType Name) [ConDeclField Name])
rnConDeclDetails doc (PrefixCon tys)
diff --git a/compiler/rename/RnTypes.lhs b/compiler/rename/RnTypes.lhs
index 3607170e70..df6008b574 100644
--- a/compiler/rename/RnTypes.lhs
+++ b/compiler/rename/RnTypes.lhs
@@ -14,6 +14,7 @@
module RnTypes (
-- Type related stuff
rnHsType, rnLHsType, rnLHsTypes, rnContext,
+ rnHsKind, rnLHsKind, rnLHsMaybeKind,
rnHsSigType, rnLHsInstType, rnHsTypeFVs, rnConDeclFields,
rnIPName,
@@ -22,7 +23,10 @@ module RnTypes (
checkPrecMatch, checkSectionPrec, warnUnusedForAlls,
-- Splice related stuff
- rnSplice, checkTH
+ rnSplice, checkTH,
+
+ -- Binding related stuff
+ bindTyVarsRn, bindTyVarsFV
) where
import {-# SOURCE #-} RnExpr( rnLExpr )
@@ -33,7 +37,7 @@ import {-# SOURCE #-} TcSplice( runQuasiQuoteType )
import DynFlags
import HsSyn
import RdrHsSyn ( extractHsRhoRdrTyVars )
-import RnHsSyn ( extractHsTyNames )
+import RnHsSyn ( extractHsTyNames, extractHsTyVarBndrNames_s )
import RnHsDoc ( rnLHsDoc, rnMbLHsDoc )
import RnEnv
import TcRnMonad
@@ -50,7 +54,7 @@ import BasicTypes ( IPName(..), ipNameName, compareFixity, funTyFixity, negateFi
Fixity(..), FixityDirection(..) )
import Outputable
import FastString
-import Control.Monad ( unless )
+import Control.Monad ( unless, zipWithM )
#include "HsVersions.h"
\end{code}
@@ -65,7 +69,7 @@ to break several loop.
%*********************************************************
\begin{code}
-rnHsTypeFVs :: SDoc -> LHsType RdrName -> RnM (LHsType Name, FreeVars)
+rnHsTypeFVs :: HsDocContext -> LHsType RdrName -> RnM (LHsType Name, FreeVars)
rnHsTypeFVs doc_str ty = do
ty' <- rnLHsType doc_str ty
return (ty', extractHsTyNames ty')
@@ -74,12 +78,12 @@ rnHsSigType :: SDoc -> LHsType RdrName -> RnM (LHsType Name)
-- rnHsSigType is used for source-language type signatures,
-- which use *implicit* universal quantification.
rnHsSigType doc_str ty
- = rnLHsType (text "In the type signature for" <+> doc_str) ty
+ = rnLHsType (TypeSigCtx doc_str) ty
rnLHsInstType :: SDoc -> LHsType RdrName -> RnM (LHsType Name)
-- Rename the type in an instance or standalone deriving decl
rnLHsInstType doc_str ty
- = do { ty' <- rnLHsType doc_str ty
+ = do { ty' <- rnLHsType (TypeSigCtx doc_str) ty
; unless good_inst_ty (addErrAt (getLoc ty) (badInstTy ty))
; return ty' }
where
@@ -96,12 +100,28 @@ rnHsType is here because we call it from loadInstDecl, and I didn't
want a gratuitous knot.
\begin{code}
-rnLHsType :: SDoc -> LHsType RdrName -> RnM (LHsType Name)
-rnLHsType doc = wrapLocM (rnHsType doc)
-
-rnHsType :: SDoc -> HsType RdrName -> RnM (HsType Name)
-
-rnHsType doc (HsForAllTy Implicit _ ctxt ty) = do
+rnLHsTyKi :: Bool -- True <=> renaming a type, False <=> a kind
+ -> HsDocContext -> LHsType RdrName -> RnM (LHsType Name)
+rnLHsTyKi isType doc = wrapLocM (rnHsTyKi isType doc)
+
+rnLHsType :: HsDocContext -> LHsType RdrName -> RnM (LHsType Name)
+rnLHsType = rnLHsTyKi True
+rnLHsKind :: HsDocContext -> LHsKind RdrName -> RnM (LHsKind Name)
+rnLHsKind = rnLHsTyKi False
+rnLHsMaybeKind :: HsDocContext -> Maybe (LHsKind RdrName) -> RnM (Maybe (LHsKind Name))
+rnLHsMaybeKind _ Nothing = return Nothing
+rnLHsMaybeKind doc (Just k) = do
+ k' <- rnLHsKind doc k
+ return (Just k')
+
+rnHsType :: HsDocContext -> HsType RdrName -> RnM (HsType Name)
+rnHsType = rnHsTyKi True
+rnHsKind :: HsDocContext -> HsKind RdrName -> RnM (HsKind Name)
+rnHsKind = rnHsTyKi False
+
+rnHsTyKi :: Bool -> HsDocContext -> HsType RdrName -> RnM (HsType Name)
+
+rnHsTyKi isType doc (HsForAllTy Implicit _ ctxt ty) = ASSERT ( isType ) do
-- Implicit quantifiction in source code (no kinds on tyvars)
-- Given the signature C => T we universally quantify
-- over FV(T) \ {in-scope-tyvars}
@@ -118,120 +138,141 @@ rnHsType doc (HsForAllTy Implicit _ ctxt ty) = do
rnForAll doc Implicit tyvar_bndrs ctxt ty
-rnHsType doc ty@(HsForAllTy Explicit forall_tyvars ctxt tau)
- = do { -- Explicit quantification.
+rnHsTyKi isType doc ty@(HsForAllTy Explicit forall_tyvars ctxt tau)
+ = ASSERT ( isType ) do { -- Explicit quantification.
-- Check that the forall'd tyvars are actually
-- mentioned in the type, and produce a warning if not
let mentioned = extractHsRhoRdrTyVars ctxt tau
in_type_doc = ptext (sLit "In the type") <+> quotes (ppr ty)
- ; warnUnusedForAlls (in_type_doc $$ doc) forall_tyvars mentioned
+ ; warnUnusedForAlls (in_type_doc $$ docOfHsDocContext doc) forall_tyvars mentioned
; -- rnForAll does the rest
rnForAll doc Explicit forall_tyvars ctxt tau }
-rnHsType _ (HsTyVar tyvar) = do
- tyvar' <- lookupOccRn tyvar
- return (HsTyVar tyvar')
+rnHsTyKi isType _ (HsTyVar rdr_name) = do
+ -- We use lookupOccRn in kinds because all the names are in
+ -- TcClsName, and we don't want to look in DataName.
+ name <- (if isType then lookupPromotedOccRn else lookupOccRn) rdr_name
+ return (HsTyVar name)
-- If we see (forall a . ty), without foralls on, the forall will give
-- a sensible error message, but we don't want to complain about the dot too
-- Hence the jiggery pokery with ty1
-rnHsType doc ty@(HsOpTy ty1 (L loc op) ty2)
- = setSrcSpan loc $
+rnHsTyKi isType doc ty@(HsOpTy ty1 (wrapper, L loc op) ty2)
+ = ASSERT ( isType ) setSrcSpan loc $
do { ops_ok <- xoptM Opt_TypeOperators
; op' <- if ops_ok
- then lookupOccRn op
+ then lookupPromotedOccRn op
else do { addErr (opTyErr op ty)
; return (mkUnboundName op) } -- Avoid double complaint
; let l_op' = L loc op'
; fix <- lookupTyFixityRn l_op'
; ty1' <- rnLHsType doc ty1
; ty2' <- rnLHsType doc ty2
- ; mkHsOpTyRn (\t1 t2 -> HsOpTy t1 l_op' t2) op' fix ty1' ty2' }
+ ; mkHsOpTyRn (\t1 t2 -> HsOpTy t1 (wrapper, l_op') t2) op' fix ty1' ty2' }
-rnHsType doc (HsParTy ty) = do
- ty' <- rnLHsType doc ty
+rnHsTyKi isType doc (HsParTy ty) = do
+ ty' <- rnLHsTyKi isType doc ty
return (HsParTy ty')
-rnHsType doc (HsBangTy b ty)
- = do { ty' <- rnLHsType doc ty
+rnHsTyKi isType doc (HsBangTy b ty)
+ = ASSERT ( isType ) do { ty' <- rnLHsType doc ty
; return (HsBangTy b ty') }
-rnHsType doc (HsRecTy flds)
- = do { flds' <- rnConDeclFields doc flds
+rnHsTyKi isType doc (HsRecTy flds)
+ = ASSERT ( isType ) do { flds' <- rnConDeclFields doc flds
; return (HsRecTy flds') }
-rnHsType doc (HsFunTy ty1 ty2) = do
- ty1' <- rnLHsType doc ty1
+rnHsTyKi isType doc (HsFunTy ty1 ty2) = do
+ ty1' <- rnLHsTyKi isType doc ty1
-- Might find a for-all as the arg of a function type
- ty2' <- rnLHsType doc ty2
+ ty2' <- rnLHsTyKi isType doc ty2
-- Or as the result. This happens when reading Prelude.hi
-- when we find return :: forall m. Monad m -> forall a. a -> m a
-- Check for fixity rearrangements
- mkHsOpTyRn HsFunTy funTyConName funTyFixity ty1' ty2'
-
-rnHsType doc (HsListTy ty) = do
- ty' <- rnLHsType doc ty
+ if isType
+ then mkHsOpTyRn HsFunTy funTyConName funTyFixity ty1' ty2'
+ else return (HsFunTy ty1' ty2')
+
+rnHsTyKi isType doc listTy@(HsListTy ty) = do
+ poly_kinds <- xoptM Opt_PolyKinds
+ unless (poly_kinds || isType) (addErr (polyKindsErr listTy))
+ ty' <- rnLHsTyKi isType doc ty
return (HsListTy ty')
-rnHsType doc (HsKindSig ty k)
- = do { kind_sigs_ok <- xoptM Opt_KindSignatures
+rnHsTyKi isType doc (HsKindSig ty k)
+ = ASSERT ( isType ) do {
+ ; kind_sigs_ok <- xoptM Opt_KindSignatures
; unless kind_sigs_ok (addErr (kindSigErr ty))
; ty' <- rnLHsType doc ty
- ; return (HsKindSig ty' k) }
+ ; k' <- rnLHsKind doc k
+ ; return (HsKindSig ty' k') }
-rnHsType doc (HsPArrTy ty) = do
+rnHsTyKi isType doc (HsPArrTy ty) = ASSERT ( isType ) do
ty' <- rnLHsType doc ty
return (HsPArrTy ty')
-- Unboxed tuples are allowed to have poly-typed arguments. These
-- sometimes crop up as a result of CPR worker-wrappering dictionaries.
-rnHsType doc (HsTupleTy tup_con tys) = do
- tys' <- mapM (rnLHsType doc) tys
+rnHsTyKi isType doc tupleTy@(HsTupleTy tup_con tys) = do
+ poly_kinds <- xoptM Opt_PolyKinds
+ unless (poly_kinds || isType) (addErr (polyKindsErr tupleTy))
+ tys' <- mapM (rnLHsTyKi isType doc) tys
return (HsTupleTy tup_con tys')
-rnHsType doc (HsAppTy ty1 ty2) = do
- ty1' <- rnLHsType doc ty1
- ty2' <- rnLHsType doc ty2
+rnHsTyKi isType doc (HsAppTy ty1 ty2) = do
+ ty1' <- rnLHsTyKi isType doc ty1
+ ty2' <- rnLHsTyKi isType doc ty2
return (HsAppTy ty1' ty2')
-rnHsType doc (HsIParamTy n ty) = do
+rnHsTyKi isType doc (HsIParamTy n ty) = ASSERT( isType ) do
ty' <- rnLHsType doc ty
n' <- rnIPName n
return (HsIParamTy n' ty')
-rnHsType doc (HsEqTy ty1 ty2) = do
+rnHsTyKi isType doc (HsEqTy ty1 ty2) = ASSERT( isType ) do
ty1' <- rnLHsType doc ty1
ty2' <- rnLHsType doc ty2
return (HsEqTy ty1' ty2')
-rnHsType _ (HsSpliceTy sp _ k)
- = do { (sp', fvs) <- rnSplice sp -- ToDo: deal with fvs
+rnHsTyKi isType _ (HsSpliceTy sp _ k)
+ = ASSERT ( isType ) do { (sp', fvs) <- rnSplice sp -- ToDo: deal with fvs
; return (HsSpliceTy sp' fvs k) }
-rnHsType doc (HsDocTy ty haddock_doc) = do
+rnHsTyKi isType doc (HsDocTy ty haddock_doc) = ASSERT ( isType ) do
ty' <- rnLHsType doc ty
haddock_doc' <- rnLHsDoc haddock_doc
return (HsDocTy ty' haddock_doc')
#ifndef GHCI
-rnHsType _ ty@(HsQuasiQuoteTy _) = pprPanic "Can't do quasiquotation without GHCi" (ppr ty)
+rnHsTyKi _ _ ty@(HsQuasiQuoteTy _) = pprPanic "Can't do quasiquotation without GHCi" (ppr ty)
#else
-rnHsType doc (HsQuasiQuoteTy qq) = do { ty <- runQuasiQuoteType qq
+rnHsTyKi isType doc (HsQuasiQuoteTy qq) = ASSERT ( isType ) do { ty <- runQuasiQuoteType qq
; rnHsType doc (unLoc ty) }
#endif
-rnHsType _ (HsCoreTy ty) = return (HsCoreTy ty)
+rnHsTyKi isType _ (HsCoreTy ty) = ASSERT ( isType ) return (HsCoreTy ty)
+rnHsTyKi _ _ (HsWrapTy {}) = panic "rnHsTyKi"
+
+rnHsTyKi isType doc (HsExplicitListTy k tys) =
+ ASSERT( isType )
+ do tys' <- mapM (rnLHsType doc) tys
+ return (HsExplicitListTy k tys')
+
+rnHsTyKi isType doc (HsExplicitTupleTy kis tys) =
+ ASSERT( isType )
+ do tys' <- mapM (rnLHsType doc) tys
+ return (HsExplicitTupleTy kis tys')
--------------
-rnLHsTypes :: SDoc -> [LHsType RdrName]
+rnLHsTypes :: HsDocContext -> [LHsType RdrName]
-> IOEnv (Env TcGblEnv TcLclEnv) [LHsType Name]
rnLHsTypes doc tys = mapM (rnLHsType doc) tys
\end{code}
\begin{code}
-rnForAll :: SDoc -> HsExplicitFlag -> [LHsTyVarBndr RdrName]
+rnForAll :: HsDocContext -> HsExplicitFlag -> [LHsTyVarBndr RdrName]
-> LHsContext RdrName -> LHsType RdrName -> RnM (HsType Name)
rnForAll doc _ [] (L _ []) (L _ ty) = rnHsType doc ty
@@ -244,17 +285,41 @@ rnForAll doc _ [] (L _ []) (L _ ty) = rnHsType doc ty
-- of kind *.
rnForAll doc exp forall_tyvars ctxt ty
- = bindTyVarsRn forall_tyvars $ \ new_tyvars -> do
+ = bindTyVarsRn doc forall_tyvars $ \ new_tyvars -> do
new_ctxt <- rnContext doc ctxt
new_ty <- rnLHsType doc ty
return (HsForAllTy exp new_tyvars new_ctxt new_ty)
-- Retain the same implicit/explicit flag as before
-- so that we can later print it correctly
-rnConDeclFields :: SDoc -> [ConDeclField RdrName] -> RnM [ConDeclField Name]
+bindTyVarsFV :: HsDocContext -> [LHsTyVarBndr RdrName]
+ -> ([LHsTyVarBndr Name] -> RnM (a, FreeVars))
+ -> RnM (a, FreeVars)
+bindTyVarsFV doc tyvars thing_inside
+ = bindTyVarsRn doc tyvars $ \ tyvars' ->
+ do { (res, fvs) <- thing_inside tyvars'
+ ; return (res, extractHsTyVarBndrNames_s tyvars' fvs) }
+
+bindTyVarsRn :: HsDocContext -> [LHsTyVarBndr RdrName]
+ -> ([LHsTyVarBndr Name] -> RnM a)
+ -> RnM a
+-- Haskell-98 binding of type variables; e.g. within a data type decl
+bindTyVarsRn doc tyvar_names enclosed_scope
+ = bindLocatedLocalsRn located_tyvars $ \ names ->
+ do { kind_sigs_ok <- xoptM Opt_KindSignatures
+ ; unless (null kinded_tyvars || kind_sigs_ok)
+ (mapM_ (addErr . kindSigErr) kinded_tyvars)
+ ; tyvar_names' <- zipWithM replace tyvar_names names
+ ; enclosed_scope tyvar_names' }
+ where
+ replace (L loc n1) n2 = replaceTyVarName n1 n2 (rnLHsKind doc) >>= return . L loc
+ located_tyvars = hsLTyVarLocNames tyvar_names
+ kinded_tyvars = [n | L _ (KindedTyVar n _ _) <- tyvar_names]
+
+rnConDeclFields :: HsDocContext -> [ConDeclField RdrName] -> RnM [ConDeclField Name]
rnConDeclFields doc fields = mapM (rnField doc) fields
-rnField :: SDoc -> ConDeclField RdrName -> RnM (ConDeclField Name)
+rnField :: HsDocContext -> ConDeclField RdrName -> RnM (ConDeclField Name)
rnField doc (ConDeclField name ty haddock_doc)
= do { new_name <- lookupLocatedTopBndrRn name
; new_ty <- rnLHsType doc ty
@@ -269,10 +334,10 @@ rnField doc (ConDeclField name ty haddock_doc)
%*********************************************************
\begin{code}
-rnContext :: SDoc -> LHsContext RdrName -> RnM (LHsContext Name)
+rnContext :: HsDocContext -> LHsContext RdrName -> RnM (LHsContext Name)
rnContext doc = wrapLocM (rnContext' doc)
-rnContext' :: SDoc -> HsContext RdrName -> RnM (HsContext Name)
+rnContext' :: HsDocContext -> HsContext RdrName -> RnM (HsContext Name)
rnContext' doc ctxt = mapM (rnLHsType doc) ctxt
rnIPName :: IPName RdrName -> RnM (IPName Name)
@@ -311,10 +376,10 @@ mkHsOpTyRn :: (LHsType Name -> LHsType Name -> HsType Name)
-> Name -> Fixity -> LHsType Name -> LHsType Name
-> RnM (HsType Name)
-mkHsOpTyRn mk1 pp_op1 fix1 ty1 (L loc2 (HsOpTy ty21 op2 ty22))
+mkHsOpTyRn mk1 pp_op1 fix1 ty1 (L loc2 (HsOpTy ty21 (w2, op2) ty22))
= do { fix2 <- lookupTyFixityRn op2
; mk_hs_op_ty mk1 pp_op1 fix1 ty1
- (\t1 t2 -> HsOpTy t1 op2 t2)
+ (\t1 t2 -> HsOpTy t1 (w2, op2) t2)
(unLoc op2) fix2 ty21 ty22 loc2 }
mkHsOpTyRn mk1 pp_op1 fix1 ty1 (L loc2 (HsFunTy ty21 ty22))
diff --git a/compiler/simplCore/FloatOut.lhs b/compiler/simplCore/FloatOut.lhs
index 1b2555d018..00d6554790 100644
--- a/compiler/simplCore/FloatOut.lhs
+++ b/compiler/simplCore/FloatOut.lhs
@@ -567,9 +567,17 @@ wrapTick t (FB tops defns)
where
wrap_defns = mapBag wrap_one
- wrap_bind (NonRec binder rhs) = NonRec binder (mkTick t rhs)
- wrap_bind (Rec pairs) = Rec (mapSnd (mkTick t) pairs)
+ wrap_bind (NonRec binder rhs) = NonRec binder (maybe_tick rhs)
+ wrap_bind (Rec pairs) = Rec (mapSnd maybe_tick pairs)
wrap_one (FloatLet bind) = FloatLet (wrap_bind bind)
- wrap_one (FloatCase e b c bs) = FloatCase (mkTick t e) b c bs
+ wrap_one (FloatCase e b c bs) = FloatCase (maybe_tick e) b c bs
+
+ maybe_tick e | exprIsHNF e = e
+ | otherwise = mkTick t e
+ -- we don't need to wrap a tick around an HNF when we float it
+ -- outside a tick: that is an invariant of the tick semantics
+ -- Conversely, inlining of HNFs inside an SCC is allowed, and
+ -- indeed the HNF we're floating here might well be inlined back
+ -- again, and we don't want to end up with duplicate ticks.
\end{code}
diff --git a/compiler/simplCore/SetLevels.lhs b/compiler/simplCore/SetLevels.lhs
index 9af757c1af..7e3b44c7d5 100644
--- a/compiler/simplCore/SetLevels.lhs
+++ b/compiler/simplCore/SetLevels.lhs
@@ -78,7 +78,8 @@ import Literal ( litIsTrivial )
import Demand ( StrictSig, increaseStrictSigArity )
import Name ( getOccName, mkSystemVarName )
import OccName ( occNameString )
-import Type ( isUnLiftedType, Type )
+import Type ( isUnLiftedType, Type, sortQuantVars )
+import Kind ( kiVarsOfKinds )
import BasicTypes ( Arity )
import UniqSupply
import Util
@@ -996,22 +997,13 @@ abstractVars :: Level -> LevelEnv -> VarSet -> [Var]
-- whose level is greater than the destination level
-- These are the ones we are going to abstract out
abstractVars dest_lvl (LE { le_lvl_env = lvl_env, le_env = id_env }) fvs
- = map zap $ uniq $ sortLe le
+ = map zap $ uniq $ sortQuantVars -- IA0_NOTE: centralizing sorting on variables
[var | fv <- varSetElems fvs
, var <- absVarsOf id_env fv
, abstract_me var ]
-- NB: it's important to call abstract_me only on the OutIds the
-- come from absVarsOf (not on fv, which is an InId)
where
- -- Sort the variables so the true type variables come first;
- -- the tyvars scope over Ids and coercion vars
- v1 `le` v2 = case (is_tv v1, is_tv v2) of
- (True, False) -> True
- (False, True) -> False
- _ -> v1 <= v2 -- Same family
-
- is_tv v = isTyVar v
-
uniq :: [Var] -> [Var]
-- Remove adjacent duplicates; the sort will have brought them together
uniq (v1:v2:vs) | v1 == v2 = uniq (v2:vs)
@@ -1036,7 +1028,9 @@ absVarsOf :: IdEnv ([Var], LevelledExpr) -> Var -> [Var]
-- variables
--
-- Also, if x::a is an abstracted variable, then so is a; that is,
- -- we must look in x's type
+ -- we must look in x's type. What's more, if a mentions kind variables,
+ -- we must also return those.
+ --
-- And similarly if x is a coercion variable.
absVarsOf id_env v
| isId v = [av2 | av1 <- lookup_avs v
@@ -1047,7 +1041,9 @@ absVarsOf id_env v
Just (abs_vars, _) -> abs_vars
Nothing -> [v]
- add_tyvars v = v : varSetElems (varTypeTyVars v)
+ add_tyvars v = v : (varSetElems tyvars ++ varSetElems kivars)
+ tyvars = varTypeTyVars v
+ kivars = kiVarsOfKinds (map tyVarKind (varSetElems tyvars))
\end{code}
\begin{code}
diff --git a/compiler/simplCore/SimplEnv.lhs b/compiler/simplCore/SimplEnv.lhs
index 022b354061..62f96e7c6e 100644
--- a/compiler/simplCore/SimplEnv.lhs
+++ b/compiler/simplCore/SimplEnv.lhs
@@ -37,7 +37,7 @@ module SimplEnv (
-- Floats
Floats, emptyFloats, isEmptyFloats, addNonRec, addFloats, extendFloats,
wrapFloats, floatBinds, setFloats, zapFloats, addRecFloats,
- doFloatFromRhs, getFloatBinds, getFloats, mapFloatRhss
+ doFloatFromRhs, getFloatBinds, getFloats, mapFloats
) where
#include "HsVersions.h"
@@ -63,7 +63,6 @@ import BasicTypes
import MonadUtils
import Outputable
import FastString
-import Util
import Data.List
\end{code}
@@ -428,12 +427,12 @@ addNonRec env id rhs
env { seFloats = seFloats env `addFlts` unitFloat (NonRec id rhs),
seInScope = extendInScopeSet (seInScope env) id }
-mapFloatRhss :: SimplEnv -> (CoreExpr -> CoreExpr) -> SimplEnv
-mapFloatRhss env@SimplEnv { seFloats = Floats fs ff } fun
+mapFloats :: SimplEnv -> ((Id,CoreExpr) -> (Id,CoreExpr)) -> SimplEnv
+mapFloats env@SimplEnv { seFloats = Floats fs ff } fun
= env { seFloats = Floats (mapOL app fs) ff }
where
- app (NonRec b e) = NonRec b (fun e)
- app (Rec bs) = Rec (mapSnd fun bs)
+ app (NonRec b e) = case fun (b,e) of (b',e') -> NonRec b' e'
+ app (Rec bs) = Rec (map fun bs)
extendFloats :: SimplEnv -> OutBind -> SimplEnv
-- Add these bindings to the floats, and extend the in-scope env too
diff --git a/compiler/simplCore/SimplUtils.lhs b/compiler/simplCore/SimplUtils.lhs
index 2b6d8e9887..c326cbc74d 100644
--- a/compiler/simplCore/SimplUtils.lhs
+++ b/compiler/simplCore/SimplUtils.lhs
@@ -1181,7 +1181,7 @@ findArity dicts_cheap bndr rhs old_arity
init_cheap_app :: CheapAppFun
init_cheap_app fn n_val_args
- | fn == bndr = True
+ | fn == bndr = True -- On the first pass, this binder gets infinite arity
| otherwise = isCheapApp fn n_val_args
mk_cheap_fn :: Bool -> CheapAppFun -> CheapFun
@@ -1383,7 +1383,7 @@ abstractFloats main_tvs body_env body
; return (subst', (NonRec poly_id poly_rhs)) }
where
rhs' = CoreSubst.substExpr (text "abstract_floats2") subst rhs
- tvs_here = varSetElems (main_tv_set `intersectVarSet` exprSomeFreeVars isTyVar rhs')
+ tvs_here = varSetElemsKvsFirst (main_tv_set `intersectVarSet` exprSomeFreeVars isTyVar rhs')
-- Abstract only over the type variables free in the rhs
-- wrt which the new binding is abstracted. But the naive
@@ -1422,7 +1422,7 @@ abstractFloats main_tvs body_env body
-- If you ever want to be more selective, remember this bizarre case too:
-- x::a = x
-- Here, we must abstract 'x' over 'a'.
- tvs_here = main_tvs
+ tvs_here = sortQuantVars main_tvs
mk_poly tvs_here var
= do { uniq <- getUniqueM
@@ -1745,18 +1745,21 @@ mkCase dflags scrut bndr alts = mkCase1 dflags scrut bndr alts
mkCase1 _dflags scrut case_bndr alts -- Identity case
| all identity_alt alts
= do { tick (CaseIdentity case_bndr)
- ; return (re_cast scrut) }
+ ; return (re_cast scrut rhs1) }
where
- identity_alt (con, args, rhs) = check_eq con args (de_cast rhs)
+ identity_alt (con, args, rhs) = check_eq con args rhs
- check_eq DEFAULT _ (Var v) = v == case_bndr
- check_eq (LitAlt lit') _ (Lit lit) = lit == lit'
- check_eq (DataAlt con) args rhs = rhs `cheapEqExpr` mkConApp con (arg_tys ++ varsToCoreExprs args)
- || rhs `cheapEqExpr` Var case_bndr
- check_eq _ _ _ = False
+ check_eq con args (Cast e co) | not (any (`elemVarSet` tyCoVarsOfCo co) args)
+ {- See Note [RHS casts] -} = check_eq con args e
+ check_eq _ _ (Var v) = v == case_bndr
+ check_eq (LitAlt lit') _ (Lit lit) = lit == lit'
+ check_eq (DataAlt con) args rhs = rhs `cheapEqExpr` mkConApp con (arg_tys ++ varsToCoreExprs args)
+ check_eq _ _ _ = False
arg_tys = map Type (tyConAppArgs (idType case_bndr))
+ -- Note [RHS casts]
+ -- ~~~~~~~~~~~~~~~~
-- We've seen this:
-- case e of x { _ -> x `cast` c }
-- And we definitely want to eliminate this case, to give
@@ -1766,12 +1769,11 @@ mkCase1 _dflags scrut case_bndr alts -- Identity case
-- if (all identity_alt alts) holds.
--
-- Don't worry about nested casts, because the simplifier combines them
- de_cast (Cast e _) = e
- de_cast e = e
- re_cast scrut = case head alts of
- (_,_,Cast _ co) -> Cast scrut co
- _ -> scrut
+ ((_,_,rhs1):_) = alts
+
+ re_cast scrut (Cast rhs co) = Cast (re_cast scrut rhs) co
+ re_cast scrut _ = scrut
--------------------------------------------------
-- 3. Merge Identical Alternatives
diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs
index 5d79ff575d..60b6889d5c 100644
--- a/compiler/simplCore/Simplify.lhs
+++ b/compiler/simplCore/Simplify.lhs
@@ -1025,40 +1025,22 @@ simplTick env tickish expr cont
; return (env', mkTick tickish expr')
}
- -- the last case handles scoped/counting ticks, where all we
- -- can do is simplify the inner expression and then rebuild.
- --
- -- NB. float handling here is tricky. We have some floats already
- -- in the env, and there may be floats arising from the inner
- -- expression. We must be careful to wrap any floats arising from
- -- the inner expression with a non-counting tick, but not those from
- -- the env passed in.
- --
-
-- For breakpoints, we cannot do any floating of bindings around the
-- tick, because breakpoints cannot be split into tick/scope pairs.
- | Breakpoint{} <- tickish
- = do { let (inc,outc) = splitCont cont
- ; (env', expr') <- simplExprF (zapFloats env) expr inc
- ; let tickish' = simplTickish env tickish
- ; (env'', expr'') <- rebuild (zapFloats env') (wrapFloats env' expr') (TickIt tickish' outc)
- ; return (env'', wrapFloats env expr'')
- }
+ | not (tickishCanSplit tickish)
+ = no_floating_past_tick
| Just expr' <- want_to_push_tick_inside
-- see Note [case-of-scc-of-case]
= simplExprF env expr' cont
| otherwise
- = do { let (inc,outc) = splitCont cont
- ; (env', expr') <- simplExprF (zapFloats env) expr inc
- ; let tickish' = simplTickish env tickish
- ; let env'' = addFloats env (mapFloatRhss env' (mkTick (mkNoTick tickish')))
- ; rebuild env'' expr' (TickIt tickish' outc)
- }
+ = no_floating_past_tick -- was: wrap_floats, see below
+
where
want_to_push_tick_inside
| not interesting_cont = Nothing
+ | not (tickishCanSplit tickish) = Nothing
| otherwise
= case expr of
Case scrut bndr ty alts
@@ -1066,10 +1048,39 @@ simplTick env tickish expr cont
where t_scope = mkNoTick tickish -- drop the tick on the dup'd ones
alts' = [ (c,bs, mkTick t_scope e) | (c,bs,e) <- alts]
_other -> Nothing
+ where
+ interesting_cont = case cont of
+ Select _ _ _ _ _ -> True
+ _ -> False
+
+ no_floating_past_tick =
+ do { let (inc,outc) = splitCont cont
+ ; (env', expr') <- simplExprF (zapFloats env) expr inc
+ ; let tickish' = simplTickish env tickish
+ ; (env'', expr'') <- rebuild (zapFloats env')
+ (wrapFloats env' expr')
+ (TickIt tickish' outc)
+ ; return (addFloats env env'', expr'')
+ }
- interesting_cont = case cont of
- Select _ _ _ _ _ -> True
- _ -> False
+-- Alternative version that wraps outgoing floats with the tick. This
+-- results in ticks being duplicated, as we don't make any attempt to
+-- eliminate the tick if we re-inline the binding (because the tick
+-- semantics allows unrestricted inlining of HNFs), so I'm not doing
+-- this any more. FloatOut will catch any real opportunities for
+-- floating.
+--
+-- wrap_floats =
+-- do { let (inc,outc) = splitCont cont
+-- ; (env', expr') <- simplExprF (zapFloats env) expr inc
+-- ; let tickish' = simplTickish env tickish
+-- ; let wrap_float (b,rhs) = (zapIdStrictness (setIdArity b 0),
+-- mkTick (mkNoTick tickish') rhs)
+-- -- when wrapping a float with mkTick, we better zap the Id's
+-- -- strictness info and arity, because it might be wrong now.
+-- ; let env'' = addFloats env (mapFloats env' wrap_float)
+-- ; rebuild env'' expr' (TickIt tickish' outc)
+-- }
simplTickish env tickish
@@ -1136,7 +1147,8 @@ rebuild :: SimplEnv -> OutExpr -> SimplCont -> SimplM (SimplEnv, OutExpr)
rebuild env expr cont
= case cont of
Stop {} -> return (env, expr)
- CoerceIt co cont -> rebuild env (mkCast expr co) cont
+ CoerceIt co cont -> rebuild env (mkCast expr co) cont
+ -- NB: mkCast implements the (Coercion co |> g) optimisation
Select _ bndr alts se cont -> rebuildCase (se `setFloats` env) expr bndr alts cont
StrictArg info _ cont -> rebuildCall env (info `addArgTo` expr) cont
StrictBind b bs body se cont -> do { env' <- simplNonRecX (se `setFloats` env) b expr
diff --git a/compiler/typecheck/FamInst.lhs b/compiler/typecheck/FamInst.lhs
index 97ba4e8ab7..0a94b2b5a7 100644
--- a/compiler/typecheck/FamInst.lhs
+++ b/compiler/typecheck/FamInst.lhs
@@ -255,6 +255,7 @@ addLocalFamInst home_fie famInst = do
-- If there are any conflicts, we should probably error
-- But, if we're allowed to overwrite and the conflict is in the home FIE,
-- then overwrite instead of error.
+ traceTc "checkForConflicts" (ppr conflicts $$ ppr famInst $$ ppr inst_envs)
isGHCi <- getIsGHCi
case conflicts of
dup : _ -> case (isGHCi, home_conflicts) of
diff --git a/compiler/typecheck/TcArrows.lhs b/compiler/typecheck/TcArrows.lhs
index 62690a50bd..e6943ea4ca 100644
--- a/compiler/typecheck/TcArrows.lhs
+++ b/compiler/typecheck/TcArrows.lhs
@@ -287,9 +287,14 @@ tc_cmd env cmd@(HsArrForm expr fixity cmd_args) (cmd_stk, res_ty)
-- Check that it has the right shape:
-- ((w,s1) .. sn)
-- where the si do not mention w
- ; checkTc (corner_ty `eqType` mkTyVarTy w_tv &&
- not (w_tv `elemVarSet` tyVarsOfTypes arg_tys))
+ ; _bogus <- unifyType corner_ty (mkTyVarTy w_tv)
+ ; checkTc (not (w_tv `elemVarSet` tyVarsOfTypes arg_tys))
(badFormFun i tup_ty')
+ -- JPM: WARNING: this test is utterly bogus; see #5609
+ -- We are not using the coercion returned by the unify;
+ -- and (even more seriously) the w not in arg_tys test is totally
+ -- bogus if there are suspended equality constraints. This code
+ -- needs to be re-architected.
; tcCmdTop (env { cmd_arr = b }) cmd arg_tys s }
diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs
index ac2fe8c11b..f12bad426d 100644
--- a/compiler/typecheck/TcBinds.lhs
+++ b/compiler/typecheck/TcBinds.lhs
@@ -1273,6 +1273,7 @@ decideGeneralisationPlan dflags type_env bndr_names lbinds sig_fn
ATyVar {} -> False -- In-scope type variables
AGlobal {} -> True -- are not closed!
AThing {} -> pprPanic "is_closed_id" (ppr name)
+ ANothing {} -> pprPanic "is_closed_id" (ppr name)
| otherwise
= WARN( isInternalName name, ppr name ) True
-- The free-var set for a top level binding mentions
diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs
index 26cb3ab0bc..adc0ea730c 100644
--- a/compiler/typecheck/TcCanonical.lhs
+++ b/compiler/typecheck/TcCanonical.lhs
@@ -23,6 +23,7 @@ import FunDeps
import qualified TcMType as TcM
import TcType
import Type
+import Kind
import Coercion
import Class
import TyCon
@@ -748,20 +749,23 @@ canEq d fl eqv (TyConApp tc1 tys1) (TyConApp tc2 tys2)
, tc1 == tc2
, length tys1 == length tys2
= -- Generate equalities for each of the corresponding arguments
- do { argeqvs <- zipWithM (newEqVar fl) tys1 tys2
+ do { let (kis1, tys1') = span isKind tys1
+ (_kis2, tys2') = span isKind tys2
+ ; let kicos = map mkReflCo kis1
+
+ ; argeqvs <- zipWithM (newEqVar fl) tys1 tys2
; case fl of
Wanted {} ->
setEqBind eqv $
- mkTyConAppCo tc1 (map (mkEqVarLCo . evc_the_evvar) argeqvs)
+ mkTyConAppCo tc1 (kicos ++ map (mkEqVarLCo . evc_the_evvar) argeqvs)
Given {} ->
let do_one argeqv n = setEqBind (evc_the_evvar argeqv)
(mkNthCo n (mkEqVarLCo eqv))
- in do { _unused <- zipWithM do_one argeqvs [0..]; return ()}
+ in zipWithM_ do_one argeqvs [(length kicos)..]
Derived {} -> return ()
; canEqEvVarsCreated d fl argeqvs tys1 tys2 }
-
-- See Note [Equality between type applications]
-- Note [Care with type applications] in TcUnify
canEq d fl eqv ty1 ty2
@@ -769,7 +773,8 @@ canEq d fl eqv ty1 ty2
, Nothing <- tcView ty2 -- See Note [Naked given applications]
, Just (s1,t1) <- tcSplitAppTy_maybe ty1
, Just (s2,t2) <- tcSplitAppTy_maybe ty2
- = if isGivenOrSolved fl then
+ = ASSERT( not (isKind t1) && not (isKind t2) )
+ if isGivenOrSolved fl then
do { traceTcS "canEq/(app case)" $
text "Ommitting decomposition of given equality between: "
<+> ppr ty1 <+> text "and" <+> ppr ty2
@@ -1039,18 +1044,26 @@ canEqLeafOriented :: SubGoalDepth -- Depth
canEqLeafOriented d fl eqv s1 s2
| let k1 = typeKind s1
, let k2 = typeKind s2
- , not (k1 `compatKind` k2) -- Establish kind invariants for CFunEqCan and CTyEqCan
- = do { traceTcS "canEqLeafOriented" $ text "kind mismatch!"
- ; canEqFailure d fl eqv }
- | Just (fn,tys1) <- splitTyConApp_maybe s1
- = canEqLeafFunEqLeftRec d fl eqv (fn,tys1) s2
- | Just tv <- getTyVar_maybe s1
- = canEqLeafTyVarLeftRec d fl eqv tv s2
- | otherwise
- = pprPanic "canEqLeafOriented" $
- text "Non-variable or non-family equality LHS" <+> ppr eqv <+>
+ -- Establish kind invariants for CFunEqCan and CTyEqCan
+ = do { are_compat <- compatKindTcS k1 k2
+ ; can_unify <- if not are_compat
+ then unifyKindTcS s1 s2 k1 k2
+ else return False
+ -- If the kinds cannot be unified or are not compatible, don't fail
+ -- right away; instead, emit a frozen error
+ ; if (not are_compat && not can_unify) then
+ canEqFailure fl eqv
+ else can_eq_kinds_ok d fl eqv s1 s2 }
+
+ where can_eq_kinds_ok d fl eqv s1 s2
+ | Just (fn,tys1) <- splitTyConApp_maybe s1
+ = canEqLeafFunEqLeftRec d fl eqv (fn,tys1) s2
+ | Just tv <- getTyVar_maybe s1
+ = canEqLeafTyVarLeftRec d fl eqv tv s2
+ | otherwise
+ = pprPanic "canEqLeafOriented" $
+ text "Non-variable or non-family equality LHS" <+> ppr eqv <+>
dcolon <+> ppr (evVarPred eqv)
-
canEqLeafFunEqLeftRec :: SubGoalDepth
-> CtFlavor
-> EqVar
@@ -1422,7 +1435,7 @@ instFunDepEqn :: WantedLoc -> Equation -> TcS [(Int,(EvVar,WantedLoc))]
instFunDepEqn wl (FDEqn { fd_qtvs = qtvs, fd_eqs = eqs
, fd_pred1 = d1, fd_pred2 = d2 })
= do { let tvs = varSetElems qtvs
- ; tvs' <- mapM instFlexiTcS tvs
+ ; tvs' <- mapM instFlexiTcS tvs -- IA0_TODO: we might need to do kind substitution
; let subst = zipTopTvSubst tvs (mkTyVarTys tvs')
; foldM (do_one subst) [] eqs }
where
diff --git a/compiler/typecheck/TcClassDcl.lhs b/compiler/typecheck/TcClassDcl.lhs
index ab938d368a..68f27148b6 100644
--- a/compiler/typecheck/TcClassDcl.lhs
+++ b/compiler/typecheck/TcClassDcl.lhs
@@ -119,7 +119,7 @@ tcClassSigs clas sigs def_methods
dm_bind_names = [op | L _ (FunBind {fun_id = L _ op}) <- bagToList def_methods]
tc_sig genop_env (op_names, op_hs_ty)
- = do { op_ty <- tcHsKindedType op_hs_ty -- Class tyvars already in scope
+ = do { op_ty <- tcHsType op_hs_ty -- Class tyvars already in scope
; return [ (op_name, f op_name, op_ty) | L _ op_name <- op_names ] }
where
f nm | nm `elemNameEnv` genop_env = GenericDM
@@ -127,7 +127,7 @@ tcClassSigs clas sigs def_methods
| otherwise = NoDM
tc_gen_sig (op_names, gen_hs_ty)
- = do { gen_op_ty <- tcHsKindedType gen_hs_ty
+ = do { gen_op_ty <- tcHsType gen_hs_ty
; return [ (op_name, gen_op_ty) | L _ op_name <- op_names ] }
\end{code}
diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs
index a5c55263a3..db25c134d7 100755
--- a/compiler/typecheck/TcDeriv.lhs
+++ b/compiler/typecheck/TcDeriv.lhs
@@ -34,7 +34,7 @@ import TcMType
import TcSimplify
import RnBinds
-import RnEnv
+import RnEnv
import RnSource ( addTcgDUs )
import HscTypes
@@ -474,13 +474,12 @@ deriveStandalone (L loc (DerivDecl deriv_ty))
= setSrcSpan loc $
addErrCtxt (standaloneCtxt deriv_ty) $
do { traceTc "Standalone deriving decl for" (ppr deriv_ty)
- ; (tvs, theta, cls, inst_tys) <- tcHsInstHead deriv_ty
+ ; (tvs, theta, cls, inst_tys) <- tcHsInstHead TcType.InstDeclCtxt deriv_ty
; traceTc "Standalone deriving;" $ vcat
[ text "tvs:" <+> ppr tvs
, text "theta:" <+> ppr theta
, text "cls:" <+> ppr cls
, text "tys:" <+> ppr inst_tys ]
- ; checkValidInstance deriv_ty tvs theta cls inst_tys
-- C.f. TcInstDcls.tcLocalInstDecl1
; let cls_tys = take (length inst_tys - 1) inst_tys
@@ -494,6 +493,7 @@ deriveStandalone (L loc (DerivDecl deriv_ty))
------------------------------------------------------------------
deriveTyData :: (LHsType Name, LTyClDecl Name) -> TcM EarlyDerivSpec
+-- The deriving clause of a data or newtype declaration
deriveTyData (L loc deriv_pred, L _ decl@(TyData { tcdLName = L _ tycon_name,
tcdTyVars = tv_names,
tcdTyPats = ty_pats }))
@@ -541,7 +541,7 @@ deriveTyData (L loc deriv_pred, L _ decl@(TyData { tcdLName = L _ tycon_name,
; checkTc (not (isFamilyTyCon tc) || n_args_to_drop == 0)
(typeFamilyPapErr tc cls cls_tys inst_ty)
- ; mkEqnHelp DerivOrigin (varSetElems univ_tvs) cls cls_tys inst_ty Nothing } }
+ ; mkEqnHelp DerivOrigin (varSetElemsKvsFirst univ_tvs) cls cls_tys inst_ty Nothing } }
where
-- Tiresomely we must figure out the "lhs", which is awkward for type families
-- E.g. data T a b = .. deriving( Eq )
@@ -553,6 +553,7 @@ deriveTyData (L loc deriv_pred, L _ decl@(TyData { tcdLName = L _ tycon_name,
get_lhs Nothing = do { tc <- tcLookupTyCon tycon_name
; let tvs = tyConTyVars tc
; return (tvs, tc, mkTyVarTys tvs) }
+ -- JPM: to fix
get_lhs (Just pats) = do { let hs_app = nlHsTyConApp tycon_name pats
; (tvs, tc_app) <- tcHsQuantifiedType tv_names hs_app
; let (tc, tc_args) = tcSplitTyConApp tc_app
@@ -1111,7 +1112,7 @@ mkNewTypeEqn orig dflags tvs
; dfun_name <- new_dfun_name cls tycon
; loc <- getSrcSpanM
; let spec = DS { ds_loc = loc, ds_orig = orig
- , ds_name = dfun_name, ds_tvs = varSetElems dfun_tvs
+ , ds_name = dfun_name, ds_tvs = varSetElemsKvsFirst dfun_tvs
, ds_cls = cls, ds_tys = inst_tys
, ds_tc = rep_tycon, ds_tc_args = rep_tc_args
, ds_theta = mtheta `orElse` all_preds
diff --git a/compiler/typecheck/TcEnv.lhs b/compiler/typecheck/TcEnv.lhs
index 48b637bdd8..4fe7ee1b93 100644
--- a/compiler/typecheck/TcEnv.lhs
+++ b/compiler/typecheck/TcEnv.lhs
@@ -14,13 +14,13 @@ module TcEnv(
-- Global environment
tcExtendGlobalEnv, tcExtendGlobalEnvImplicit, setGlobalTypeEnv,
tcExtendGlobalValEnv,
- tcLookupLocatedGlobal, tcLookupGlobal,
+ tcLookupLocatedGlobal, tcLookupGlobal,
tcLookupField, tcLookupTyCon, tcLookupClass, tcLookupDataCon,
tcLookupLocatedGlobalId, tcLookupLocatedTyCon,
tcLookupLocatedClass, tcLookupInstance,
-- Local environment
- tcExtendKindEnv, tcExtendKindEnvTvs,
+ tcExtendKindEnv, tcExtendKindEnvTvs, tcExtendTcTyThingEnv,
tcExtendTyVarEnv, tcExtendTyVarEnv2,
tcExtendGhciEnv, tcExtendLetEnv,
tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2,
@@ -32,13 +32,13 @@ module TcEnv(
tcExtendRecEnv, -- For knot-tying
-- Rules
- tcExtendRules,
+ tcExtendRules,
-- Defaults
tcGetDefaultTys,
-- Global type variables
- tcGetGlobalTyVars,
+ tcGetGlobalTyVars, zapLclTypeEnv,
-- Template Haskell stuff
checkWellStaged, tcMetaTy, thLevel,
@@ -221,36 +221,31 @@ setGlobalTypeEnv tcg_env new_type_env
; return (tcg_env { tcg_type_env = new_type_env }) }
-tcExtendGlobalEnv :: [TyThing] -> TcM r -> TcM r
- -- Given a mixture of Ids, TyCons, Classes, all defined in the
- -- module being compiled, extend the global environment
-tcExtendGlobalEnv things thing_inside
- = do { env <- getGblEnv
- ; let env' = env { tcg_tcs = [ tc | ATyCon tc <- things,
- not (isClassTyCon tc)]
- ++ tcg_tcs env
- , tcg_clss = [ cl | ATyCon tc <- things,
- Just cl <- [tyConClass_maybe tc]]
- ++ tcg_clss env }
- ; setGblEnv env' $
- tcExtendGlobalEnvImplicit things thing_inside
- }
-
tcExtendGlobalEnvImplicit :: [TyThing] -> TcM r -> TcM r
-- Extend the global environment with some TyThings that can be obtained
-- via implicitTyThings from other entities in the environment. Examples
-- are dfuns, famInstTyCons, data cons, etc.
- -- These TyThings are not added to tcg_tcs or tcg_clss.
+ -- These TyThings are not added to tcg_tcs.
tcExtendGlobalEnvImplicit things thing_inside
= do { tcg_env <- getGblEnv
; let ge' = extendTypeEnvList (tcg_type_env tcg_env) things
; tcg_env' <- setGlobalTypeEnv tcg_env ge'
; setGblEnv tcg_env' thing_inside }
+tcExtendGlobalEnv :: [TyThing] -> TcM r -> TcM r
+ -- Given a mixture of Ids, TyCons, Classes, all defined in the
+ -- module being compiled, extend the global environment
+tcExtendGlobalEnv things thing_inside
+ = do { env <- getGblEnv
+ ; let env' = env { tcg_tcs = [tc | ATyCon tc <- things] ++ tcg_tcs env }
+ ; setGblEnv env' $
+ tcExtendGlobalEnvImplicit things thing_inside
+ }
+
tcExtendGlobalValEnv :: [Id] -> TcM a -> TcM a
-- Same deal as tcExtendGlobalEnv, but for Ids
tcExtendGlobalValEnv ids thing_inside
- = tcExtendGlobalEnv [AnId id | id <- ids] thing_inside
+ = tcExtendGlobalEnvImplicit [AnId id | id <- ids] thing_inside
tcExtendRecEnv :: [(Name,TyThing)] -> TcM r -> TcM r
-- Extend the global environments for the type/class knot tying game
@@ -319,6 +314,13 @@ getInLocalScope = do { lcl_env <- getLclTypeEnv
\end{code}
\begin{code}
+tcExtendTcTyThingEnv :: [(Name, TcTyThing)] -> TcM r -> TcM r
+tcExtendTcTyThingEnv things thing_inside
+ = updLclEnv upd thing_inside
+ where
+ upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
+ extend env = extendNameEnvList env things
+
tcExtendKindEnv :: [(Name, TcKind)] -> TcM r -> TcM r
tcExtendKindEnv things thing_inside
= updLclEnv upd thing_inside
@@ -442,6 +444,14 @@ tcExtendGlobalTyVars :: IORef VarSet -> VarSet -> TcM (IORef VarSet)
tcExtendGlobalTyVars gtv_var extra_global_tvs
= do { global_tvs <- readMutVar gtv_var
; newMutVar (global_tvs `unionVarSet` extra_global_tvs) }
+
+zapLclTypeEnv :: TcM a -> TcM a
+zapLclTypeEnv thing_inside
+ = do { tvs_var <- newTcRef emptyVarSet
+ ; let upd env = env { tcl_env = emptyNameEnv
+ , tcl_rdr = emptyLocalRdrEnv
+ , tcl_tyvars = tvs_var }
+ ; updLclEnv upd thing_inside }
\end{code}
@@ -724,11 +734,15 @@ pprBinders bndrs = pprWithCommas ppr bndrs
notFound :: Name -> TcM TyThing
notFound name
- = do { (gbl,lcl) <- getEnvs
+ = do { (_gbl,lcl) <- getEnvs
; failWithTc (vcat[ptext (sLit "GHC internal error:") <+> quotes (ppr name) <+>
ptext (sLit "is not in scope during type checking, but it passed the renamer"),
- ptext (sLit "tcg_type_env of environment:") <+> ppr (tcg_type_env gbl),
ptext (sLit "tcl_env of environment:") <+> ppr (tcl_env lcl)]
+ -- Take case: printing the whole gbl env can
+ -- cause an infnite loop, in the case where we
+ -- are in the middle of a recursive TyCon/Class group;
+ -- so let's just not print it! Getting a loop here is
+ -- very unhelpful, because it hides one compiler bug with another
) }
wrongThingErr :: String -> TcTyThing -> Name -> TcM a
diff --git a/compiler/typecheck/TcExpr.lhs b/compiler/typecheck/TcExpr.lhs
index 63ce0767a0..52177567e3 100644
--- a/compiler/typecheck/TcExpr.lhs
+++ b/compiler/typecheck/TcExpr.lhs
@@ -39,11 +39,13 @@ import TcHsType
import TcPat
import TcMType
import TcType
+import DsMonad hiding (Splice)
import Id
import DataCon
import Name
import TyCon
import Type
+import Kind( splitKiTyVars )
import Coercion
import Var
import VarSet
@@ -52,7 +54,6 @@ import TysWiredIn
import TysPrim( intPrimTy )
import PrimOp( tagToEnumKey )
import PrelNames
-import Module
import DynFlags
import SrcLoc
import Util
@@ -290,8 +291,8 @@ tcExpr (OpApp arg1 op fix arg2) res_ty
-- Make sure that the argument and result types have kind '*'
-- Eg we do not want to allow (D# $ 4.0#) Trac #5570
- ; unifyKind (typeKind arg2_ty) liftedTypeKind
- ; unifyKind (typeKind res_ty) liftedTypeKind
+ ; _ <- unifyKind (typeKind arg2_ty) liftedTypeKind
+ ; _ <- unifyKind (typeKind res_ty) liftedTypeKind
; arg2' <- tcArg op (arg2, arg2_ty, 2)
; co_res <- unifyType op_res_ty res_ty
@@ -646,16 +647,24 @@ tcExpr (RecordUpd record_expr rbinds _ _ _) res_ty
--
; let fixed_tvs = getFixedTyVars con1_tvs relevant_cons
is_fixed_tv tv = tv `elemVarSet` fixed_tvs
- mk_inst_ty tv result_inst_ty
+ mk_inst_ty subst tv result_inst_ty
| is_fixed_tv tv = return result_inst_ty -- Same as result type
- | otherwise = newFlexiTyVarTy (tyVarKind tv) -- Fresh type, of correct kind
+ | otherwise = newFlexiTyVarTy (subst (tyVarKind tv)) -- Fresh type, of correct kind
; (_, result_inst_tys, result_inst_env) <- tcInstTyVars con1_tvs
- ; scrut_inst_tys <- zipWithM mk_inst_ty con1_tvs result_inst_tys
- ; let rec_res_ty = TcType.substTy result_inst_env con1_res_ty
+ ; let (con1_r_kvs, con1_r_tvs) = splitKiTyVars con1_tvs
+ n_kinds = length con1_r_kvs
+ (result_inst_r_kis, result_inst_r_tys) = splitAt n_kinds result_inst_tys
+ ; scrut_inst_r_kis <- zipWithM (mk_inst_ty (TcType.substTy (zipTopTvSubst [] []))) con1_r_kvs result_inst_r_kis
+ -- IA0_NOTE: we have to build the kind substitution
+ ; let kind_subst = TcType.substTy (zipTopTvSubst con1_r_kvs scrut_inst_r_kis)
+ ; scrut_inst_r_tys <- zipWithM (mk_inst_ty kind_subst) con1_r_tvs result_inst_r_tys
+
+ ; let scrut_inst_tys = scrut_inst_r_kis ++ scrut_inst_r_tys
+ rec_res_ty = TcType.substTy result_inst_env con1_res_ty
con1_arg_tys' = map (TcType.substTy result_inst_env) con1_arg_tys
- scrut_subst = zipTopTvSubst con1_tvs scrut_inst_tys
+ scrut_subst = zipTopTvSubst con1_tvs scrut_inst_tys
scrut_ty = TcType.substTy scrut_subst con1_res_ty
; co_res <- unifyType rec_res_ty res_ty
@@ -749,8 +758,9 @@ tcExpr (PArrSeq _ seq@(FromTo expr1 expr2)) res_ty
= do { (coi, elt_ty) <- matchExpectedPArrTy res_ty
; expr1' <- tcPolyExpr expr1 elt_ty
; expr2' <- tcPolyExpr expr2 elt_ty
+ ; enumFromToP <- initDsTc $ dsDPHBuiltin enumFromToPVar
; enum_from_to <- newMethodFromName (PArrSeqOrigin seq)
- (enumFromToPName basePackageId) elt_ty -- !!!FIXME: chak
+ (idName enumFromToP) elt_ty
; return $ mkHsWrapCo coi
(PArrSeq enum_from_to (FromTo expr1' expr2')) }
@@ -759,13 +769,14 @@ tcExpr (PArrSeq _ seq@(FromThenTo expr1 expr2 expr3)) res_ty
; expr1' <- tcPolyExpr expr1 elt_ty
; expr2' <- tcPolyExpr expr2 elt_ty
; expr3' <- tcPolyExpr expr3 elt_ty
+ ; enumFromThenToP <- initDsTc $ dsDPHBuiltin enumFromThenToPVar
; eft <- newMethodFromName (PArrSeqOrigin seq)
- (enumFromThenToPName basePackageId) elt_ty -- !!!FIXME: chak
+ (idName enumFromThenToP) elt_ty -- !!!FIXME: chak
; return $ mkHsWrapCo coi
(PArrSeq eft (FromThenTo expr1' expr2' expr3')) }
tcExpr (PArrSeq _ _) _
- = panic "TcExpr.tcMonoExpr: Infinite parallel array!"
+ = panic "TcExpr.tcExpr: Infinite parallel array!"
-- the parser shouldn't have generated it and the renamer shouldn't have
-- let it through
\end{code}
diff --git a/compiler/typecheck/TcHsSyn.lhs b/compiler/typecheck/TcHsSyn.lhs
index 5d6f8cc20c..1b50a57a78 100644
--- a/compiler/typecheck/TcHsSyn.lhs
+++ b/compiler/typecheck/TcHsSyn.lhs
@@ -26,7 +26,7 @@ module TcHsSyn (
-- re-exported from TcMonad
TcId, TcIdSet,
- zonkTopDecls, zonkTopExpr, zonkTopLExpr,
+ zonkTopDecls, zonkTopExpr, zonkTopLExpr, mkZonkTcTyVar,
zonkId, zonkTopBndrs
) where
@@ -45,6 +45,8 @@ import TcMType
import Coercion
import TysPrim
import TysWiredIn
+import Type
+import Kind
import DataCon
import Name
import NameSet
@@ -189,8 +191,15 @@ It's all pretty boring stuff, because HsSyn is such a large type, and
the environment manipulation is tiresome.
\begin{code}
-data ZonkEnv = ZonkEnv (TcType -> TcM Type) -- How to zonk a type
- (VarEnv Var) -- What variables are in scope
+type UnboundTyVarZonker = TcTyVar-> TcM Type
+ -- How to zonk an unbound type variable
+ -- Note [Zonking the LHS of a RULE]
+
+data ZonkEnv
+ = ZonkEnv
+ UnboundTyVarZonker
+ (TyVarEnv TyVar) --
+ (IdEnv Var) -- What variables are in scope
-- Maps an Id or EvVar to its zonked version; both have the same Name
-- Note that all evidence (coercion variables as well as dictionaries)
-- are kept in the ZonkEnv
@@ -202,21 +211,25 @@ instance Outputable ZonkEnv where
emptyZonkEnv :: ZonkEnv
-emptyZonkEnv = ZonkEnv zonkTypeZapping emptyVarEnv
+emptyZonkEnv = ZonkEnv zonkTypeZapping emptyVarEnv emptyVarEnv
-extendZonkEnv :: ZonkEnv -> [Var] -> ZonkEnv
-extendZonkEnv (ZonkEnv zonk_ty env) ids
- = ZonkEnv zonk_ty (extendVarEnvList env [(id,id) | id <- ids])
+extendIdZonkEnv :: ZonkEnv -> [Var] -> ZonkEnv
+extendIdZonkEnv (ZonkEnv zonk_ty ty_env id_env) ids
+ = ZonkEnv zonk_ty ty_env (extendVarEnvList id_env [(id,id) | id <- ids])
-extendZonkEnv1 :: ZonkEnv -> Var -> ZonkEnv
-extendZonkEnv1 (ZonkEnv zonk_ty env) id
- = ZonkEnv zonk_ty (extendVarEnv env id id)
+extendIdZonkEnv1 :: ZonkEnv -> Var -> ZonkEnv
+extendIdZonkEnv1 (ZonkEnv zonk_ty ty_env id_env) id
+ = ZonkEnv zonk_ty ty_env (extendVarEnv id_env id id)
-setZonkType :: ZonkEnv -> (TcType -> TcM Type) -> ZonkEnv
-setZonkType (ZonkEnv _ env) zonk_ty = ZonkEnv zonk_ty env
+extendTyZonkEnv1 :: ZonkEnv -> TyVar -> ZonkEnv
+extendTyZonkEnv1 (ZonkEnv zonk_ty ty_env id_env) ty
+ = ZonkEnv zonk_ty (extendVarEnv ty_env ty ty) id_env
+
+setZonkType :: ZonkEnv -> UnboundTyVarZonker -> ZonkEnv
+setZonkType (ZonkEnv _ ty_env id_env) zonk_ty = ZonkEnv zonk_ty ty_env id_env
zonkEnvIds :: ZonkEnv -> [Id]
-zonkEnvIds (ZonkEnv _ env) = varEnvElts env
+zonkEnvIds (ZonkEnv _ _ id_env) = varEnvElts id_env
zonkIdOcc :: ZonkEnv -> TcId -> Id
-- Ids defined in this module should be in the envt;
@@ -234,7 +247,7 @@ zonkIdOcc :: ZonkEnv -> TcId -> Id
--
-- Even without template splices, in module Main, the checking of
-- 'main' is done as a separate chunk.
-zonkIdOcc (ZonkEnv _zonk_ty env) id
+zonkIdOcc (ZonkEnv _zonk_ty _ty_env env) id
| isLocalVar id = lookupVarEnv env id `orElse` id
| otherwise = id
@@ -261,17 +274,30 @@ zonkEvBndrX :: ZonkEnv -> EvVar -> TcM (ZonkEnv, EvVar)
-- Works for dictionaries and coercions
zonkEvBndrX env var
= do { var' <- zonkEvBndr env var
- ; return (extendZonkEnv1 env var', var') }
+ ; return (extendIdZonkEnv1 env var', var') }
zonkEvBndr :: ZonkEnv -> EvVar -> TcM EvVar
-- Works for dictionaries and coercions
-- Does not extend the ZonkEnv
zonkEvBndr env var
- = do { ty' <- zonkTcTypeToType env (varType var)
- ; return (setVarType var ty') }
+ = do { ty <- zonkTcTypeToType env (varType var)
+ ; return (setVarType var ty) }
zonkEvVarOcc :: ZonkEnv -> EvVar -> EvVar
zonkEvVarOcc env v = zonkIdOcc env v
+
+zonkTyBndrsX :: ZonkEnv -> [TyVar] -> TcM (ZonkEnv, [TyVar])
+zonkTyBndrsX = mapAccumLM zonkTyBndrX
+
+zonkTyBndrX :: ZonkEnv -> TyVar -> TcM (ZonkEnv, TyVar)
+zonkTyBndrX env tv
+ = do { tv' <- zonkTyBndr env tv
+ ; return (extendTyZonkEnv1 env tv', tv') }
+
+zonkTyBndr :: ZonkEnv -> TyVar -> TcM TyVar
+zonkTyBndr env tv
+ = do { ki <- zonkTcTypeToType env (tyVarKind tv)
+ ; return (setVarType tv ki) }
\end{code}
@@ -335,7 +361,7 @@ zonkLocalBinds env (HsValBinds vb@(ValBindsOut binds sigs))
zonkLocalBinds env (HsIPBinds (IPBinds binds dict_binds))
= mappM (wrapLocM zonk_ip_bind) binds `thenM` \ new_binds ->
let
- env1 = extendZonkEnv env [ipNameName n | L _ (IPBind n _) <- new_binds]
+ env1 = extendIdZonkEnv env [ipNameName n | L _ (IPBind n _) <- new_binds]
in
zonkTcEvBinds env1 dict_binds `thenM` \ (env2, new_dict_binds) ->
returnM (env2, HsIPBinds (IPBinds new_binds new_dict_binds))
@@ -349,7 +375,7 @@ zonkLocalBinds env (HsIPBinds (IPBinds binds dict_binds))
zonkRecMonoBinds :: ZonkEnv -> SigWarn -> LHsBinds TcId -> TcM (ZonkEnv, LHsBinds Id)
zonkRecMonoBinds env sig_warn binds
= fixM (\ ~(_, new_binds) -> do
- { let env1 = extendZonkEnv env (collectHsBindsBinders new_binds)
+ { let env1 = extendIdZonkEnv env (collectHsBindsBinders new_binds)
; binds' <- zonkMonoBinds env1 sig_warn binds
; return (env1, binds') })
@@ -429,15 +455,17 @@ zonk_bind env sig_warn (AbsBinds { abs_tvs = tyvars, abs_ev_vars = evs
, abs_exports = exports
, abs_binds = val_binds })
= ASSERT( all isImmutableTyVar tyvars )
- do { (env1, new_evs) <- zonkEvBndrsX env evs
+ do { (env0, new_tyvars) <- zonkTyBndrsX env tyvars
+ ; (env1, new_evs) <- zonkEvBndrsX env0 evs
; (env2, new_ev_binds) <- zonkTcEvBinds env1 ev_binds
; (new_val_bind, new_exports) <- fixM $ \ ~(new_val_binds, _) ->
- do { let env3 = extendZonkEnv env2 (collectHsBindsBinders new_val_binds)
+ do { let env3 = extendIdZonkEnv env2 (collectHsBindsBinders new_val_binds)
; new_val_binds <- zonkMonoBinds env3 noSigWarn val_binds
; new_exports <- mapM (zonkExport env3) exports
; return (new_val_binds, new_exports) }
; sig_warn True (map abe_poly new_exports)
- ; return (AbsBinds { abs_tvs = tyvars, abs_ev_vars = new_evs, abs_ev_binds = new_ev_binds
+ ; return (AbsBinds { abs_tvs = new_tyvars, abs_ev_vars = new_evs
+ , abs_ev_binds = new_ev_binds
, abs_exports = new_exports, abs_binds = new_val_bind }) }
where
zonkExport env (ABE{ abe_wrap = wrap, abe_poly = poly_id
@@ -699,7 +727,8 @@ zonkCoFn env (WpEvLam ev) = do { (env', ev') <- zonkEvBndrX env ev
zonkCoFn env (WpEvApp arg) = do { arg' <- zonkEvTerm env arg
; return (env, WpEvApp arg') }
zonkCoFn env (WpTyLam tv) = ASSERT( isImmutableTyVar tv )
- return (env, WpTyLam tv)
+ do { (env', tv') <- zonkTyBndrX env tv
+ ; return (env', WpTyLam tv') }
zonkCoFn env (WpTyApp ty) = do { ty' <- zonkTcTypeToType env ty
; return (env, WpTyApp ty') }
zonkCoFn env (WpLet bs) = do { (env1, bs') <- zonkTcEvBinds env bs
@@ -748,7 +777,7 @@ zonkStmt env (ParStmt stmts_w_bndrs mzip_op bind_op return_op)
= mappM zonk_branch stmts_w_bndrs `thenM` \ new_stmts_w_bndrs ->
let
new_binders = concat (map snd new_stmts_w_bndrs)
- env1 = extendZonkEnv env new_binders
+ env1 = extendIdZonkEnv env new_binders
in
zonkExpr env1 mzip_op `thenM` \ new_mzip ->
zonkExpr env1 bind_op `thenM` \ new_bind ->
@@ -767,12 +796,12 @@ zonkStmt env (RecStmt { recS_stmts = segStmts, recS_later_ids = lvs, recS_rec_id
; new_ret_id <- zonkExpr env ret_id
; new_mfix_id <- zonkExpr env mfix_id
; new_bind_id <- zonkExpr env bind_id
- ; let env1 = extendZonkEnv env new_rvs
+ ; let env1 = extendIdZonkEnv env new_rvs
; (env2, new_segStmts) <- zonkStmts env1 segStmts
-- Zonk the ret-expressions in an envt that
-- has the polymorphic bindings in the envt
; new_rets <- mapM (zonkExpr env2) rets
- ; return (extendZonkEnv env new_lvs, -- Only the lvs are needed
+ ; return (extendIdZonkEnv env new_lvs, -- Only the lvs are needed
RecStmt { recS_stmts = new_segStmts, recS_later_ids = new_lvs
, recS_rec_ids = new_rvs, recS_ret_fn = new_ret_id
, recS_mfix_fn = new_mfix_id, recS_bind_fn = new_bind_id
@@ -800,7 +829,7 @@ zonkStmt env (TransStmt { trS_stmts = stmts, trS_bndrs = binderMap
; return_op' <- zonkExpr env' return_op
; bind_op' <- zonkExpr env' bind_op
; liftM_op' <- zonkExpr env' liftM_op
- ; let env'' = extendZonkEnv env' (map snd binderMap')
+ ; let env'' = extendIdZonkEnv env' (map snd binderMap')
; return (env'', TransStmt { trS_stmts = stmts', trS_bndrs = binderMap'
, trS_by = by', trS_form = form, trS_using = using'
, trS_ret = return_op', trS_bind = bind_op', trS_fmap = liftM_op' }) }
@@ -862,7 +891,7 @@ zonk_pat env (WildPat ty)
zonk_pat env (VarPat v)
= do { v' <- zonkIdBndr env v
- ; return (extendZonkEnv1 env v', VarPat v') }
+ ; return (extendIdZonkEnv1 env v', VarPat v') }
zonk_pat env (LazyPat pat)
= do { (env', pat') <- zonkPat env pat
@@ -874,7 +903,7 @@ zonk_pat env (BangPat pat)
zonk_pat env (AsPat (L loc v) pat)
= do { v' <- zonkIdBndr env v
- ; (env', pat') <- zonkPat (extendZonkEnv1 env v') pat
+ ; (env', pat') <- zonkPat (extendIdZonkEnv1 env v') pat
; return (env', AsPat (L loc v') pat') }
zonk_pat env (ViewPat expr pat ty)
@@ -925,7 +954,7 @@ zonk_pat env (NPlusKPat (L loc n) lit e1 e2)
; lit' <- zonkOverLit env lit
; e1' <- zonkExpr env e1
; e2' <- zonkExpr env e2
- ; return (extendZonkEnv1 env n', NPlusKPat (L loc n') lit' e1' e2') }
+ ; return (extendIdZonkEnv1 env n', NPlusKPat (L loc n') lit' e1' e2') }
zonk_pat env (CoPat co_fn pat ty)
= do { (env', co_fn') <- zonkCoFn env co_fn
@@ -987,35 +1016,21 @@ zonkRules env rs = mappM (wrapLocM (zonkRule env)) rs
zonkRule :: ZonkEnv -> RuleDecl TcId -> TcM (RuleDecl Id)
zonkRule env (HsRule name act (vars{-::[RuleBndr TcId]-}) lhs fv_lhs rhs fv_rhs)
- = do { (env_rhs, new_bndrs) <- mapAccumLM zonk_bndr env vars
-
- ; unbound_tv_set <- newMutVar emptyVarSet
- ; let env_lhs = setZonkType env_rhs (zonkTypeCollecting unbound_tv_set)
- -- We need to gather the type variables mentioned on the LHS so we can
- -- quantify over them. Example:
- -- data T a = C
- --
- -- foo :: T a -> Int
- -- foo C = 1
- --
- -- {-# RULES "myrule" foo C = 1 #-}
- --
- -- After type checking the LHS becomes (foo a (C a))
- -- and we do not want to zap the unbound tyvar 'a' to (), because
- -- that limits the applicability of the rule. Instead, we
- -- want to quantify over it!
- --
- -- It's easiest to find the free tyvars here. Attempts to do so earlier
- -- are tiresome, because (a) the data type is big and (b) finding the
- -- free type vars of an expression is necessarily monadic operation.
- -- (consider /\a -> f @ b, where b is side-effected to a)
-
- ; new_lhs <- zonkLExpr env_lhs lhs
- ; new_rhs <- zonkLExpr env_rhs rhs
-
- ; unbound_tvs <- readMutVar unbound_tv_set
+ = do { unbound_tkv_set <- newMutVar emptyVarSet
+ ; let env_rule = setZonkType env (zonkTvCollecting unbound_tkv_set)
+ -- See Note [Zonking the LHS of a RULE]
+
+ ; (env_inside, new_bndrs) <- mapAccumLM zonk_bndr env_rule vars
+
+ ; new_lhs <- zonkLExpr env_inside lhs
+ ; new_rhs <- zonkLExpr env_inside rhs
+
+ ; unbound_tkvs <- readMutVar unbound_tkv_set
+
; let final_bndrs :: [RuleBndr Var]
- final_bndrs = map (RuleBndr . noLoc) (varSetElems unbound_tvs) ++ new_bndrs
+ final_bndrs = map (RuleBndr . noLoc)
+ (varSetElemsKvsFirst unbound_tkvs)
+ ++ new_bndrs
; return (HsRule name act final_bndrs new_lhs fv_lhs new_rhs fv_rhs) }
where
@@ -1024,7 +1039,7 @@ zonkRule env (HsRule name act (vars{-::[RuleBndr TcId]-}) lhs fv_lhs rhs fv_rhs)
zonk_bndr _ (RuleBndrSig {}) = panic "zonk_bndr RuleBndrSig"
zonk_it env v
- | isId v = do { v' <- zonkIdBndr env v; return (extendZonkEnv1 env v', v') }
+ | isId v = do { v' <- zonkIdBndr env v; return (extendIdZonkEnv1 env v', v') }
| otherwise = ASSERT( isImmutableTyVar v) return (env, v)
\end{code}
@@ -1089,7 +1104,7 @@ zonkEvBindsVar env (EvBindsVar ref _) = do { bs <- readMutVar ref
zonkEvBinds :: ZonkEnv -> Bag EvBind -> TcM (ZonkEnv, Bag EvBind)
zonkEvBinds env binds
= fixM (\ ~( _, new_binds) -> do
- { let env1 = extendZonkEnv env (collect_ev_bndrs new_binds)
+ { let env1 = extendIdZonkEnv env (collect_ev_bndrs new_binds)
; binds' <- mapBagM (zonkEvBind env1) binds
; return (env1, binds') })
where
@@ -1110,39 +1125,108 @@ zonkEvBind env (EvBind var term)
%* *
%************************************************************************
+Note [Zonking the LHS of a RULE]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We need to gather the type variables mentioned on the LHS so we can
+quantify over them. Example:
+ data T a = C
+
+ foo :: T a -> Int
+ foo C = 1
+
+ {-# RULES "myrule" foo C = 1 #-}
+
+After type checking the LHS becomes (foo a (C a))
+and we do not want to zap the unbound tyvar 'a' to (), because
+that limits the applicability of the rule. Instead, we
+want to quantify over it!
+
+It's easiest to get zonkTvCollecting to gather the free tyvars
+here. Attempts to do so earlier are tiresome, because (a) the data
+type is big and (b) finding the free type vars of an expression is
+necessarily monadic operation. (consider /\a -> f @ b, where b is
+side-effected to a)
+
+And that in turn is why ZonkEnv carries the function to use for
+type variables!
+
+Note [Zonking mutable unbound type or kind variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In zonkTypeZapping, we zonk mutable but unbound type or kind variables to an
+arbitrary type. We know if they are unbound even though we don't carry an
+environment, because at the binding site for a variable we bind the mutable
+var to a fresh immutable one. So the mutable store plays the role of an
+environment. If we come across a mutable variable that isn't so bound, it
+must be completely free. We zonk the expected kind to make sure we don't get
+some unbound meta variable as the kind.
+
+Note that since we have kind polymorphism, zonk_unbound_tyvar will handle both
+type and kind variables. Consider the following datatype:
+
+ data Phantom a = Phantom Int
+
+The type of Phantom is (forall (k : BOX). forall (a : k). Int). Both `a` and
+`k` are unbound variables. We want to zonk this to
+(forall (k : AnyK). forall (a : Any AnyK). Int). For that we have to check if
+we have a type or a kind variable; for kind variables we just return AnyK (and
+not the ill-kinded Any BOX).
+
\begin{code}
+mkZonkTcTyVar :: (TcTyVar -> TcM Type) -- What to do for an *mutable Flexi* var
+ -> (TcTyVar -> Type) -- What to do for an immutable var
+ -> TcTyVar -> TcM TcType
+mkZonkTcTyVar unbound_mvar_fn unbound_ivar_fn
+ = zonk_tv
+ where
+ zonk_tv tv
+ = ASSERT( isTcTyVar tv )
+ case tcTyVarDetails tv of
+ SkolemTv {} -> return (unbound_ivar_fn tv)
+ RuntimeUnk {} -> return (unbound_ivar_fn tv)
+ FlatSkol ty -> zonkType zonk_tv ty
+ MetaTv _ ref -> do { cts <- readMutVar ref
+ ; case cts of
+ Flexi -> do { kind <- zonkType zonk_tv (tyVarKind tv)
+ ; unbound_mvar_fn (setTyVarKind tv kind) }
+ Indirect ty -> zonkType zonk_tv ty }
+
zonkTcTypeToType :: ZonkEnv -> TcType -> TcM Type
-zonkTcTypeToType (ZonkEnv zonk_ty _) ty = zonk_ty ty
+zonkTcTypeToType (ZonkEnv zonk_unbound_tyvar tv_env _id_env)
+ = zonkType (mkZonkTcTyVar zonk_unbound_tyvar zonk_bound_tyvar)
+ where
+ zonk_bound_tyvar tv = case lookupVarEnv tv_env tv of
+ Nothing -> mkTyVarTy tv
+ Just tv' -> mkTyVarTy tv'
zonkTcTypeToTypes :: ZonkEnv -> [TcType] -> TcM [Type]
zonkTcTypeToTypes env tys = mapM (zonkTcTypeToType env) tys
-zonkTypeCollecting :: TcRef TyVarSet -> TcType -> TcM Type
+zonkTvCollecting :: TcRef TyVarSet -> UnboundTyVarZonker
-- This variant collects unbound type variables in a mutable variable
-zonkTypeCollecting unbound_tv_set
- = zonkType (mkZonkTcTyVar zonk_unbound_tyvar)
- where
- zonk_unbound_tyvar tv
- = do { tv' <- zonkQuantifiedTyVar tv
- ; tv_set <- readMutVar unbound_tv_set
- ; writeMutVar unbound_tv_set (extendVarSet tv_set tv')
- ; return (mkTyVarTy tv') }
-
-zonkTypeZapping :: TcType -> TcM Type
+-- Works on both types and kinds
+zonkTvCollecting unbound_tv_set tv
+ = do { poly_kinds <- xoptM Opt_PolyKinds
+ ; if isKiVar tv && not poly_kinds then
+ do { defaultKindVarToStar tv
+ ; return liftedTypeKind }
+ else do
+ { tv' <- zonkQuantifiedTyVar tv
+ ; tv_set <- readMutVar unbound_tv_set
+ ; writeMutVar unbound_tv_set (extendVarSet tv_set tv')
+ ; return (mkTyVarTy tv') } }
+
+zonkTypeZapping :: UnboundTyVarZonker
-- This variant is used for everything except the LHS of rules
-- It zaps unbound type variables to (), or some other arbitrary type
-zonkTypeZapping ty
- = zonkType (mkZonkTcTyVar zonk_unbound_tyvar) ty
- where
- -- Zonk a mutable but unbound type variable to an arbitrary type
- -- We know it's unbound even though we don't carry an environment,
- -- because at the binding site for a type variable we bind the
- -- mutable tyvar to a fresh immutable one. So the mutable store
- -- plays the role of an environment. If we come across a mutable
- -- type variable that isn't so bound, it must be completely free.
- zonk_unbound_tyvar tv = do { let ty = anyTypeOfKind (tyVarKind tv)
- ; writeMetaTyVar tv ty
- ; return ty }
+-- Works on both types and kinds
+zonkTypeZapping tv
+ = do { let ty = if isKiVar tv
+ -- ty is actually a kind, zonk to AnyK
+ then anyKind
+ else anyTypeOfKind (tyVarKind tv)
+ ; writeMetaTyVar tv ty
+ ; return ty }
+
zonkTcLCoToLCo :: ZonkEnv -> LCoercion -> TcM LCoercion
-- NB: zonking often reveals that the coercion is an identity
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs
index b0ef207799..8f1fb54df3 100644
--- a/compiler/typecheck/TcHsType.lhs
+++ b/compiler/typecheck/TcHsType.lhs
@@ -20,11 +20,16 @@ module TcHsType (
-- Kind checking
kcHsTyVars, kcHsSigType, kcHsLiftedSigType,
kcLHsType, kcCheckLHsType, kcHsContext, kcApps,
-
- -- Typechecking kinded types
- tcHsKindedContext, tcHsKindedType, tcHsBangType,
- tcTyVarBndrs, dsHsType,
- tcDataKindSig,
+ kindGeneralizeKind, kindGeneralizeKinds,
+
+ -- Sort checking
+ scDsLHsKind, scDsLHsMaybeKind,
+
+ -- Typechecking kinded types
+ tcHsType, tcCheckHsType,
+ tcHsKindedContext, tcHsKindedType, tcHsBangType,
+ tcTyVarBndrs, tcTyVarBndrsKindGen, dsHsType,
+ tcDataKindSig, tcTyClTyVars,
ExpKind(..), EkCtxt(..), ekConstraint,
checkExpectedKind,
@@ -42,27 +47,34 @@ import {-# SOURCE #-} TcSplice( kcSpliceType )
import HsSyn
import RnHsSyn
import TcRnMonad
+import RnEnv ( polyKindsErr )
+import TcHsSyn ( mkZonkTcTyVar )
import TcEnv
import TcMType
import TcUnify
import TcIface
import TcType
import {- Kind parts of -} Type
-import Kind ( isConstraintKind )
+import Kind
import Var
import VarSet
import TyCon
+import DataCon ( DataCon, dataConUserType )
+import TysPrim ( liftedTypeKindTyConName, constraintKindTyConName )
import Class
+import RdrName ( rdrNameSpace, nameRdrName )
import Name
import NameSet
import TysWiredIn
import BasicTypes
import SrcLoc
-import DynFlags ( ExtensionFlag( Opt_ConstraintKinds ) )
+import DynFlags ( ExtensionFlag( Opt_ConstraintKinds, Opt_PolyKinds ) )
import Util
import UniqSupply
import Outputable
+import BuildTyCl ( buildPromotedDataTyCon )
import FastString
+import Control.Monad ( unless )
\end{code}
@@ -163,34 +175,37 @@ tcHsSigTypeNC ctxt hs_ty
-- The kind is checked by checkValidType, and isn't necessarily
-- of kind * in a Template Haskell quote eg [t| Maybe |]
; ty <- tcHsKindedType kinded_ty
- ; checkValidType ctxt ty
+ ; checkValidType ctxt ty
; return ty }
-tcHsInstHead :: LHsType Name -> TcM ([TyVar], ThetaType, Class, [Type])
+-- Like tcHsType, but takes an expected kind
+tcCheckHsType :: LHsType Name -> Kind -> TcM Type
+tcCheckHsType hs_ty exp_kind
+ = do { kinded_ty <- kcCheckLHsType hs_ty (EK exp_kind EkUnk) -- JPM add context
+ ; ty <- tcHsKindedType kinded_ty
+ ; return ty }
+
+tcHsType :: LHsType Name -> TcM Type
+-- kind check and desugar
+-- no validity checking because of knot-tying
+tcHsType hs_ty
+ = do { (kinded_ty, _) <- kc_lhs_type hs_ty
+ ; ty <- tcHsKindedType kinded_ty
+ ; return ty }
+
+tcHsInstHead :: UserTypeCtxt -> LHsType Name -> TcM ([TyVar], ThetaType, Class, [Type])
-- Typecheck an instance head. We can't use
-- tcHsSigType, because it's not a valid user type.
-tcHsInstHead (L loc hs_ty)
+tcHsInstHead ctxt lhs_ty@(L loc hs_ty)
= setSrcSpan loc $ -- No need for an "In the type..." context
-- because that comes from the caller
- kc_ds_inst_head hs_ty
- where
- kc_ds_inst_head ty = case splitHsClassTy_maybe cls_ty of
- Just _ -> do -- Kind-checking first
- (tvs, ctxt, cls_ty) <- kcHsTyVars tv_names $ \ tv_names' -> do
- ctxt' <- mapM kcHsLPredType ctxt
- cls_ty' <- kc_check_hs_type cls_ty ekConstraint
- -- The body of a forall is usually lifted, but in an instance
- -- head we only allow something of kind Constraint.
- return (tv_names', ctxt', cls_ty')
- -- Now desugar the kind-checked type
- let Just (cls_name, tys) = splitHsClassTy_maybe cls_ty
- tcTyVarBndrs tvs $ \ tvs' -> do
- ctxt' <- dsHsTypes ctxt
- clas <- tcLookupClass cls_name
- tys' <- dsHsTypes tys
- return (tvs', ctxt', clas, tys')
- _ -> failWithTc (ptext (sLit "Malformed instance type"))
- where (tv_names, ctxt, cls_ty) = splitHsForAllTy ty
+ do { kinded_ty <- kc_check_hs_type hs_ty ekConstraint
+ ; ty <- ds_type kinded_ty
+ ; let (tvs, theta, tau) = tcSplitSigmaTy ty
+ ; case getClassPredTys_maybe tau of
+ Nothing -> failWithTc (ptext (sLit "Malformed instance type"))
+ Just (clas,tys) -> do { checkValidInstance ctxt lhs_ty tvs theta clas tys
+ ; return (tvs, theta, clas, tys) } }
tcHsQuantifiedType :: [LHsTyVarBndr Name] -> LHsType Name -> TcM ([TyVar], Type)
-- Behave very like type-checking (HsForAllTy sig_tvs hs_ty),
@@ -219,7 +234,7 @@ tc_hs_deriv tv_names ty
= kcHsTyVars tv_names $ \ tv_names' ->
do { cls_kind <- kcClass cls_name
; (tys, _res_kind) <- kcApps cls_name cls_kind hs_tys
- ; tcTyVarBndrs tv_names' $ \ tyvars ->
+ ; tcTyVarBndrsKindGen tv_names' $ \ tyvars ->
do { arg_tys <- dsHsTypes tys
; cls <- tcLookupClass cls_name
; return (tyvars, cls, arg_tys) }}
@@ -249,7 +264,7 @@ tcHsVectInst ty
\begin{code}
kcHsSigType, kcHsLiftedSigType :: LHsType Name -> TcM (LHsType Name)
-- Used for type signatures
-kcHsSigType ty = addKcTypeCtxt ty $ kcTypeType ty
+kcHsSigType ty = addKcTypeCtxt ty $ kcArgType ty
kcHsLiftedSigType ty = addKcTypeCtxt ty $ kcLiftedType ty
tcHsKindedType :: LHsType Name -> TcM Type
@@ -261,6 +276,7 @@ tcHsKindedType hs_ty = dsHsType hs_ty
tcHsBangType :: LHsType Name -> TcM Type
-- Permit a bang, but discard it
+-- Input type has already been kind-checked
tcHsBangType (L _ (HsBangTy _ ty)) = tcHsKindedType ty
tcHsBangType ty = tcHsKindedType ty
@@ -287,7 +303,7 @@ kcLiftedType ty = kc_check_lhs_type ty ekLifted
---------------------------
kcTypeType :: LHsType Name -> TcM (LHsType Name)
--- The type ty must be a *type*, but it can be lifted or
+-- The type ty must be a *type*, but it can be lifted or
-- unlifted or an unboxed tuple.
kcTypeType ty = kc_check_lhs_type ty ekOpen
@@ -297,6 +313,11 @@ kcArgs what tys kind
| (ty,n) <- tys `zip` [1..] ]
---------------------------
+kcArgType :: LHsType Name -> TcM (LHsType Name)
+-- The type ty must be an *arg* *type* (lifted or unlifted)
+kcArgType ty = kc_check_lhs_type ty ekArg
+
+---------------------------
kcCheckLHsType :: LHsType Name -> ExpKind -> TcM (LHsType Name)
kcCheckLHsType ty kind = addKcTypeCtxt ty $ kc_check_lhs_type ty kind
@@ -333,7 +354,8 @@ kc_check_hs_type ty@(HsAppTy ty1 ty2) exp_kind
-- This is the general case: infer the kind and compare
kc_check_hs_type ty exp_kind
- = do { (ty', act_kind) <- kc_hs_type ty
+ = do { traceTc "kc_check_hs_type" (ppr ty)
+ ; (ty', act_kind) <- kc_hs_type ty
-- Add the context round the inner check only
-- because checkExpectedKind already mentions
-- 'ty' by name in any error message
@@ -361,7 +383,8 @@ kcLHsType ty = addKcTypeCtxt ty (kc_lhs_type ty)
kc_lhs_type :: LHsType Name -> TcM (LHsType Name, TcKind)
kc_lhs_type (L span ty)
= setSrcSpan span $
- do { (ty', kind) <- kc_hs_type ty
+ do { traceTc "kc_lhs_type" (ppr ty)
+ ; (ty', kind) <- kc_hs_type ty
; return (L span ty', kind) }
-- kc_hs_type *returns* the kind of the type, rather than taking an expected
@@ -383,9 +406,7 @@ kc_hs_type (HsTyVar name)
-- Special case for the unit tycon so it benefits from kind overloading
| name == tyConName unitTyCon
= kc_hs_type (HsTupleTy (HsBoxyTuple placeHolderKind) [])
- | otherwise = do
- kind <- kcTyVar name
- return (HsTyVar name, kind)
+ | otherwise = kcTyVar name
kc_hs_type (HsListTy ty) = do
ty' <- kcLiftedType ty
@@ -396,13 +417,14 @@ kc_hs_type (HsPArrTy ty) = do
return (HsPArrTy ty', liftedTypeKind)
kc_hs_type (HsKindSig ty k) = do
- ty' <- kc_check_lhs_type ty (EK k EkKindSig)
- return (HsKindSig ty' k, k)
+ k' <- scDsLHsKind k
+ ty' <- kc_check_lhs_type ty (EK k' EkKindSig)
+ return (HsKindSig ty' k, k')
kc_hs_type (HsTupleTy (HsBoxyTuple _) tys)
= do { fact_tup_ok <- xoptM Opt_ConstraintKinds
; k <- if fact_tup_ok
- then newKindVar
+ then newMetaKindVar
else return liftedTypeKind
; tys' <- kcArgs (ptext (sLit "a tuple")) tys k
; return (HsTupleTy (HsBoxyTuple k) tys', k) }
@@ -421,10 +443,14 @@ kc_hs_type (HsFunTy ty1 ty2) = do
ty2' <- kcTypeType ty2
return (HsFunTy ty1' ty2', liftedTypeKind)
-kc_hs_type (HsOpTy ty1 op ty2) = do
- op_kind <- addLocM kcTyVar op
- ([ty1',ty2'], res_kind) <- kcApps op op_kind [ty1,ty2]
- return (HsOpTy ty1' op ty2', res_kind)
+kc_hs_type (HsOpTy ty1 (_, l_op@(L loc op)) ty2) = do
+ (wop, op_kind) <- kcTyVar op
+ ([ty1',ty2'], res_kind) <- kcApps l_op op_kind [ty1,ty2]
+ let op' = case wop of
+ HsTyVar name -> (WpKiApps [], L loc name)
+ HsWrapTy wrap (HsTyVar name) -> (wrap, L loc name)
+ _ -> panic "kc_hs_type HsOpTy"
+ return (HsOpTy ty1' op' ty2', res_kind)
kc_hs_type (HsAppTy ty1 ty2) = do
let (fun_ty, arg_tys) = splitHsAppTys ty1 [ty2]
@@ -448,17 +474,22 @@ kc_hs_type (HsCoreTy ty)
kc_hs_type (HsForAllTy exp tv_names context ty)
= kcHsTyVars tv_names $ \ tv_names' ->
do { ctxt' <- kcHsContext context
- ; ty' <- kcLiftedType ty
+ ; (ty', k) <- kc_lhs_type ty
-- The body of a forall is usually a type, but in principle
-- there's no reason to prohibit *unlifted* types.
-- In fact, GHC can itself construct a function with an
-- unboxed tuple inside a for-all (via CPR analyis; see
- -- typecheck/should_compile/tc170)
+ -- typecheck/should_compile/tc170).
+ --
+ -- Moreover in instance heads we get forall-types with
+ -- kind Constraint.
--
- -- Still, that's only for internal interfaces, which aren't
- -- kind-checked, so we only allow liftedTypeKind here
+ -- Really we should check that it's a type of value kind
+ -- {*, Constraint, #}, but I'm not doing that yet
+ -- Example that should be rejected:
+ -- f :: (forall (a:*->*). a) Int
- ; return (HsForAllTy exp tv_names' ctxt' ty', liftedTypeKind) }
+ ; return (HsForAllTy exp tv_names' ctxt' ty', k) }
kc_hs_type (HsBangTy b ty)
= do { (ty', kind) <- kc_lhs_type ty
@@ -482,6 +513,17 @@ kc_hs_type (HsQuasiQuoteTy {}) = panic "kc_hs_type" -- Eliminated by renamer
kc_hs_type (HsDocTy ty _)
= kc_hs_type (unLoc ty)
+kc_hs_type (HsExplicitListTy _ tys)
+ = do { ty_k_s <- mapM kc_lhs_type tys
+ ; kind <- unifyKinds (ptext (sLit "In a promoted list")) ty_k_s
+ ; return (HsExplicitListTy kind (map fst ty_k_s), mkListTy kind) }
+kc_hs_type (HsExplicitTupleTy _ tys) = do
+ ty_k_s <- mapM kc_lhs_type tys
+ return ( HsExplicitTupleTy (map snd ty_k_s) (map fst ty_k_s)
+ , mkTyConApp (tupleTyCon BoxedTuple (length tys)) (map snd ty_k_s))
+
+kc_hs_type (HsWrapTy {}) = panic "kc_hs_type HsWrapTy" -- it means we kind checked something twice
+
---------------------------
kcApps :: Outputable a
=> a
@@ -526,16 +568,42 @@ kcHsLPredType :: LHsType Name -> TcM (LHsType Name)
kcHsLPredType pred = kc_check_lhs_type pred ekConstraint
---------------------------
-kcTyVar :: Name -> TcM TcKind
-kcTyVar name = do -- Could be a tyvar or a tycon
- traceTc "lk1" (ppr name)
- thing <- tcLookup name
- traceTc "lk2" (ppr name <+> ppr thing)
- case thing of
- ATyVar _ ty -> return (typeKind ty)
- AThing kind -> return kind
- AGlobal (ATyCon tc) -> return (tyConKind tc)
- _ -> wrongThingErr "type" thing name
+kcTyVar :: Name -> TcM (HsType Name, TcKind)
+-- See Note [Type checking recursive type and class declarations]
+-- in TcTyClsDecls
+kcTyVar name -- Could be a tyvar, a tycon, or a datacon
+ = do { traceTc "lk1" (ppr name)
+ ; thing <- tcLookup name
+ ; traceTc "lk2" (ppr name <+> ppr thing)
+ ; case thing of
+ ATyVar _ ty -> wrap_mono (typeKind ty)
+ AThing kind -> wrap_poly kind
+ AGlobal (ATyCon tc) -> wrap_poly (tyConKind tc)
+ AGlobal (ADataCon dc) -> kcDataCon dc >>= wrap_poly
+ _ -> wrongThingErr "type" thing name }
+ where
+ wrap_mono kind = do { traceTc "lk3" (ppr name <+> dcolon <+> ppr kind)
+ ; return (HsTyVar name, kind) }
+ wrap_poly kind
+ | null kvs = wrap_mono kind
+ | otherwise
+ = do { traceTc "lk4" (ppr name <+> dcolon <+> ppr kind)
+ ; kvs' <- mapM (const newMetaKindVar) kvs
+ ; let ki = substKiWith kvs kvs' ki_body
+ ; return (HsWrapTy (WpKiApps kvs') (HsTyVar name), ki) }
+ where (kvs, ki_body) = splitForAllTys kind
+
+-- IA0_TODO: this function should disapear, and use the dcPromoted field of DataCon
+kcDataCon :: DataCon -> TcM TcKind
+kcDataCon dc = do
+ let ty = dataConUserType dc
+ unless (isPromotableType ty) $ promoteErr dc ty
+ let ki = promoteType ty
+ traceTc "prm" (ppr ty <+> ptext (sLit "~~>") <+> ppr ki)
+ return ki
+ where
+ promoteErr dc ty = failWithTc (quotes (ppr dc) <+> ptext (sLit "of type")
+ <+> quotes (ppr ty) <+> ptext (sLit "is not promotable"))
kcClass :: Name -> TcM TcKind
kcClass cls = do -- Must be a class
@@ -554,22 +622,51 @@ kcClass cls = do -- Must be a class
%* *
%************************************************************************
-The type desugarer
-
- * Transforms from HsType to Type
- * Zonks any kinds
-
-It cannot fail, and does no validity checking, except for
-structural matters, such as
+Note [Desugaring types]
+~~~~~~~~~~~~~~~~~~~~~~~
+The type desugarer is phase 2 of dealing with HsTypes. Specifically:
+
+ * It transforms from HsType to Type
+
+ * It zonks any kinds. The returned type should have no mutable kind
+ or type variables (hence returning Type not TcType):
+ - any unconstrained kind variables are defaulted to AnyK just
+ as in TcHsSyn.
+ - there are no mutable type variables because we are
+ kind-checking a type
+ Reason: the returned type may be put in a TyCon or DataCon where
+ it will never subsequently be zonked.
+
+You might worry about nested scopes:
+ ..a:kappa in scope..
+ let f :: forall b. T '[a,b] -> Int
+In this case, f's type could have a mutable kind variable kappa in it;
+and we might then default it to AnyK when dealing with f's type
+signature. But we don't expect this to happen because we can't get a
+lexically scoped type variable with a mutable kind variable in it. A
+delicate point, this. If it becomes an issue we might need to
+distinguish top-level from nested uses.
+
+Moreover
+ * it cannot fail,
+ * it does no unifications
+ * it does no validity checking, except for structural matters, such as
(a) spurious ! annotations.
(b) a class used as a type
\begin{code}
+
+zonkTcKindToKind :: TcKind -> TcM Kind
+-- When zonking a TcKind to a kind we instantiate kind variables to AnyK
+zonkTcKindToKind = zonkType (mkZonkTcTyVar (\ _ -> return anyKind) mkTyVarTy)
+
dsHsType :: LHsType Name -> TcM Type
-- All HsTyVarBndrs in the intput type are kind-annotated
+-- See Note [Desugaring types]
dsHsType ty = ds_type (unLoc ty)
ds_type :: HsType Name -> TcM Type
+-- See Note [Desugaring types]
ds_type ty@(HsTyVar _)
= ds_app ty []
@@ -599,7 +696,10 @@ ds_type (HsTupleTy hs_con tys) = do
con <- case hs_con of
HsUnboxedTuple -> return UnboxedTuple
HsBoxyTuple kind -> do
- kind' <- zonkTcKindToKind kind
+ -- Here we use zonkTcKind instead of zonkTcKindToKind because pairs
+ -- are a special case: we use them both for types (eg. (Int, Bool))
+ -- and for constraints (eg. (Show a, Eq a))
+ kind' <- zonkTcKind kind
case () of
_ | kind' `eqKind` constraintKind -> return ConstraintTuple
_ | kind' `eqKind` liftedTypeKind -> return BoxedTuple
@@ -615,10 +715,8 @@ ds_type (HsFunTy ty1 ty2) = do
tau_ty2 <- dsHsType ty2
return (mkFunTy tau_ty1 tau_ty2)
-ds_type (HsOpTy ty1 (L span op) ty2) = do
- tau_ty1 <- dsHsType ty1
- tau_ty2 <- dsHsType ty2
- setSrcSpan span (ds_var_app op [tau_ty1,tau_ty2])
+ds_type (HsOpTy ty1 (wrap, (L span op)) ty2) =
+ setSrcSpan span (ds_app (HsWrapTy wrap (HsTyVar op)) [ty1,ty2])
ds_type ty@(HsAppTy _ _)
= ds_app ty []
@@ -633,7 +731,7 @@ ds_type (HsEqTy ty1 ty2) = do
return (mkEqPred (tau_ty1, tau_ty2))
ds_type (HsForAllTy _ tv_names ctxt ty)
- = tcTyVarBndrs tv_names $ \ tyvars -> do
+ = tcTyVarBndrsKindGen tv_names $ \ tyvars -> do
theta <- mapM dsHsType (unLoc ctxt)
tau <- dsHsType ty
return (mkSigmaTy tyvars theta tau)
@@ -642,16 +740,51 @@ ds_type (HsDocTy ty _) -- Remove the doc comment
= dsHsType ty
ds_type (HsSpliceTy _ _ kind)
- = do { kind' <- zonkTcKindToKind kind
+ = do { kind' <- zonkType (mkZonkTcTyVar (\ _ -> return liftedTypeKind) mkTyVarTy)
+ kind
+ -- See Note [Kind of a type splice]
; newFlexiTyVarTy kind' }
ds_type (HsQuasiQuoteTy {}) = panic "ds_type" -- Eliminated by renamer
ds_type (HsCoreTy ty) = return ty
+ds_type (HsExplicitListTy kind tys) = do
+ kind' <- zonkTcKindToKind kind
+ ds_tys <- mapM dsHsType tys
+ return $
+ foldr (\a b -> mkTyConApp (buildPromotedDataTyCon consDataCon) [kind', a, b])
+ (mkTyConApp (buildPromotedDataTyCon nilDataCon) [kind']) ds_tys
+
+ds_type (HsExplicitTupleTy kis tys) = do
+ MASSERT( length kis == length tys )
+ kis' <- mapM zonkTcKindToKind kis
+ tys' <- mapM dsHsType tys
+ return $ mkTyConApp (buildPromotedDataTyCon (tupleCon BoxedTuple (length kis'))) (kis' ++ tys')
+
+ds_type (HsWrapTy (WpKiApps kappas) ty) = do
+ tau <- ds_type ty
+ kappas' <- mapM zonkTcKindToKind kappas
+ return (mkAppTys tau kappas')
+
dsHsTypes :: [LHsType Name] -> TcM [Type]
dsHsTypes arg_tys = mapM dsHsType arg_tys
\end{code}
+Note [Kind of a type splice]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider these terms, each with TH type splice inside:
+ [| e1 :: Maybe $(..blah..) |]
+ [| e2 :: $(..blah..) |]
+When kind-checking the type signature, we'll kind-check the splice
+$(..blah..); we want to give it a kind that can fit in any context,
+as if $(..blah..) :: forall k. k.
+
+In the e1 example, the context of the splice fixes kappa to *. But
+in the e2 example, we'll desugar the type, zonking the kind unification
+variables as we go. When we encournter the unconstrained kappa, we
+want to default it to '*', not to AnyK.
+
+
Help functions for type applications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -668,15 +801,22 @@ ds_app ty tys = do
return (mkAppTys fun_ty arg_tys)
ds_var_app :: Name -> [Type] -> TcM Type
-ds_var_app name arg_tys = do
- thing <- tcLookup name
- case thing of
- ATyVar _ ty -> return (mkAppTys ty arg_tys)
- AGlobal (ATyCon tc) -> return (mkTyConApp tc arg_tys)
- _ -> wrongThingErr "type" thing name
-\end{code}
+-- See Note [Type checking recursive type and class declarations]
+-- in TcTyClsDecls
+ds_var_app name arg_tys
+ | isTvNameSpace (rdrNameSpace (nameRdrName name))
+ = do { thing <- tcLookup name
+ ; case thing of
+ ATyVar _ ty -> return (mkAppTys ty arg_tys)
+ _ -> wrongThingErr "type" thing name }
+
+ | otherwise
+ = do { thing <- tcLookupGlobal name
+ ; case thing of
+ ATyCon tc -> return (mkTyConApp tc arg_tys)
+ ADataCon dc -> return (mkTyConApp (buildPromotedDataTyCon dc) arg_tys)
+ _ -> wrongThingErr "type" (AGlobal thing) name }
-\begin{code}
addKcTypeCtxt :: LHsType Name -> TcM a -> TcM a
-- Wrap a context around only if we want to show that contexts.
-- Omit invisble ones and ones user's won't grok
@@ -692,6 +832,20 @@ typeCtxt ty = ptext (sLit "In the type") <+> quotes (ppr ty)
%* *
%************************************************************************
+Note [Kind-checking kind-polymorphic types]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider:
+ f :: forall (f::k -> *) a. f a -> Int
+
+Here, the [LHsTyVarBndr Name] of the forall type will be [f,a], where
+ a is a UserTyVar -> type variable without kind annotation
+ f is a KindedTyVar -> type variable with kind annotation
+
+If were were to allow binding sites for kind variables, thus
+ f :: forall @k (f :: k -> *) a. f a -> Int
+then we'd also need
+ k is a UserKiVar -> kind variable (they don't need annotation,
+ since we only have BOX for a super kind)
\begin{code}
kcHsTyVars :: [LHsTyVarBndr Name]
@@ -703,33 +857,141 @@ kcHsTyVars tvs thing_inside
; tcExtendKindEnvTvs kinded_tvs thing_inside }
kcHsTyVar :: HsTyVarBndr Name -> TcM (HsTyVarBndr Name)
- -- Return a *kind-annotated* binder, and a tyvar with a mutable kind in it
-kcHsTyVar (UserTyVar name _) = UserTyVar name <$> newKindVar
-kcHsTyVar tv@(KindedTyVar {}) = return tv
+-- Return a *kind-annotated* binder, whose PostTcKind is
+-- initialised with a kind variable.
+-- Typically the Kind inside the KindedTyVar will be a tyvar with a mutable kind
+-- in it. We aren't yet sure whether the binder is a *type* variable or a *kind*
+-- variable. See Note [Kind-checking kind-polymorphic types]
+--
+-- If the variable is already in scope return it, instead of introducing a new
+-- one. This can occur in
+-- instance C (a,b) where
+-- type F (a,b) c = ...
+-- Here a,b will be in scope when processing the associated type instance for F.
+kcHsTyVar tyvar = do in_scope <- getInLocalScope
+ if in_scope (hsTyVarName tyvar)
+ then do inscope_tyvar <- tcLookupTyVar (hsTyVarName tyvar)
+ return (UserTyVar (tyVarName inscope_tyvar)
+ (tyVarKind inscope_tyvar))
+ else kcHsTyVar' tyvar
+ where
+ kcHsTyVar' (UserTyVar name _) = UserTyVar name <$> newMetaKindVar
+ kcHsTyVar' (KindedTyVar name kind _) = do
+ kind' <- scDsLHsKind kind
+ return (KindedTyVar name kind kind')
------------------
-tcTyVarBndrs :: [LHsTyVarBndr Name] -- Kind-annotated binders, which need kind-zonking
- -> ([TyVar] -> TcM r)
- -> TcM r
+tcTyVarBndrs :: [LHsTyVarBndr Name] -- Kind-annotated binders, which need kind-zonking
+ -> ([TyVar] -> TcM r)
+ -> TcM r
-- Used when type-checking types/classes/type-decls
-- Brings into scope immutable TyVars, not mutable ones that require later zonking
+-- Fix #5426: avoid abstraction over kinds containing # or (#)
tcTyVarBndrs bndrs thing_inside = do
- tyvars <- mapM (zonk . unLoc) bndrs
+ tyvars <- mapM (zonk . hsTyVarNameKind . unLoc) bndrs
tcExtendTyVarEnv tyvars (thing_inside tyvars)
where
- zonk (UserTyVar name kind) = do { kind' <- zonkTcKindToKind kind
- ; return (mkTyVar name kind') }
- zonk (KindedTyVar name kind) = return (mkTyVar name kind)
+ zonk (name, kind)
+ = do { kind' <- zonkTcKind kind
+ ; checkTc (noHashInKind kind') (ptext (sLit "Kind signature contains # or (#)"))
+ ; return (mkTyVar name kind') }
+
+tcTyVarBndrsKindGen :: [LHsTyVarBndr Name] -> ([TyVar] -> TcM r) -> TcM r
+-- tcTyVarBndrsKindGen [(f :: ?k -> *), (a :: ?k)] thing_inside
+-- calls thing_inside with [(k :: BOX), (f :: k -> *), (a :: k)]
+tcTyVarBndrsKindGen bndrs thing_inside
+ = do { let kinds = map (hsTyVarKind . unLoc) bndrs
+ ; (kvs, zonked_kinds) <- kindGeneralizeKinds kinds
+ ; let tyvars = zipWith mkTyVar (map hsLTyVarName bndrs) zonked_kinds
+ ktvs = kvs ++ tyvars -- See Note [Kinds of quantified type variables]
+ ; traceTc "tcTyVarBndrsKindGen" (ppr (bndrs, kvs, tyvars))
+ ; tcExtendTyVarEnv ktvs (thing_inside ktvs) }
+\end{code}
+
+Note [Kinds of quantified type variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+tcTyVarBndrsKindGen quantifies over a specified list of type variables,
+*and* over the kind variables mentioned in the kinds of those tyvars.
+
+Note that we must zonk those kinds (obviously) but less obviously, we
+must return type variables whose kinds are zonked too. Example
+ (a :: k7) where k7 := k9 -> k9
+We must return
+ [k9, a:k9->k9]
+and NOT
+ [k9, a:k7]
+Reason: we're going to turn this into a for-all type,
+ forall k9. forall (a:k7). blah
+which the type checker will then instantiate, and instantiate does not
+look through unification variables!
+
+Hence using zonked_kinds when forming 'tyvars'.
+
+\begin{code}
+tcTyClTyVars :: Name -> [LHsTyVarBndr Name] -- LHS of the type or class decl
+ -> ([TyVar] -> Kind -> TcM a) -> TcM a
+-- tcTyClTyVars T [a,b] calls thing_inside with
+-- [k1,k2,a,b] (k2 -> *) where T : forall k1 k2 (a:k1 -> *) (b:k1). k2 -> *
+--
+-- No need to freshen the k's because they are just skolem
+-- constants here, and we are at top level anyway.
+tcTyClTyVars tycon tyvars thing_inside
+ = do { thing <- tcLookup tycon
+ ; let { kind =
+ case thing of
+ AThing kind -> kind
+ _ -> panic "tcTyClTyVars"
+ -- We only call tcTyClTyVars during typechecking in
+ -- TcTyClDecls, where the local env is extended with
+ -- the generalized_env (mapping Names to AThings).
+ ; (kvs, body) = splitForAllTys kind
+ ; (kinds, res) = splitKindFunTysN (length names) body
+ ; names = hsLTyVarNames tyvars
+ ; tvs = zipWith mkTyVar names kinds
+ ; all_vs = kvs ++ tvs }
+ ; tcExtendTyVarEnv all_vs (thing_inside all_vs res) }
+
+-- Used when generalizing binders and type family patterns
+-- It takes a kind from the type checker (like `k0 -> *`), and returns the
+-- final, kind-generalized kind (`forall k::BOX. k -> *`)
+kindGeneralizeKinds :: [TcKind] -> TcM ([KindVar], [Kind])
+-- INVARIANT: the returned kinds are zonked, and
+-- mention the returned kind variables
+kindGeneralizeKinds kinds
+ = do { -- Quantify over kind variables free in
+ -- the kinds, and *not* in the environment
+ ; zonked_kinds <- mapM zonkTcKind kinds
+ ; gbl_tvs <- tcGetGlobalTyVars -- Already zonked
+ ; let kvs_to_quantify = tyVarsOfTypes zonked_kinds
+ `minusVarSet` gbl_tvs
+
+ ; kvs <- ASSERT2 (all isKiVar (varSetElems kvs_to_quantify), ppr kvs_to_quantify)
+ zonkQuantifiedTyVars kvs_to_quantify
+
+ -- Zonk the kinds again, to pick up either the kind
+ -- variables we quantify over, or *, depending on whether
+ -- zonkQuantifiedTyVars decided to generalise (which in
+ -- turn depends on PolyKinds)
+ ; final_kinds <- mapM zonkTcKind zonked_kinds
+
+ ; traceTc "generalizeKind" ( ppr kinds <+> ppr kvs_to_quantify
+ <+> ppr kvs <+> ppr final_kinds)
+ ; return (kvs, final_kinds) }
+
+kindGeneralizeKind :: TcKind -> TcM ( [KindVar] -- these were flexi kind vars
+ , Kind ) -- this is the old kind where flexis got zonked
+kindGeneralizeKind kind = do
+ (kvs, [kind']) <- kindGeneralizeKinds [kind]
+ return (kvs, kind')
-----------------------------------
-tcDataKindSig :: Maybe Kind -> TcM [TyVar]
+tcDataKindSig :: Kind -> TcM [TyVar]
-- GADT decls can have a (perhaps partial) kind signature
-- e.g. data T :: * -> * -> * where ...
-- This function makes up suitable (kinded) type variables for
-- the argument kinds, and checks that the result kind is indeed *.
-- We use it also to make up argument type variables for for data instances.
-tcDataKindSig Nothing = return []
-tcDataKindSig (Just kind)
+tcDataKindSig kind
= do { checkTc (isLiftedTypeKind res_kind) (badKindSig kind)
; span <- getSrcSpanM
; us <- newUniqueSupply
@@ -932,12 +1194,22 @@ data EkCtxt = EkUnk -- Unknown context
| EkIParam -- Implicit parameter type
| EkFamInst -- Family instance
+instance Outputable ExpKind where
+ ppr (EK k _) = ptext (sLit "Expected kind:") <+> ppr k
-ekLifted, ekOpen, ekConstraint :: ExpKind
+ekLifted, ekOpen, ekArg, ekConstraint :: ExpKind
ekLifted = EK liftedTypeKind EkUnk
ekOpen = EK openTypeKind EkUnk
+ekArg = EK argTypeKind EkUnk
ekConstraint = EK constraintKind EkUnk
+unifyKinds :: SDoc -> [(LHsType Name, TcKind)] -> TcM TcKind
+unifyKinds fun act_kinds = do
+ kind <- newMetaKindVar
+ let exp_kind arg_no = EK kind (EkArg fun arg_no)
+ mapM_ (\(arg_no, (ty, act_kind)) -> checkExpectedKind ty act_kind (exp_kind arg_no)) (zip [1..] act_kinds)
+ return kind
+
checkExpectedKind :: Outputable a => a -> TcKind -> ExpKind -> TcM ()
-- A fancy wrapper for 'unifyKind', which tries
-- to give decent error messages.
@@ -945,8 +1217,9 @@ checkExpectedKind :: Outputable a => a -> TcKind -> ExpKind -> TcM ()
-- checks that the actual kind act_kind is compatible
-- with the expected kind exp_kind
-- The first argument, ty, is used only in the error message generation
-checkExpectedKind ty act_kind (EK exp_kind ek_ctxt) = do
- (_errs, mb_r) <- tryTc (unifyKind exp_kind act_kind)
+checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt) = do
+ traceTc "checkExpectedKind" (ppr ty $$ ppr act_kind $$ ppr ek)
+ (_errs, mb_r) <- tryTc (unifyKind act_kind exp_kind)
case mb_r of
Just _ -> return () -- Unification succeeded
Nothing -> do
@@ -962,8 +1235,8 @@ checkExpectedKind ty act_kind (EK exp_kind ek_ctxt) = do
n_exp_as = length exp_as
n_act_as = length act_as
- (env1, tidy_exp_kind) = tidyKind env0 exp_kind
- (env2, tidy_act_kind) = tidyKind env1 act_kind
+ (env1, tidy_exp_kind) = tidyOpenKind env0 exp_kind
+ (env2, tidy_act_kind) = tidyOpenKind env1 act_kind
err | n_exp_as < n_act_as -- E.g. [Maybe]
= quotes (ppr ty) <+> ptext (sLit "is not applied to enough type arguments")
@@ -1005,6 +1278,100 @@ checkExpectedKind ty act_kind (EK exp_kind ek_ctxt) = do
\end{code}
%************************************************************************
+%* *
+ Sort checking kinds
+%* *
+%************************************************************************
+
+scDsLHsKind converts a user-written kind to an internal, sort-checked kind.
+It does sort checking and desugaring at the same time, in one single pass.
+It fails when the kinds are not well-formed (eg. data A :: * Int), or if there
+are non-promotable or non-fully applied kinds.
+
+\begin{code}
+scDsLHsKind :: LHsKind Name -> TcM Kind
+scDsLHsKind k = addErrCtxt (ptext (sLit "In the kind") <+> quotes (ppr k)) $
+ sc_ds_lhs_kind k
+
+scDsLHsMaybeKind :: Maybe (LHsKind Name) -> TcM (Maybe Kind)
+scDsLHsMaybeKind Nothing = return Nothing
+scDsLHsMaybeKind (Just k) = do k' <- scDsLHsKind k
+ return (Just k')
+
+sc_ds_lhs_kind :: LHsKind Name -> TcM Kind
+sc_ds_lhs_kind (L span ki) = setSrcSpan span (sc_ds_hs_kind ki)
+
+-- The main worker
+sc_ds_hs_kind :: HsKind Name -> TcM Kind
+sc_ds_hs_kind k@(HsTyVar _) = sc_ds_app k []
+sc_ds_hs_kind k@(HsAppTy _ _) = sc_ds_app k []
+
+sc_ds_hs_kind (HsParTy ki) = sc_ds_lhs_kind ki
+
+sc_ds_hs_kind (HsFunTy ki1 ki2) =
+ do kappa_ki1 <- sc_ds_lhs_kind ki1
+ kappa_ki2 <- sc_ds_lhs_kind ki2
+ return (mkArrowKind kappa_ki1 kappa_ki2)
+
+sc_ds_hs_kind (HsListTy ki) =
+ do kappa <- sc_ds_lhs_kind ki
+ checkWiredInTyCon listTyCon
+ return $ mkListTy kappa
+
+sc_ds_hs_kind (HsTupleTy _ kis) =
+ do kappas <- mapM sc_ds_lhs_kind kis
+ checkWiredInTyCon tycon
+ return $ mkTyConApp tycon kappas
+ where tycon = tupleTyCon BoxedTuple (length kis)
+
+-- Argument not kind-shaped
+sc_ds_hs_kind k = panic ("sc_ds_hs_kind: " ++ showPpr k)
+
+-- Special case for kind application
+sc_ds_app :: HsKind Name -> [LHsKind Name] -> TcM Kind
+sc_ds_app (HsAppTy ki1 ki2) kis = sc_ds_app (unLoc ki1) (ki2:kis)
+sc_ds_app (HsTyVar tc) kis =
+ do arg_kis <- mapM sc_ds_lhs_kind kis
+ sc_ds_var_app tc arg_kis
+sc_ds_app ki _ = failWithTc (quotes (ppr ki) <+>
+ ptext (sLit "is not a kind constructor"))
+
+-- IA0_TODO: With explicit kind polymorphism I might need to add ATyVar
+sc_ds_var_app :: Name -> [Kind] -> TcM Kind
+-- Special case for * and Constraint kinds
+sc_ds_var_app name arg_kis
+ | name == liftedTypeKindTyConName
+ || name == constraintKindTyConName = do
+ unless (null arg_kis)
+ (failWithTc (text "Kind" <+> ppr name <+> text "cannot be applied"))
+ thing <- tcLookup name
+ case thing of
+ AGlobal (ATyCon tc) -> return (mkTyConApp tc [])
+ _ -> panic "sc_ds_var_app 1"
+
+-- General case
+sc_ds_var_app name arg_kis = do
+ thing <- tcLookup name
+ case thing of
+ AGlobal (ATyCon tc)
+ | isAlgTyCon tc || isTupleTyCon tc -> do
+ poly_kinds <- xoptM Opt_PolyKinds
+ unless poly_kinds $ addErr (polyKindsErr name)
+ let tc_kind = tyConKind tc
+ case isPromotableKind tc_kind of
+ Just n | n == length arg_kis ->
+ return (mkTyConApp (mkPromotedTypeTyCon tc) arg_kis)
+ Just _ -> err tc_kind "is not fully applied"
+ Nothing -> err tc_kind "is not promotable"
+
+ _ -> wrongThingErr "promoted type" thing name
+
+ where err k m = failWithTc ( quotes (ppr name) <+> ptext (sLit "of kind")
+ <+> quotes (ppr k) <+> ptext (sLit m))
+
+\end{code}
+
+%************************************************************************
%* *
Scoped type variables
%* *
diff --git a/compiler/typecheck/TcInstDcls.lhs b/compiler/typecheck/TcInstDcls.lhs
index 01bffce61d..837f3823ba 100644
--- a/compiler/typecheck/TcInstDcls.lhs
+++ b/compiler/typecheck/TcInstDcls.lhs
@@ -454,16 +454,15 @@ tcLocalInstDecl1 (L loc (InstDecl poly_ty binds uprags ats))
; checkTc (not is_boot || (isEmptyLHsBinds binds && null uprags))
badBootDeclErr
- ; (tyvars, theta, clas, inst_tys) <- tcHsInstHead poly_ty
- ; checkValidInstance poly_ty tyvars theta clas inst_tys
+ ; (tyvars, theta, clas, inst_tys) <- tcHsInstHead InstDeclCtxt poly_ty
; let mini_env = mkVarEnv (classTyVars clas `zip` inst_tys)
-- Next, process any associated types.
; traceTc "tcLocalInstDecl" (ppr poly_ty)
; idx_tycons0 <- tcExtendTyVarEnv tyvars $
- mapAndRecoverM (tcAssocDecl clas mini_env) ats
+ mapAndRecoverM (tcAssocDecl clas mini_env) ats
- -- Check for misssing associated types and build them
+ -- Check for missing associated types and build them
-- from their defaults (if available)
; let defined_ats = mkNameSet $ map (tcdName . unLoc) ats
check_at_instance (fam_tc, defs)
@@ -473,7 +472,7 @@ tcLocalInstDecl1 (L loc (InstDecl poly_ty binds uprags ats))
| null defs = return (Just (tyConName fam_tc), [])
-- No user instance, have defaults ==> instatiate them
| otherwise = do
- defs' <- forM defs $ \(ATD tvs pat_tys rhs) -> do
+ defs' <- forM defs $ \(ATD tvs pat_tys rhs _loc) -> do
let mini_env_subst = mkTvSubst (mkInScopeSet (mkVarSet tvs)) mini_env
tvs' = varSetElems (tyVarsOfType rhs')
pat_tys' = substTys mini_env_subst pat_tys
@@ -526,6 +525,7 @@ tcFamInstDecl :: TopLevelFlag -> TyClDecl Name -> TcM TyCon
tcFamInstDecl top_lvl decl
= do { -- type family instances require -XTypeFamilies
-- and can't (currently) be in an hs-boot file
+ ; traceTc "tcFamInstDecl" (ppr decl)
; let fam_tc_lname = tcdLName decl
; type_families <- xoptM Opt_TypeFamilies
; is_boot <- tcIsHsBoot -- Are we compiling an hs-boot file?
@@ -551,13 +551,8 @@ tcFamInstDecl1 :: TyCon -> TyClDecl Name -> TcM TyCon
-- "type instance"
tcFamInstDecl1 fam_tc (decl@TySynonym {})
- = kcFamTyPats decl $ \k_tvs k_typats resKind ->
- do { -- kind check the right-hand side of the type equation
- ; k_rhs <- kcCheckLHsType (tcdSynRhs decl) (EK resKind EkUnk)
- -- ToDo: the ExpKind could be better
-
- -- (1) do the work of verifying the synonym
- ; (t_tvs, t_typats, t_rhs) <- tcSynFamInstDecl fam_tc (decl { tcdTyVars = k_tvs, tcdTyPats = Just k_typats, tcdSynRhs = k_rhs })
+ = do { -- (1) do the work of verifying the synonym
+ ; (t_tvs, t_typats, t_rhs) <- tcSynFamInstDecl fam_tc decl
-- (2) check the well-formedness of the instance
; checkValidFamInst t_typats t_rhs
@@ -571,59 +566,50 @@ tcFamInstDecl1 fam_tc (decl@TySynonym {})
}
-- "newtype instance" and "data instance"
-tcFamInstDecl1 fam_tc (decl@TyData { tcdND = new_or_data
- , tcdCons = cons})
- = kcFamTyPats decl $ \k_tvs k_typats resKind ->
- do { -- check that the family declaration is for the right kind
+tcFamInstDecl1 fam_tc (decl@TyData { tcdND = new_or_data, tcdCtxt = ctxt
+ , tcdTyVars = tvs, tcdTyPats = Just pats
+ , tcdCons = cons})
+ = do { -- Check that the family declaration is for the right kind
checkTc (isFamilyTyCon fam_tc) (notFamily fam_tc)
; checkTc (isAlgTyCon fam_tc) (wrongKindOfFamily fam_tc)
- ; -- (1) kind check the data declaration as usual
- ; k_decl <- kcDataDecl decl k_tvs
- ; let k_ctxt = tcdCtxt k_decl
- k_cons = tcdCons k_decl
-
- -- result kind must be '*' (otherwise, we have too few patterns)
- ; resKind' <- zonkTcKindToKind resKind -- Remember: kcFamTyPats supplies unzonked kind!
- ; checkTc (isLiftedTypeKind resKind') $ tooFewParmsErr (tyConArity fam_tc)
-
- -- (2) type check indexed data type declaration
- ; tcTyVarBndrs k_tvs $ \t_tvs -> do -- turn kinded into proper tyvars
+ -- Kind check type patterns
+ ; tcFamTyPats fam_tc tvs pats (\_always_star -> kcDataDecl decl) $
+ \tvs' pats' resultKind -> do
- -- kind check the type indexes and the context
- { t_typats <- mapM tcHsKindedType k_typats
- ; stupid_theta <- tcHsKindedContext k_ctxt
+ -- Check that left-hand side contains no type family applications
+ -- (vanilla synonyms are fine, though, and we checked for
+ -- foralls earlier)
+ { mapM_ checkTyFamFreeness pats'
+
+ -- Result kind must be '*' (otherwise, we have too few patterns)
+ ; checkTc (isLiftedTypeKind resultKind) $ tooFewParmsErr (tyConArity fam_tc)
- -- (3) Check that
- -- (a) left-hand side contains no type family applications
- -- (vanilla synonyms are fine, though, and we checked for
- -- foralls earlier)
- ; mapM_ checkTyFamFreeness t_typats
+ ; stupid_theta <- tcHsKindedContext =<< kcHsContext ctxt
+ ; dataDeclChecks (tcdName decl) new_or_data stupid_theta cons
- ; dataDeclChecks (tcdName decl) new_or_data stupid_theta k_cons
-
- -- (4) construct representation tycon
- ; rep_tc_name <- newFamInstTyConName (tcdLName decl) t_typats
+ -- Construct representation tycon
+ ; rep_tc_name <- newFamInstTyConName (tcdLName decl) pats'
; let ex_ok = True -- Existentials ok for type families!
; fixM (\ rep_tycon -> do
- { let orig_res_ty = mkTyConApp fam_tc t_typats
- ; data_cons <- tcConDecls ex_ok rep_tycon
- (t_tvs, orig_res_ty) k_cons
+ { let orig_res_ty = mkTyConApp fam_tc pats'
+ ; data_cons <- tcConDecls new_or_data ex_ok rep_tycon
+ (tvs', orig_res_ty) cons
; tc_rhs <-
case new_or_data of
DataType -> return (mkDataTyConRhs data_cons)
NewType -> ASSERT( not (null data_cons) )
mkNewTyConRhs rep_tc_name rep_tycon (head data_cons)
- ; buildAlgTyCon rep_tc_name t_tvs stupid_theta tc_rhs Recursive
- h98_syntax NoParentTyCon (Just (fam_tc, t_typats))
+ ; buildAlgTyCon rep_tc_name tvs' stupid_theta tc_rhs Recursive
+ h98_syntax NoParentTyCon (Just (fam_tc, pats'))
-- We always assume that indexed types are recursive. Why?
-- (1) Due to their open nature, we can never be sure that a
-- further instance might not introduce a new recursive
-- dependency. (2) They are always valid loop breakers as
-- they involve a coercion.
})
- }}
- where
+ } }
+ where
h98_syntax = case cons of -- All constructors have same shape
L _ (ConDecl { con_res = ResTyGADT _ }) : _ -> False
_ -> True
@@ -644,9 +630,9 @@ tcAssocDecl clas mini_env (L loc decl)
-- Check that the associated type comes from this class
; checkTc (Just clas == tyConAssoc_maybe fam_tc)
- (badATErr clas (tyConName at_tc))
+ (badATErr (className clas) (tyConName at_tc))
- -- See Note [Checking consistent instantiation]
+ -- See Note [Checking consistent instantiation] in TcTyClsDecls
; zipWithM_ check_arg (tyConTyVars fam_tc) at_tys
; return at_tc }
@@ -914,7 +900,7 @@ tcSpecInst :: Id -> Sig Name -> TcM TcSpecPrag
tcSpecInst dfun_id prag@(SpecInstSig hs_ty)
= addErrCtxt (spec_ctxt prag) $
do { let name = idName dfun_id
- ; (tyvars, theta, clas, tys) <- tcHsInstHead hs_ty
+ ; (tyvars, theta, clas, tys) <- tcHsInstHead SpecInstCtxt hs_ty
; let spec_dfun_ty = mkDictFunTy tyvars theta clas tys
; co_fn <- tcSubType (SpecPragOrigin name) SpecInstCtxt
diff --git a/compiler/typecheck/TcInteract.lhs b/compiler/typecheck/TcInteract.lhs
index 8258036b95..f0e1a4ddbe 100644
--- a/compiler/typecheck/TcInteract.lhs
+++ b/compiler/typecheck/TcInteract.lhs
@@ -440,8 +440,9 @@ trySpontaneousEqOneWay d eqv gw tv xi
| not (isSigTyVar tv) || isTyVarTy xi
= do { let kxi = typeKind xi -- NB: 'xi' is fully rewritten according to the inerts
-- so we have its more specific kind in our hands
- ; if kxi `isSubKind` tyVarKind tv then
- solveWithIdentity d eqv gw tv xi
+ ; is_sub_kind <- kxi `isSubKindTcS` tyVarKind tv
+ ; if is_sub_kind then
+ solveWithIdentity eqv gw tv xi
else return SPCantSolve
}
| otherwise -- Still can't solve, sig tyvar and non-variable rhs
@@ -451,17 +452,34 @@ trySpontaneousEqOneWay d eqv gw tv xi
trySpontaneousEqTwoWay :: SubGoalDepth
-> EqVar -> CtFlavor -> TcTyVar -> TcTyVar -> TcS SPSolveResult
-- Both tyvars are *touchable* MetaTyvars so there is only a chance for kind error here
-trySpontaneousEqTwoWay d eqv gw tv1 tv2
- | k1 `isSubKind` k2
- , nicer_to_update_tv2 = solveWithIdentity d eqv gw tv2 (mkTyVarTy tv1)
- | k2 `isSubKind` k1
- = solveWithIdentity d eqv gw tv1 (mkTyVarTy tv2)
- | otherwise -- None is a subkind of the other, but they are both touchable!
- = return SPCantSolve
+
+trySpontaneousEqTwoWay eqv gw tv1 tv2
+ = do { k1_sub_k2 <- k1 `isSubKindTcS` k2
+ ; if k1_sub_k2 && nicer_to_update_tv2
+ then solveWithIdentity eqv gw tv2 (mkTyVarTy tv1)
+ else do
+ { k2_sub_k1 <- k2 `isSubKindTcS` k1
+ ; MASSERT( k2_sub_k1 ) -- they were unified in TcCanonical
+ ; solveWithIdentity eqv gw tv1 (mkTyVarTy tv2) } }
where
k1 = tyVarKind tv1
k2 = tyVarKind tv2
nicer_to_update_tv2 = isSigTyVar tv1 || isSystemName (Var.varName tv2)
+{-
+-- Previous code below (before kind polymorphism and unification):
+ -- | k1 `isSubKind` k2
+ -- , nicer_to_update_tv2 = solveWithIdentity eqv gw tv2 (mkTyVarTy tv1)
+ -- | k2 `isSubKind` k1
+ -- = solveWithIdentity eqv gw tv1 (mkTyVarTy tv2)
+ -- | otherwise -- None is a subkind of the other, but they are both touchable!
+ -- = return SPCantSolve
+ -- -- do { addErrorTcS KindError gw (mkTyVarTy tv1) (mkTyVarTy tv2)
+ -- -- ; return SPError }
+ -- where
+ -- k1 = tyVarKind tv1
+ -- k2 = tyVarKind tv2
+ -- nicer_to_update_tv2 = isSigTyVar tv1 || isSystemName (Var.varName tv2)
+-}
\end{code}
Note [Kind errors]
diff --git a/compiler/typecheck/TcMType.lhs b/compiler/typecheck/TcMType.lhs
index dc8347f88a..d3db194d1f 100644
--- a/compiler/typecheck/TcMType.lhs
+++ b/compiler/typecheck/TcMType.lhs
@@ -24,7 +24,7 @@ module TcMType (
newFlexiTyVar,
newFlexiTyVarTy, -- Kind -> TcM TcType
newFlexiTyVarTys, -- Int -> Kind -> TcM [TcType]
- newKindVar, newKindVars,
+ newMetaKindVar, newMetaKindVars,
mkTcTyVarName,
newMetaTyVar, readMetaTyVar, writeMetaTyVar, writeMetaTyVarRef,
@@ -42,13 +42,15 @@ module TcMType (
-- Instantiation
tcInstTyVars, tcInstSigTyVars,
tcInstType,
- tcInstSkolTyVars, tcInstSuperSkolTyVars, tcInstSkolTyVar, tcInstSkolType,
+ tcInstSkolTyVars, tcInstSuperSkolTyVars,
+ tcInstSkolTyVarsX, tcInstSuperSkolTyVarsX,
+ tcInstSkolTyVar, tcInstSkolType,
tcSkolDFunType, tcSuperSkolTyVars,
--------------------------------
-- Checking type validity
Rank, UserTypeCtxt(..), checkValidType, checkValidMonoType,
- SourceTyCtxt(..), checkValidTheta,
+ checkValidTheta,
checkValidInstHead, checkValidInstance, validDerivPred,
checkInstTermination, checkValidFamInst, checkTyFamFreeness,
arityErr,
@@ -56,20 +58,20 @@ module TcMType (
--------------------------------
-- Zonking
- zonkType, mkZonkTcTyVar, zonkTcPredType,
+ zonkType, zonkKind, zonkTcPredType,
zonkTcTypeCarefully, skolemiseUnboundMetaTyVar,
zonkTcTyVar, zonkTcTyVars, zonkTcTyVarsAndFV, zonkSigTyVar,
zonkQuantifiedTyVar, zonkQuantifiedTyVars,
zonkTcType, zonkTcTypes, zonkTcThetaType,
- zonkTcKindToKind, zonkTcKind,
- zonkCt, zonkCts,
+
+ zonkTcKind, defaultKindVarToStar, zonkCt, zonkCts,
zonkImplication, zonkEvVar, zonkWantedEvVar,
+
zonkWC, zonkWantedEvVars,
zonkTcTypeAndSubst,
tcGetGlobalTyVars,
-
- readKindVar, writeKindVar
+ compatKindTcM, isSubKindTcM
) where
#include "HsVersions.h"
@@ -78,6 +80,7 @@ module TcMType (
import TypeRep
import TcType
import Type
+import Kind
import Class
import TyCon
import Var
@@ -103,7 +106,7 @@ import Unique( Unique )
import Bag
import Control.Monad
-import Data.List ( (\\) )
+import Data.List ( (\\), partition, mapAccumL )
\end{code}
@@ -114,13 +117,13 @@ import Data.List ( (\\) )
%************************************************************************
\begin{code}
-newKindVar :: TcM TcKind
-newKindVar = do { uniq <- newUnique
+newMetaKindVar :: TcM TcKind
+newMetaKindVar = do { uniq <- newUnique
; ref <- newMutVar Flexi
- ; return (mkTyVarTy (mkKindVar uniq ref)) }
+ ; return (mkTyVarTy (mkMetaKindVar uniq ref)) }
-newKindVars :: Int -> TcM [TcKind]
-newKindVars n = mapM (\ _ -> newKindVar) (nOfThem n ())
+newMetaKindVars :: Int -> TcM [TcKind]
+newMetaKindVars n = mapM (\ _ -> newMetaKindVar) (nOfThem n ())
\end{code}
@@ -210,31 +213,48 @@ tcSkolDFunType ty = tcInstType (\tvs -> return (tcSuperSkolTyVars tvs)) ty
tcSuperSkolTyVars :: [TyVar] -> [TcTyVar]
-- Make skolem constants, but do *not* give them new names, as above
-- Moreover, make them "super skolems"; see comments with superSkolemTv
-tcSuperSkolTyVars tyvars
- = [ mkTcTyVar (tyVarName tv) (tyVarKind tv) superSkolemTv
- | tv <- tyvars ]
+-- see Note [Kind substitution when instantiating]
+-- Precondition: tyvars should be ordered (kind vars first)
+tcSuperSkolTyVars = snd . mapAccumL tcSuperSkolTyVar (mkTopTvSubst [])
+
+tcSuperSkolTyVar :: TvSubst -> TyVar -> (TvSubst, TcTyVar)
+tcSuperSkolTyVar subst tv
+ = (extendTvSubst subst tv (mkTyVarTy new_tv), new_tv)
+ where
+ kind = substTy subst (tyVarKind tv)
+ new_tv = mkTcTyVar (tyVarName tv) kind superSkolemTv
-tcInstSkolTyVar :: Bool -> TyVar -> TcM TcTyVar
+tcInstSkolTyVar :: Bool -> TvSubst -> TyVar -> TcM (TvSubst, TcTyVar)
-- Instantiate the tyvar, using
--- * the occ-name and kind of the supplied tyvar,
--- * the unique from the monad,
--- * the location either from the tyvar (skol_info = SigSkol)
+-- * the occ-name and kind of the supplied tyvar,
+-- * the unique from the monad,
+-- * the location either from the tyvar (skol_info = SigSkol)
-- or from the monad (otherwise)
-tcInstSkolTyVar overlappable tyvar
- = do { uniq <- newUnique
- ; loc <- getSrcSpanM
- ; let new_name = mkInternalName uniq occ loc
- ; return (mkTcTyVar new_name kind (SkolemTv overlappable)) }
+tcInstSkolTyVar overlappable subst tyvar
+ = do { uniq <- newUnique
+ ; loc <- getSrcSpanM
+ ; let new_name = mkInternalName uniq occ loc
+ new_tv = mkTcTyVar new_name kind (SkolemTv overlappable)
+ ; return (extendTvSubst subst tyvar (mkTyVarTy new_tv), new_tv) }
where
old_name = tyVarName tyvar
occ = nameOccName old_name
- kind = tyVarKind tyvar
+ kind = substTy subst (tyVarKind tyvar)
+
+tcInstSkolTyVars' :: Bool -> TvSubst -> [TyVar] -> TcM (TvSubst, [TcTyVar])
+-- Precondition: tyvars should be ordered (kind vars first)
+-- see Note [Kind substitution when instantiating]
+tcInstSkolTyVars' isSuperSkol = mapAccumLM (tcInstSkolTyVar isSuperSkol)
-tcInstSkolTyVars :: [TyVar] -> TcM [TcTyVar]
-tcInstSkolTyVars tyvars = mapM (tcInstSkolTyVar False) tyvars
+-- Wrappers
+tcInstSkolTyVars, tcInstSuperSkolTyVars :: [TyVar] -> TcM [TcTyVar]
+tcInstSkolTyVars = fmap snd . tcInstSkolTyVars' False (mkTopTvSubst [])
+tcInstSuperSkolTyVars = fmap snd . tcInstSkolTyVars' True (mkTopTvSubst [])
-tcInstSuperSkolTyVars :: [TyVar] -> TcM [TcTyVar]
-tcInstSuperSkolTyVars tyvars = mapM (tcInstSkolTyVar True) tyvars
+tcInstSkolTyVarsX, tcInstSuperSkolTyVarsX
+ :: TvSubst -> [TyVar] -> TcM (TvSubst, [TcTyVar])
+tcInstSkolTyVarsX subst = tcInstSkolTyVars' False subst
+tcInstSuperSkolTyVarsX subst = tcInstSkolTyVars' True subst
tcInstSkolType :: TcType -> TcM ([TcTyVar], TcThetaType, TcType)
-- Instantiate a type with fresh skolem constants
@@ -244,19 +264,37 @@ tcInstSkolType ty = tcInstType tcInstSkolTyVars ty
tcInstSigTyVars :: [TyVar] -> TcM [TcTyVar]
-- Make meta SigTv type variables for patten-bound scoped type varaibles
-- We use SigTvs for them, so that they can't unify with arbitrary types
-tcInstSigTyVars = mapM tcInstSigTyVar
-
-tcInstSigTyVar :: TyVar -> TcM TcTyVar
-tcInstSigTyVar tyvar
- = do { uniq <- newMetaUnique
- ; ref <- newMutVar Flexi
- ; let name = setNameUnique (tyVarName tyvar) uniq
- -- Use the same OccName so that the tidy-er
- -- doesn't rename 'a' to 'a0' etc
- kind = tyVarKind tyvar
- ; return (mkTcTyVar name kind (MetaTv SigTv ref)) }
+-- Precondition: tyvars should be ordered (kind vars first)
+-- see Note [Kind substitution when instantiating]
+tcInstSigTyVars = fmap snd . mapAccumLM tcInstSigTyVar (mkTopTvSubst [])
+
+tcInstSigTyVar :: TvSubst -> TyVar -> TcM (TvSubst, TcTyVar)
+tcInstSigTyVar subst tv
+ = do { uniq <- newMetaUnique
+ ; ref <- newMutVar Flexi
+ ; let name = setNameUnique (tyVarName tv) uniq
+ -- Use the same OccName so that the tidy-er
+ -- doesn't rename 'a' to 'a0' etc
+ kind = substTy subst (tyVarKind tv)
+ new_tv = mkTcTyVar name kind (MetaTv SigTv ref)
+ ; return (extendTvSubst subst tv (mkTyVarTy new_tv), new_tv) }
\end{code}
+Note [Kind substitution when instantiating]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When we instantiate a bunch of kind and type variables, first we
+expect them to be sorted (kind variables first, then type variables).
+Then we have to instantiate the kind variables, build a substitution
+from old variables to the new variables, then instantiate the type
+variables substituting the original kind.
+
+Exemple: If we want to instantiate
+ [(k1 :: BOX), (k2 :: BOX), (a :: k1 -> k2), (b :: k1)]
+we want
+ [(?k1 :: BOX), (?k2 :: BOX), (?a :: ?k1 -> ?k2), (?b :: ?k1)]
+instead of the buggous
+ [(?k1 :: BOX), (?k2 :: BOX), (?a :: k1 -> k2), (?b :: k1)]
+
%************************************************************************
%* *
@@ -282,6 +320,7 @@ mkTcTyVarName :: Unique -> FastString -> Name
-- leaving the un-cluttered names free for user names
mkTcTyVarName uniq str = mkSysTvName uniq str
+-- Works for both type and kind variables
readMetaTyVar :: TyVar -> TcM MetaDetails
readMetaTyVar tyvar = ASSERT2( isMetaTyVar tyvar, ppr tyvar )
readMutVar (metaTvRef tyvar)
@@ -305,6 +344,7 @@ isFlexiMetaTyVar tv
| otherwise = return False
--------------------
+-- Works with both type and kind variables
writeMetaTyVar :: TcTyVar -> TcType -> TcM ()
-- Write into a currently-empty MetaTyVar
@@ -334,20 +374,27 @@ writeMetaTyVarRef tyvar ref ty
; writeMutVar ref (Indirect ty) }
-- Everything from here on only happens if DEBUG is on
- | not (isPredTy tv_kind) -- Don't check kinds for updates to coercion variables
- , not (ty_kind `isSubKind` tv_kind)
- = WARN( True, hang (text "Ill-kinded update to meta tyvar")
- 2 (ppr tyvar $$ ppr tv_kind $$ ppr ty $$ ppr ty_kind) )
- return ()
-
| otherwise
= do { meta_details <- readMutVar ref;
+ -- Zonk kinds to allow the error check to work
+ ; zonked_tv_kind <- zonkTcKind tv_kind
+ ; zonked_ty_kind <- zonkTcKind ty_kind
+
+ -- Check for double updates
; ASSERT2( isFlexi meta_details,
hang (text "Double update of meta tyvar")
2 (ppr tyvar $$ ppr meta_details) )
traceTc "writeMetaTyVar" (ppr tyvar <+> text ":=" <+> ppr ty)
- ; writeMutVar ref (Indirect ty) }
+ ; writeMutVar ref (Indirect ty)
+ ; when ( not (isPredTy tv_kind)
+ -- Don't check kinds for updates to coercion variables
+ && not (zonked_ty_kind `isSubKind` zonked_tv_kind))
+ $ WARN( True, hang (text "Ill-kinded update to meta tyvar")
+ 2 ( ppr tyvar <+> text "::" <+> ppr tv_kind
+ <+> text ":="
+ <+> ppr ty <+> text "::" <+> ppr ty_kind) )
+ (return ()) }
where
tv_kind = tyVarKind tyvar
ty_kind = typeKind ty
@@ -374,23 +421,26 @@ newFlexiTyVarTys n kind = mapM newFlexiTyVarTy (nOfThem n kind)
tcInstTyVars :: [TyVar] -> TcM ([TcTyVar], [TcType], TvSubst)
-- Instantiate with META type variables
-tcInstTyVars tyvars
- = do { tc_tvs <- mapM tcInstTyVar tyvars
- ; let tys = mkTyVarTys tc_tvs
- ; return (tc_tvs, tys, zipTopTvSubst tyvars tys) }
- -- Since the tyvars are freshly made,
- -- they cannot possibly be captured by
- -- any existing for-alls. Hence zipTopTvSubst
-
-tcInstTyVar :: TyVar -> TcM TcTyVar
--- Make a new unification variable tyvar whose Name and Kind
--- come from an existing TyVar
-tcInstTyVar tyvar
- = do { uniq <- newMetaUnique
- ; ref <- newMutVar Flexi
- ; let name = mkSystemName uniq (getOccName tyvar)
- kind = tyVarKind tyvar
- ; return (mkTcTyVar name kind (MetaTv TauTv ref)) }
+tcInstTyVars tyvars = tcInstTyVarsX emptyTvSubst tyvars
+ -- emptyTvSubst has an empty in-scope set, but that's fine here
+ -- Since the tyvars are freshly made, they cannot possibly be
+ -- captured by any existing for-alls.
+
+tcInstTyVarsX :: TvSubst -> [TyVar] -> TcM ([TcTyVar], [TcType], TvSubst)
+tcInstTyVarsX subst tyvars =
+ do { (subst', tyvars') <- mapAccumLM tcInstTyVar subst tyvars
+ ; return (tyvars', mkTyVarTys tyvars', subst') }
+
+tcInstTyVar :: TvSubst -> TyVar -> TcM (TvSubst, TcTyVar)
+-- Make a new unification variable tyvar whose Name and Kind come from
+-- an existing TyVar. We substitute kind variables in the kind.
+tcInstTyVar subst tyvar
+ = do { uniq <- newMetaUnique
+ ; ref <- newMutVar Flexi
+ ; let name = mkSystemName uniq (getOccName tyvar)
+ kind = substTy subst (tyVarKind tyvar)
+ new_tv = mkTcTyVar name kind (MetaTv TauTv ref)
+ ; return (extendTvSubst subst tyvar (mkTyVarTy new_tv), new_tv) }
\end{code}
@@ -475,29 +525,37 @@ zonkTcType ty = zonkType zonkTcTyVar ty
zonkTcTyVar :: TcTyVar -> TcM TcType
-- Simply look through all Flexis
zonkTcTyVar tv
- = ASSERT2( isTcTyVar tv, ppr tv )
+ = ASSERT2( isTcTyVar tv, ppr tv ) do
case tcTyVarDetails tv of
- SkolemTv {} -> return (TyVarTy tv)
- RuntimeUnk {} -> return (TyVarTy tv)
+ SkolemTv {} -> zonk_kind_and_return
+ RuntimeUnk {} -> zonk_kind_and_return
FlatSkol ty -> zonkTcType ty
MetaTv _ ref -> do { cts <- readMutVar ref
; case cts of
- Flexi -> return (TyVarTy tv)
+ Flexi -> zonk_kind_and_return
Indirect ty -> zonkTcType ty }
+ where
+ zonk_kind_and_return = do { z_tv <- zonkTyVarKind tv
+ ; return (TyVarTy z_tv) }
+
+zonkTyVarKind :: TyVar -> TcM TyVar
+zonkTyVarKind tv = do { kind' <- zonkTcKind (tyVarKind tv)
+ ; return (setTyVarKind tv kind') }
zonkTcTypeAndSubst :: TvSubst -> TcType -> TcM TcType
-- Zonk, and simultaneously apply a non-necessarily-idempotent substitution
zonkTcTypeAndSubst subst ty = zonkType zonk_tv ty
where
- zonk_tv tv
- = case tcTyVarDetails tv of
- SkolemTv {} -> return (TyVarTy tv)
- RuntimeUnk {} -> return (TyVarTy tv)
- FlatSkol ty -> zonkType zonk_tv ty
- MetaTv _ ref -> do { cts <- readMutVar ref
- ; case cts of
- Flexi -> zonk_flexi tv
- Indirect ty -> zonkType zonk_tv ty }
+ zonk_tv tv
+ = do { z_tv <- updateTyVarKindM zonkTcKind tv
+ ; case tcTyVarDetails tv of
+ SkolemTv {} -> return (TyVarTy z_tv)
+ RuntimeUnk {} -> return (TyVarTy z_tv)
+ FlatSkol ty -> zonkType zonk_tv ty
+ MetaTv _ ref -> do { cts <- readMutVar ref
+ ; case cts of
+ Flexi -> zonk_flexi z_tv
+ Indirect ty -> zonkType zonk_tv ty } }
zonk_flexi tv
= case lookupTyVar subst tv of
Just ty -> zonkType zonk_tv ty
@@ -517,8 +575,32 @@ zonkTcPredType = zonkTcType
are used at the end of type checking
\begin{code}
-zonkQuantifiedTyVars :: [TcTyVar] -> TcM [TcTyVar]
-zonkQuantifiedTyVars = mapM zonkQuantifiedTyVar
+defaultKindVarToStar :: TcTyVar -> TcM ()
+-- We have a meta-kind: unify it with '*'
+defaultKindVarToStar kv
+ = ASSERT ( isKiVar kv && isMetaTyVar kv )
+ writeMetaTyVar kv liftedTypeKind
+
+zonkQuantifiedTyVars :: TcTyVarSet -> TcM [TcTyVar]
+-- Precondition: a kind variable occurs before a type
+-- variable mentioning it in its kind
+zonkQuantifiedTyVars tyvars
+ = do { let (kvs, tvs) = partitionKiTyVars (varSetElems tyvars)
+ ; poly_kinds <- xoptM Opt_PolyKinds
+ ; if poly_kinds then
+ mapM zonkQuantifiedTyVar (kvs ++ tvs)
+ -- Because of the order, any kind variables
+ -- mentioned in the kinds of the type variables refer to
+ -- the now-quantified versions
+ else
+ -- In the non-PolyKinds case, default the kind variables
+ -- to *, and zonk the tyvars as usual. Notice that this
+ -- may make zonkQuantifiedTyVars return a shorter list
+ -- than it was passed, but that's ok
+ do { let (meta_kvs, skolem_kvs) = partition isMetaTyVar kvs
+ ; WARN ( not (null skolem_kvs), ppr skolem_kvs )
+ mapM_ defaultKindVarToStar meta_kvs
+ ; mapM zonkQuantifiedTyVar (skolem_kvs ++ tvs) } }
zonkQuantifiedTyVar :: TcTyVar -> TcM TcTyVar
-- The quantified type variables often include meta type variables
@@ -530,11 +612,13 @@ zonkQuantifiedTyVar :: TcTyVar -> TcM TcTyVar
-- the immutable version.
--
-- We leave skolem TyVars alone; they are immutable.
+--
+-- This function is called on both kind and type variables,
+-- but kind variables *only* if PolyKinds is on.
zonkQuantifiedTyVar tv
= ASSERT2( isTcTyVar tv, ppr tv )
case tcTyVarDetails tv of
- SkolemTv {} -> WARN( True, ppr tv ) -- Dec10: Can this really happen?
- do { kind <- zonkTcType (tyVarKind tv)
+ SkolemTv {} -> do { kind <- zonkTcKind (tyVarKind tv)
; return $ setTyVarKind tv kind }
-- It might be a skolem type variable,
-- for example from a user type signature
@@ -562,11 +646,13 @@ skolemiseUnboundMetaTyVar tv details
do { span <- getSrcSpanM -- Get the location from "here"
-- ie where we are generalising
; uniq <- newUnique -- Remove it from TcMetaTyVar unique land
- ; let final_kind = defaultKind (tyVarKind tv)
+ ; kind <- zonkTcKind (tyVarKind tv)
+ ; let final_kind = defaultKind kind
final_name = mkInternalName uniq (getOccName tv) span
final_tv = mkTcTyVar final_name final_kind details
- ; writeMetaTyVar tv (mkTyVarTy final_tv)
- ; return final_tv }
+
+ ; writeMetaTyVar tv (mkTyVarTy final_tv)
+ ; return final_tv }
\end{code}
\begin{code}
@@ -680,7 +766,7 @@ leads to problems. Consider this program from the regression test suite:
It leads to the deferral of an equality (wrapped in an implication constraint)
- forall a. (String -> String -> String) ~ a
+ forall a. () => ((String -> String -> String) ~ a)
which is propagated up to the toplevel (see TcSimplify.tcSimplifyInferCheck).
In the meantime `a' is zonked and quantified to form `evalRHS's signature.
@@ -712,6 +798,9 @@ simplifier knows how to deal with.
-- For tyvars bound at a for-all, zonkType zonks them to an immutable
-- type variable and zonks the kind too
+zonkKind :: (TcTyVar -> TcM Kind) -> TcKind -> TcM Kind
+zonkKind = zonkType
+
zonkType :: (TcTyVar -> TcM Type) -- What to do with TcTyVars
-> TcType -> TcM Type
zonkType zonk_tc_tyvar ty
@@ -733,26 +822,13 @@ zonkType zonk_tc_tyvar ty
-- The two interesting cases!
go (TyVarTy tyvar) | isTcTyVar tyvar = zonk_tc_tyvar tyvar
- | otherwise = return (TyVarTy tyvar)
+ | otherwise = TyVarTy <$> updateTyVarKindM zonkTcKind tyvar
-- Ordinary (non Tc) tyvars occur inside quantified types
go (ForAllTy tyvar ty) = ASSERT( isImmutableTyVar tyvar ) do
ty' <- go ty
- tyvar' <- return tyvar
+ tyvar' <- updateTyVarKindM zonkTcKind tyvar
return (ForAllTy tyvar' ty')
-
-mkZonkTcTyVar :: (TcTyVar -> TcM Type) -- What to do for an *mutable Flexi* var
- -> TcTyVar -> TcM TcType
-mkZonkTcTyVar unbound_var_fn tyvar
- = ASSERT( isTcTyVar tyvar )
- case tcTyVarDetails tyvar of
- SkolemTv {} -> return (TyVarTy tyvar)
- RuntimeUnk {} -> return (TyVarTy tyvar)
- FlatSkol ty -> zonkType (mkZonkTcTyVar unbound_var_fn) ty
- MetaTv _ ref -> do { cts <- readMutVar ref
- ; case cts of
- Flexi -> unbound_var_fn tyvar
- Indirect ty -> zonkType (mkZonkTcTyVar unbound_var_fn) ty }
\end{code}
@@ -764,21 +840,21 @@ mkZonkTcTyVar unbound_var_fn tyvar
%************************************************************************
\begin{code}
-readKindVar :: KindVar -> TcM (MetaDetails)
-writeKindVar :: KindVar -> TcKind -> TcM ()
-readKindVar kv = readMutVar (kindVarRef kv)
-writeKindVar kv val = writeMutVar (kindVarRef kv) (Indirect val)
+compatKindTcM :: Kind -> Kind -> TcM Bool
+compatKindTcM k1 k2
+ = do { k1' <- zonkTcKind k1
+ ; k2' <- zonkTcKind k2
+ ; return $ k1' `isSubKind` k2' || k2' `isSubKind` k1' }
+
+isSubKindTcM :: Kind -> Kind -> TcM Bool
+isSubKindTcM k1 k2
+ = do { k1' <- zonkTcKind k1
+ ; k2' <- zonkTcKind k2
+ ; return $ k1' `isSubKind` k2' }
-------------
zonkTcKind :: TcKind -> TcM TcKind
zonkTcKind k = zonkTcType k
-
--------------
-zonkTcKindToKind :: TcKind -> TcM Kind
--- When zonking a TcKind to a kind, we need to instantiate kind variables,
--- Haskell specifies that * is to be used, so we follow that.
-zonkTcKindToKind k
- = zonkType (mkZonkTcTyVar (\ _ -> return liftedTypeKind)) k
\end{code}
%************************************************************************
@@ -835,9 +911,6 @@ checkValidType ctxt ty = do
LamPatSigCtxt -> gen_rank 0
BindPatSigCtxt -> gen_rank 0
TySynCtxt _ -> gen_rank 0
- GenPatCtxt -> gen_rank 1
- -- This one is a bit of a hack
- -- See the forall-wrapping in TcClassDcl.mkGenericInstance
ExprSigCtxt -> gen_rank 1
FunSigCtxt _ -> gen_rank 1
@@ -851,8 +924,8 @@ checkValidType ctxt ty = do
SpecInstCtxt -> gen_rank 1
ThBrackCtxt -> gen_rank 1
GhciCtxt -> ArbitraryRank
- GenSigCtxt -> panic "checkValidType"
- -- Can't happen; GenSigCtxt not used for *user* sigs
+ _ -> panic "checkValidType"
+ -- Can't happen; not used for *user* sigs
actual_kind = typeKind ty
@@ -860,11 +933,10 @@ checkValidType ctxt ty = do
TySynCtxt _ -> True -- Any kind will do
ThBrackCtxt -> True -- ditto
GhciCtxt -> True -- ditto
- ResSigCtxt -> isSubOpenTypeKind actual_kind
- ExprSigCtxt -> isSubOpenTypeKind actual_kind
- GenPatCtxt -> isLiftedTypeKind actual_kind
+ ResSigCtxt -> tcIsSubOpenTypeKind actual_kind
+ ExprSigCtxt -> tcIsSubOpenTypeKind actual_kind
ForSigCtxt _ -> isLiftedTypeKind actual_kind
- _ -> isSubArgTypeKind actual_kind
+ _ -> tcIsSubArgTypeKind actual_kind
ubx_tup
| not unboxed = UT_NotOk
@@ -879,8 +951,9 @@ checkValidType ctxt ty = do
check_type rank ubx_tup ty
-- Check that the thing has kind Type, and is lifted if necessary
- -- Do this second, becuase we can't usefully take the kind of an
+ -- Do this second, because we can't usefully take the kind of an
-- ill-formed type such as (a~Int)
+ traceTc "checkValidType kind_ok ctxt" (ppr kind_ok $$ pprUserTypeCtxt ctxt)
checkTc kind_ok (kindErr actual_kind)
traceTc "checkValidType done" (ppr ty)
@@ -912,9 +985,11 @@ data UbxTupFlag = UT_Ok | UT_NotOk
-- The "Ok" version means "ok if UnboxedTuples is on"
----------------------------------------
-check_mono_type :: Rank -> Type -> TcM () -- No foralls anywhere
+check_mono_type :: Rank -> KindOrType -> TcM () -- No foralls anywhere
-- No unlifted types of any kind
check_mono_type rank ty
+ | isKind ty = return () -- IA0_NOTE: Do we need to check kinds?
+ | otherwise
= do { check_type rank UT_NotOk ty
; checkTc (not (isUnLiftedType ty)) (unliftedArgErr ty) }
@@ -996,7 +1071,7 @@ check_type rank ubx_tup ty@(TyConApp tc tys)
check_type _ _ ty = pprPanic "check_type" (ppr ty)
----------------------------------------
-check_arg_type :: Rank -> Type -> TcM ()
+check_arg_type :: Rank -> KindOrType -> TcM ()
-- The sort of type that can instantiate a type variable,
-- or be the argument of a type constructor.
-- Not an unboxed tuple, but now *can* be a forall (since impredicativity)
@@ -1015,7 +1090,9 @@ check_arg_type :: Rank -> Type -> TcM ()
-- But not in user code.
-- Anyway, they are dealt with by a special case in check_tau_type
-check_arg_type rank ty
+check_arg_type rank ty
+ | isKind ty = return () -- IA0_NOTE: Do we need to check a kind?
+ | otherwise
= do { impred <- xoptM Opt_ImpredicativeTypes
; let rank' = case rank of -- Predictive => must be monotype
MustBeMonoType -> MustBeMonoType -- Monotype, regardless
@@ -1085,39 +1162,12 @@ If we do both, we get exponential behaviour!!
%************************************************************************
\begin{code}
--- Enumerate the contexts in which a "source type", <S>, can occur
--- Eq a
--- or ?x::Int
--- or r <: {x::Int}
--- or (N a) where N is a newtype
-
-data SourceTyCtxt
- = ClassSCCtxt Name -- Superclasses of clas
- -- class <S> => C a where ...
- | SigmaCtxt -- Theta part of a normal for-all type
- -- f :: <S> => a -> a
- | DataTyCtxt Name -- Theta part of a data decl
- -- data <S> => T a = MkT a
- | TypeCtxt -- Source type in an ordinary type
- -- f :: N a -> N a
- | InstThetaCtxt -- Context of an instance decl
- -- instance <S> => C [a] where ...
-
-pprSourceTyCtxt :: SourceTyCtxt -> SDoc
-pprSourceTyCtxt (ClassSCCtxt c) = ptext (sLit "the super-classes of class") <+> quotes (ppr c)
-pprSourceTyCtxt SigmaCtxt = ptext (sLit "the context of a polymorphic type")
-pprSourceTyCtxt (DataTyCtxt tc) = ptext (sLit "the context of the data type declaration for") <+> quotes (ppr tc)
-pprSourceTyCtxt InstThetaCtxt = ptext (sLit "the context of an instance declaration")
-pprSourceTyCtxt TypeCtxt = ptext (sLit "the context of a type")
-\end{code}
-
-\begin{code}
-checkValidTheta :: SourceTyCtxt -> ThetaType -> TcM ()
+checkValidTheta :: UserTypeCtxt -> ThetaType -> TcM ()
checkValidTheta ctxt theta
= addErrCtxt (checkThetaCtxt ctxt theta) (check_valid_theta ctxt theta)
-------------------------
-check_valid_theta :: SourceTyCtxt -> [PredType] -> TcM ()
+check_valid_theta :: UserTypeCtxt -> [PredType] -> TcM ()
check_valid_theta _ []
= return ()
check_valid_theta ctxt theta = do
@@ -1128,10 +1178,10 @@ check_valid_theta ctxt theta = do
(_,dups) = removeDups cmpPred theta
-------------------------
-check_pred_ty :: DynFlags -> SourceTyCtxt -> PredType -> TcM ()
+check_pred_ty :: DynFlags -> UserTypeCtxt -> PredType -> TcM ()
check_pred_ty dflags ctxt pred = check_pred_ty' dflags ctxt (shallowPredTypePredTree pred)
-check_pred_ty' :: DynFlags -> SourceTyCtxt -> PredTree -> TcM ()
+check_pred_ty' :: DynFlags -> UserTypeCtxt -> PredTree -> TcM ()
check_pred_ty' dflags ctxt (ClassPred cls tys)
= do { -- Class predicates are valid in all contexts
; checkTc (arity == n_tys) arity_err
@@ -1207,22 +1257,55 @@ check_pred_ty' dflags ctxt (IrredPred pred)
| xopt Opt_UndecidableInstances dflags -> return ()
| otherwise -> do
-- Make sure it is OK to have an irred pred in this context
- checkTc (case ctxt of ClassSCCtxt _ -> False; InstThetaCtxt -> False; _ -> True)
+ checkTc (case ctxt of ClassSCCtxt _ -> False; InstDeclCtxt -> False; _ -> True)
(predIrredBadCtxtErr pred)
-------------------------
-check_class_pred_tys :: DynFlags -> SourceTyCtxt -> [Type] -> Bool
-check_class_pred_tys dflags ctxt tys
+check_class_pred_tys :: DynFlags -> UserTypeCtxt -> [KindOrType] -> Bool
+check_class_pred_tys dflags ctxt kts
= case ctxt of
- TypeCtxt -> True -- {-# SPECIALISE instance Eq (T Int) #-} is fine
- InstThetaCtxt -> flexible_contexts || undecidable_ok || all tcIsTyVarTy tys
+ SpecInstCtxt -> True -- {-# SPECIALISE instance Eq (T Int) #-} is fine
+ InstDeclCtxt -> flexible_contexts || undecidable_ok || all tcIsTyVarTy tys
-- Further checks on head and theta in
-- checkInstTermination
_ -> flexible_contexts || all tyvar_head tys
where
+ (_, tys) = span isKind kts -- see Note [Kind polymorphic type classes]
flexible_contexts = xopt Opt_FlexibleContexts dflags
undecidable_ok = xopt Opt_UndecidableInstances dflags
+{-
+Note [Kind polymorphic type classes]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class C f where
+ empty :: f a
+-- C :: forall k. k -> Constraint
+-- empty :: forall (a :: k). f a
+
+MultiParam:
+~~~~~~~~~~~
+
+instance C Maybe where
+ empty = Nothing
+
+The dictionary gets type [C * Maybe] even if it's not a MultiParam
+type class.
+
+Flexible:
+~~~~~~~~~
+
+data D a = D
+-- D :: forall k. k -> *
+
+instance C D where
+ empty = D
+
+The dictionary gets type [C * (D *)]. IA0_TODO it should be
+generalized actually.
+
+-}
+
-------------------------
tyvar_head :: Type -> Bool
tyvar_head ty -- Haskell 98 allows predicates of form
@@ -1345,10 +1428,10 @@ so we can take their type variables into account as part of the
\begin{code}
-checkThetaCtxt :: SourceTyCtxt -> ThetaType -> SDoc
+checkThetaCtxt :: UserTypeCtxt -> ThetaType -> SDoc
checkThetaCtxt ctxt theta
= vcat [ptext (sLit "In the context:") <+> pprTheta theta,
- ptext (sLit "While checking") <+> pprSourceTyCtxt ctxt ]
+ ptext (sLit "While checking") <+> pprUserTypeCtxt ctxt ]
eqPredTyErr, predTyVarErr, predTupleErr, predIrredErr, predIrredBadCtxtErr :: PredType -> SDoc
eqPredTyErr pred = ptext (sLit "Illegal equational constraint") <+> pprType pred
@@ -1393,20 +1476,23 @@ compiled elsewhere). In these cases, we let them go through anyway.
We can also have instances for functions: @instance Foo (a -> b) ...@.
\begin{code}
-checkValidInstHead :: Class -> [Type] -> TcM ()
-checkValidInstHead clas tys
+checkValidInstHead :: UserTypeCtxt -> Class -> [Type] -> TcM ()
+checkValidInstHead ctxt clas tys
= do { dflags <- getDOpts
- -- If GlasgowExts then check at least one isn't a type variable
- ; checkTc (xopt Opt_TypeSynonymInstances dflags ||
- all tcInstHeadTyNotSynonym tys)
+ -- Check language restrictions;
+ -- but not for SPECIALISE isntance pragmas
+ ; unless spec_inst_prag $
+ do { checkTc (xopt Opt_TypeSynonymInstances dflags ||
+ all tcInstHeadTyNotSynonym tys)
(instTypeErr pp_pred head_type_synonym_msg)
- ; checkTc (xopt Opt_FlexibleInstances dflags ||
- all tcInstHeadTyAppAllTyVars tys)
+ ; checkTc (xopt Opt_FlexibleInstances dflags ||
+ all tcInstHeadTyAppAllTyVars tys)
(instTypeErr pp_pred head_type_args_tyvars_msg)
- ; checkTc (xopt Opt_MultiParamTypeClasses dflags ||
- isSingleton tys)
- (instTypeErr pp_pred head_one_type_msg)
+ ; checkTc (xopt Opt_MultiParamTypeClasses dflags ||
+ isSingleton (dropWhile isKind tys)) -- IA0_NOTE: only count type arguments
+ (instTypeErr pp_pred head_one_type_msg) }
+
-- May not contain type family applications
; mapM_ checkTyFamFreeness tys
@@ -1419,6 +1505,8 @@ checkValidInstHead clas tys
}
where
+ spec_inst_prag = case ctxt of { SpecInstCtxt -> True; _ -> False }
+
pp_pred = pprClassPred clas tys
head_type_synonym_msg = parens (
text "All instance types must be of the form (T t1 ... tn)" $$
@@ -1471,12 +1559,12 @@ validDerivPred tv_set ty = case getClassPredTys_maybe ty of
%************************************************************************
\begin{code}
-checkValidInstance :: LHsType Name -> [TyVar] -> ThetaType
+checkValidInstance :: UserTypeCtxt -> LHsType Name -> [TyVar] -> ThetaType
-> Class -> [TcType] -> TcM ()
-checkValidInstance hs_type tyvars theta clas inst_tys
+checkValidInstance ctxt hs_type tyvars theta clas inst_tys
= setSrcSpan (getLoc hs_type) $
- do { setSrcSpan head_loc (checkValidInstHead clas inst_tys)
- ; checkValidTheta InstThetaCtxt theta
+ do { setSrcSpan head_loc (checkValidInstHead ctxt clas inst_tys)
+ ; checkValidTheta ctxt theta
; checkAmbiguity tyvars theta (tyVarsOfTypes inst_tys)
-- Check that instance inference will terminate (if we care)
@@ -1648,19 +1736,6 @@ fvType (ForAllTy tyvar ty) = filter (/= tyvar) (fvType ty)
fvTypes :: [Type] -> [TyVar]
fvTypes tys = concat (map fvType tys)
--------------------
-sizePred :: PredType -> Int
--- Size of a predicate: the number of variables and constructors
--- See Note [Paterson conditions on PredTypes]
-sizePred ty = go (classifyPredType ty)
- where
- go (ClassPred _ tys') = sizeTypes tys'
- go (IPPred {}) = 0
- go (EqPred {}) = 0
- go (TuplePred ts) = maximum (0:map sizePred ts)
- go (IrredPred ty) = sizeType ty
-
--------------------
sizeType :: Type -> Int
-- Size of a type: the number of variables and constructors
sizeType ty | Just exp_ty <- tcView ty = sizeType exp_ty
@@ -1671,7 +1746,24 @@ sizeType (AppTy fun arg) = sizeType fun + sizeType arg
sizeType (ForAllTy _ ty) = sizeType ty
sizeTypes :: [Type] -> Int
-sizeTypes xs = sum (map sizeType xs)
+-- IA0_NOTE: Avoid kinds.
+sizeTypes xs = sum (map sizeType tys)
+ where tys = filter (not . isKind) xs
+
+-- Size of a predicate
+--
+-- We are considering whether *class* constraints terminate
+-- Once we get into an implicit parameter or equality we
+-- can't get back to a class constraint, so it's safe
+-- to say "size 0". See Trac #4200.
+sizePred :: PredType -> Int
+sizePred ty = go (predTypePredTree ty)
+ where
+ go (ClassPred _ tys') = sizeTypes tys'
+ go (IPPred {}) = 0
+ go (EqPred {}) = 0
+ go (TuplePred ts) = sum (map go ts)
+ go (IrredPred ty) = sizeType ty
\end{code}
Note [Paterson conditions on PredTypes]
diff --git a/compiler/typecheck/TcPat.lhs b/compiler/typecheck/TcPat.lhs
index e99d2656fc..c9a67aa76d 100644
--- a/compiler/typecheck/TcPat.lhs
+++ b/compiler/typecheck/TcPat.lhs
@@ -672,15 +672,14 @@ tcConPat penv (L con_span con_name) pat_ty arg_pats thing_inside
; setSrcSpan con_span $ addDataConStupidTheta data_con ctxt_res_tys
; checkExistentials ex_tvs penv
- ; ex_tvs' <- tcInstSuperSkolTyVars ex_tvs
+ ; (tenv, ex_tvs') <- tcInstSuperSkolTyVarsX
+ (zipTopTvSubst univ_tvs ctxt_res_tys) ex_tvs
-- Get location from monad, not from ex_tvs
; let pat_ty' = mkTyConApp tycon ctxt_res_tys
-- pat_ty' is type of the actual constructor application
-- pat_ty' /= pat_ty iff coi /= IdCo
- tenv = zipTopTvSubst (univ_tvs ++ ex_tvs)
- (ctxt_res_tys ++ mkTyVarTys ex_tvs')
arg_tys' = substTys tenv arg_tys
; if null ex_tvs && null eq_spec && null theta
diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs
index 76d96cfd3c..5312e681c6 100644
--- a/compiler/typecheck/TcRnDriver.lhs
+++ b/compiler/typecheck/TcRnDriver.lhs
@@ -335,7 +335,7 @@ tcRnExtCore hsc_env (HsExtCore this_mod decls src_binds)
-- any mutually recursive types are done right
-- Just discard the auxiliary bindings; they are generated
-- only for Haskell source code, and should already be in Core
- (tcg_env, _aux_binds) <- tcTyAndClassDecls emptyModDetails rn_decls ;
+ tcg_env <- tcTyAndClassDecls emptyModDetails rn_decls ;
dep_files <- liftIO $ readIORef (tcg_dependent_files tcg_env) ;
setGblEnv tcg_env $ do {
@@ -359,7 +359,6 @@ tcRnExtCore hsc_env (HsExtCore this_mod decls src_binds)
mg_deps = noDependencies, -- ??
mg_exports = my_exports,
mg_tcs = tcg_tcs tcg_env,
- mg_clss = tcg_clss tcg_env,
mg_insts = tcg_insts tcg_env,
mg_fam_insts = tcg_fam_insts tcg_env,
mg_inst_env = tcg_inst_env tcg_env,
@@ -543,8 +542,8 @@ tcRnHsBootDecls decls
-- Typecheck type/class decls
; traceTc "Tc2" empty
- ; (tcg_env, aux_binds)
- <- tcTyAndClassDecls emptyModDetails tycl_decls
+ ; tcg_env <- tcTyAndClassDecls emptyModDetails tycl_decls
+ ; let aux_binds = mkRecSelBinds [tc | ATyCon tc <- nameEnvElts (tcg_type_env tcg_env)]
; setGblEnv tcg_env $ do {
-- Typecheck instance decls
@@ -751,7 +750,8 @@ checkBootTyCon tc1 tc2
= checkBootTyCon tc1 tc2 &&
eqListBy eqATDef def_ats1 def_ats2
- eqATDef (ATD tvs1 ty_pats1 ty1) (ATD tvs2 ty_pats2 ty2)
+ -- Ignore the location of the defaults
+ eqATDef (ATD tvs1 ty_pats1 ty1 _loc1) (ATD tvs2 ty_pats2 ty2 _loc2)
= eqListBy same_kind tvs1 tvs2 &&
eqListBy (eqTypeX env) ty_pats1 ty_pats2 &&
eqTypeX env ty1 ty2
@@ -892,9 +892,10 @@ tcTopSrcDecls boot_details
-- The latter come in via tycl_decls
traceTc "Tc2" empty ;
- (tcg_env, aux_binds) <- tcTyAndClassDecls boot_details tycl_decls ;
+ tcg_env <- tcTyAndClassDecls boot_details tycl_decls ;
+ let { aux_binds = mkRecSelBinds [tc | tc <- tcg_tcs tcg_env] } ;
-- If there are any errors, tcTyAndClassDecls fails here
-
+
setGblEnv tcg_env $ do {
-- Source-language instances, including derivings,
@@ -968,6 +969,7 @@ tcTopSrcDecls boot_details
, tcg_vects = tcg_vects tcg_env ++ vects
, tcg_anns = tcg_anns tcg_env ++ annotations
, tcg_fords = tcg_fords tcg_env ++ foe_decls ++ fi_decls } } ;
+
return (tcg_env', tcl_env)
}}}}}}
\end{code}
@@ -1451,7 +1453,7 @@ tcRnType hsc_env ictxt normalise rdr_type
= initTcPrintErrors hsc_env iNTERACTIVE $
setInteractiveContext hsc_env ictxt $ do {
- rn_type <- rnLHsType doc rdr_type ;
+ rn_type <- rnLHsType GHCiCtx rdr_type ;
failIfErrsM ;
-- Now kind-check the type
@@ -1467,8 +1469,6 @@ tcRnType hsc_env ictxt normalise rdr_type
return (ty', typeKind ty)
}
- where
- doc = ptext (sLit "In GHCi input")
\end{code}
@@ -1732,10 +1732,8 @@ pprTcGblEnv (TcGblEnv { tcg_type_env = type_env,
pprModGuts :: ModGuts -> SDoc
pprModGuts (ModGuts { mg_tcs = tcs
- , mg_clss = clss
, mg_rules = rules })
- = vcat [ ppr_types [] (mkTypeEnv (map ATyCon tcs
- ++ map (ATyCon . classTyCon) clss)),
+ = vcat [ ppr_types [] (mkTypeEnv (map ATyCon tcs)),
ppr_rules rules ]
ppr_types :: [Instance] -> TypeEnv -> SDoc
diff --git a/compiler/typecheck/TcRnMonad.lhs b/compiler/typecheck/TcRnMonad.lhs
index b3b5cd319c..75a80c3222 100644
--- a/compiler/typecheck/TcRnMonad.lhs
+++ b/compiler/typecheck/TcRnMonad.lhs
@@ -124,7 +124,6 @@ initTc hsc_env hsc_src keep_rn_syntax mod do_this
tcg_warns = NoWarnings,
tcg_anns = [],
tcg_tcs = [],
- tcg_clss = [],
tcg_insts = [],
tcg_fam_insts = [],
tcg_rules = [],
diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index b429d6bb80..1640edc2df 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -302,8 +302,7 @@ data TcGblEnv
tcg_imp_specs :: [LTcSpecPrag], -- ...SPECIALISE prags for imported Ids
tcg_warns :: Warnings, -- ...Warnings and deprecations
tcg_anns :: [Annotation], -- ...Annotations
- tcg_tcs :: [TyCon], -- ...TyCons
- tcg_clss :: [Class], -- ...Classes
+ tcg_tcs :: [TyCon], -- ...TyCons and Classes
tcg_insts :: [Instance], -- ...Instances
tcg_fam_insts :: [FamInst], -- ...Family instances
tcg_rules :: [LRuleDecl Id], -- ...Rules
@@ -565,8 +564,32 @@ data TcTyThing
-- for error-message purposes; it is the corresponding
-- Name in the domain of the envt
- | AThing TcKind -- Used temporarily, during kind checking, for the
- -- tycons and clases in this recursive group
+ | AThing TcKind -- Used temporarily, during kind checking, for the
+ -- tycons and clases in this recursive group
+ -- Can be a mono-kind or a poly-kind; in TcTyClsDcls see
+ -- Note [Type checking recursive type and class declarations]
+
+ | ANothing -- see Note [ANothing]
+
+{-
+Note [ANothing]
+~~~~~~~~~~~~~~~
+
+We don't want to allow promotion in a strongly connected component
+when kind checking.
+
+Consider:
+ data T f = K (f (K Any))
+
+When kind checking the `data T' declaration the local env contains the
+mappings:
+ T -> AThing <some initial kind>
+ K -> ANothing
+
+ANothing is only used for DataCons, and only used during type checking
+in tcTyClGroup.
+-}
+
instance Outputable TcTyThing where -- Debugging only
ppr (AGlobal g) = pprTyThing g
@@ -577,12 +600,14 @@ instance Outputable TcTyThing where -- Debugging only
<+> ppr (tct_level elt))
ppr (ATyVar tv _) = text "Type variable" <+> quotes (ppr tv)
ppr (AThing k) = text "AThing" <+> ppr k
+ ppr ANothing = text "ANothing"
pprTcTyThingCategory :: TcTyThing -> SDoc
pprTcTyThingCategory (AGlobal thing) = pprTyThingCategory thing
pprTcTyThingCategory (ATyVar {}) = ptext (sLit "Type variable")
pprTcTyThingCategory (ATcId {}) = ptext (sLit "Local identifier")
pprTcTyThingCategory (AThing {}) = ptext (sLit "Kinded thing")
+pprTcTyThingCategory ANothing = ptext (sLit "Opaque thing")
\end{code}
Note [Bindings with closed types]
@@ -593,7 +618,7 @@ Consider
in ...
Can we generalise 'g' under the OutsideIn algorithm? Yes,
-becuase all g's free variables are top-level; that is they themselves
+because all g's free variables are top-level; that is they themselves
have no free type variables, and it is the type variables in the
environment that makes things tricky for OutsideIn generalisation.
diff --git a/compiler/typecheck/TcRules.lhs b/compiler/typecheck/TcRules.lhs
index 9aae216ab5..f4dafcbeee 100644
--- a/compiler/typecheck/TcRules.lhs
+++ b/compiler/typecheck/TcRules.lhs
@@ -25,7 +25,6 @@ import TcExpr
import TcEnv
import Id
import Name
-import VarSet
import SrcLoc
import Outputable
import FastString
@@ -60,7 +59,7 @@ tcRule (HsRule name act hs_bndrs lhs fv_lhs rhs fv_rhs)
-- Note [Typechecking rules]
; vars <- tcRuleBndrs hs_bndrs
; let (id_bndrs, tv_bndrs) = partition isId vars
- ; (lhs', lhs_lie, rhs', rhs_lie, rule_ty)
+ ; (lhs', lhs_lie, rhs', rhs_lie, _rule_ty)
<- tcExtendTyVarEnv tv_bndrs $
tcExtendIdEnv id_bndrs $
do { ((lhs', rule_ty), lhs_lie) <- captureConstraints (tcInferRho lhs)
@@ -91,6 +90,7 @@ tcRule (HsRule name act hs_bndrs lhs fv_lhs rhs fv_rhs)
-- during zonking (see TcHsSyn.zonkRule)
; let tpl_ids = lhs_dicts ++ id_bndrs
+{-
forall_tvs = tyVarsOfTypes (rule_ty : map idType tpl_ids)
-- Now figure out what to quantify over
@@ -101,10 +101,13 @@ tcRule (HsRule name act hs_bndrs lhs fv_lhs rhs fv_rhs)
`minusVarSet` gbl_tvs
`delVarSetList` tv_bndrs
; qtvs <- zonkQuantifiedTyVars (varSetElems extra_bound_tvs)
+ ; let all_tvs = tv_bndrs ++ qtvs
+ ; (kvs, _kinds) <- kindGeneralizeKinds $ map tyVarKind all_tvs
+-}
-- The tv_bndrs are already skolems, so no need to zonk them
; return (HsRule name act
- (map (RuleBndr . noLoc) (tv_bndrs ++ qtvs ++ tpl_ids)) -- yuk
+ (map (RuleBndr . noLoc) (tv_bndrs ++ tpl_ids))
(mkHsDictLet lhs_ev_binds lhs') fv_lhs
(mkHsDictLet rhs_ev_binds rhs') fv_rhs) }
@@ -134,7 +137,3 @@ ruleCtxt :: FastString -> SDoc
ruleCtxt name = ptext (sLit "When checking the transformation rule") <+>
doubleQuotes (ftext name)
\end{code}
-
-
-
-
diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs
index cd0477297e..7d3ee73f6b 100644
--- a/compiler/typecheck/TcSMonad.lhs
+++ b/compiler/typecheck/TcSMonad.lhs
@@ -74,7 +74,7 @@ module TcSMonad (
instDFunConstraints,
newFlexiTcSTy, instFlexiTcS,
- compatKind,
+ compatKind, compatKindTcS, isSubKindTcS, unifyKindTcS,
TcsUntouchables,
isTouchableMetaTyVar,
@@ -106,6 +106,7 @@ import qualified TcRnMonad as TcM
import qualified TcMType as TcM
import qualified TcEnv as TcM
( checkWellStaged, topIdLvl, tcGetDefaultTys )
+import {-# SOURCE #-} qualified TcUnify as TcM ( unifyKindEq, mkKindErrorCtxt )
import Kind
import TcType
import DynFlags
@@ -148,6 +149,23 @@ import TrieMap
compatKind :: Kind -> Kind -> Bool
compatKind k1 k2 = k1 `isSubKind` k2 || k2 `isSubKind` k1
+compatKindTcS :: Kind -> Kind -> TcS Bool
+-- Because kind unification happens during constraint solving, we have
+-- to make sure that two kinds are zonked before we compare them.
+compatKindTcS k1 k2 = wrapTcS (TcM.compatKindTcM k1 k2)
+
+isSubKindTcS :: Kind -> Kind -> TcS Bool
+isSubKindTcS k1 k2 = wrapTcS (TcM.isSubKindTcM k1 k2)
+
+unifyKindTcS :: Type -> Type -- Context
+ -> Kind -> Kind -- Corresponding kinds
+ -> TcS Bool
+unifyKindTcS ty1 ty2 ki1 ki2
+ = wrapTcS $ TcM.addErrCtxtM ctxt $ do
+ (_errs, mb_r) <- TcM.tryTc (TcM.unifyKindEq ki1 ki2)
+ return (maybe False (const True) mb_r)
+ where ctxt = TcM.mkKindErrorCtxt ty1 ki1 ty2 ki2
+
\end{code}
%************************************************************************
diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs
index d91432e810..be29e38772 100644
--- a/compiler/typecheck/TcSimplify.lhs
+++ b/compiler/typecheck/TcSimplify.lhs
@@ -28,7 +28,6 @@ import VarSet
import VarEnv
import Coercion
import TypeRep
-
import Name
import NameEnv ( emptyNameEnv )
import Bag
@@ -211,6 +210,18 @@ Allow constraints which consist only of type variables, with no repeats.
* *
***********************************************************************************
+Note [Which variables to quantify]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Suppose the inferred type of a function is
+ T kappa (alpha:kappa) -> Int
+where alpha is a type unification variable and
+ kappa is a kind unification variable
+Then we want to quantify over *both* alpha and kappa. But notice that
+kappa appears "at top level" of the type, as well as inside the kind
+of alpha. So it should be fine to just look for the "top level"
+kind/type variables of the type, without looking transitively into the
+kinds of those type variables.
+
\begin{code}
simplifyInfer :: Bool
-> Bool -- Apply monomorphism restriction
@@ -227,8 +238,10 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
| isEmptyWC wanteds
= do { gbl_tvs <- tcGetGlobalTyVars -- Already zonked
; zonked_taus <- zonkTcTypes (map snd name_taus)
- ; let tvs_to_quantify = get_tau_tvs zonked_taus `minusVarSet` gbl_tvs
- ; qtvs <- zonkQuantifiedTyVars (varSetElems tvs_to_quantify)
+ ; let tvs_to_quantify = tyVarsOfTypes zonked_taus `minusVarSet` gbl_tvs
+ -- tvs_to_quantify can contain both kind and type vars
+ -- See Note [Which variables to quantify]
+ ; qtvs <- zonkQuantifiedTyVars tvs_to_quantify
; return (qtvs, [], False, emptyTcEvBinds) }
| otherwise
@@ -250,7 +263,7 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
-- Then split the constraints on the baisis of those tyvars
-- to avoid unnecessarily simplifying a class constraint
-- See Note [Avoid unecessary constraint simplification]
- ; let zonked_tau_tvs = get_tau_tvs zonked_taus
+ ; let zonked_tau_tvs = tyVarsOfTypes zonked_taus
proto_qtvs = growWanteds gbl_tvs zonked_wanteds $
zonked_tau_tvs `minusVarSet` gbl_tvs
(perhaps_bound, surely_free)
@@ -313,8 +326,7 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
-- they are also bound in ic_skols and we want them to be
-- tidied uniformly
- ; gloc <- getCtLoc skol_info
- ; qtvs_to_return <- zonkQuantifiedTyVars (varSetElems qtvs)
+ ; qtvs_to_return <- zonkQuantifiedTyVars qtvs
-- Step 5
-- Minimize `bound' and emit an implication
@@ -322,6 +334,7 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
; ev_binds_var <- newTcEvBinds
; mapBagM_ (\(EvBind evar etrm) -> addTcEvBind ev_binds_var evar etrm) tc_binds0
; lcl_env <- getLclTypeEnv
+ ; gloc <- getCtLoc skol_info
; let implic = Implic { ic_untch = NoUntouchables
, ic_env = lcl_env
, ic_skols = mkVarSet qtvs_to_return
@@ -342,13 +355,6 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
; return ( qtvs_to_return, minimal_bound_ev_vars
, mr_bites, TcEvBinds ev_binds_var) } }
- where
- get_tau_tvs = tyVarsOfTypes -- I think this stuff is out of date
-{-
- get_tau_tvs | isTopLevel top_lvl = tyVarsOfTypes
- | otherwise = exactTyVarsOfTypes
- -- See Note [Silly type synonym] in TcType
--}
\end{code}
diff --git a/compiler/typecheck/TcSplice.lhs b/compiler/typecheck/TcSplice.lhs
index 5939117565..54bc0cd6e2 100644
--- a/compiler/typecheck/TcSplice.lhs
+++ b/compiler/typecheck/TcSplice.lhs
@@ -364,7 +364,7 @@ tcBracket brack res_ty
; return (noLoc (HsBracketOut brack pendings)) }
tc_bracket :: ThStage -> HsBracket Name -> TcM TcType
-tc_bracket outer_stage (VarBr name) -- Note [Quoting names]
+tc_bracket outer_stage br@(VarBr _ name) -- Note [Quoting names]
= do { thing <- tcLookup name
; case thing of
AGlobal _ -> return ()
@@ -373,7 +373,7 @@ tc_bracket outer_stage (VarBr name) -- Note [Quoting names]
-> keepAliveTc id
| otherwise
-> do { checkTc (thLevel outer_stage + 1 == bind_lvl)
- (quotedNameStageErr name) }
+ (quotedNameStageErr br) }
_ -> pprPanic "th_bracket" (ppr name)
; tcMetaTy nameTyConName -- Result type is Var (not Q-monadic)
@@ -410,9 +410,9 @@ tc_bracket _ (PatBr pat)
tc_bracket _ (DecBrL _)
= panic "tc_bracket: Unexpected DecBrL"
-quotedNameStageErr :: Name -> SDoc
-quotedNameStageErr v
- = sep [ ptext (sLit "Stage error: the non-top-level quoted name") <+> ppr (VarBr v)
+quotedNameStageErr :: HsBracket Name -> SDoc
+quotedNameStageErr br
+ = sep [ ptext (sLit "Stage error: the non-top-level quoted name") <+> ppr br
, ptext (sLit "must be used at the same stage at which is is bound")]
\end{code}
@@ -536,8 +536,8 @@ kcSpliceType splice@(HsSplice name hs_expr) fvs
-- Here (h 4) :: Q Type
-- but $(h 4) :: a i.e. any type, of any kind
- ; kind <- newKindVar
- ; return (HsSpliceTy splice fvs kind, kind)
+ ; kind <- newMetaKindVar
+ ; return (HsSpliceTy splice fvs kind, kind)
}}}
kcTopSpliceType :: LHsExpr Name -> TcM (HsType Name, TcKind)
@@ -551,11 +551,11 @@ kcTopSpliceType expr
-- Run the expression
; hs_ty2 <- runMetaT zonked_q_expr
; showSplice "type" expr (ppr hs_ty2)
-
+
-- Rename it, but bale out if there are errors
-- otherwise the type checker just gives more spurious errors
- ; addErrCtxt (spliceResultDoc expr) $ do
- { let doc = ptext (sLit "In the spliced type") <+> ppr hs_ty2
+ ; addErrCtxt (spliceResultDoc expr) $ do
+ { let doc = SpliceTypeCtx hs_ty2
; hs_ty3 <- checkNoErrs (rnLHsType doc hs_ty2)
; (ty4, kind) <- kcLHsType hs_ty3
; return (unLoc ty4, kind) }}
@@ -990,7 +990,7 @@ reifyInstances th_nm th_tys
_ -> bale_out (ppr_th th_nm <+> ptext (sLit "is not a class or type constructor"))
}
where
- doc = ptext (sLit "TcSplice.reifyInstances")
+ doc = ClassInstanceCtx
bale_out msg = failWithTc msg
tc_types :: TyCon -> [TH.Type] -> TcM [Type]
@@ -1159,6 +1159,7 @@ reifyThing (ATyVar tv ty)
; return (TH.TyVarI (reifyName tv) ty2) }
reifyThing (AThing {}) = panic "reifyThing AThing"
+reifyThing ANothing = panic "reifyThing ANothing"
------------------------------
reifyAxiom :: CoAxiom -> TcM TH.Info
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index 7a56db4020..47c134a198 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -19,7 +19,7 @@ module TcTyClsDecls (
-- Functions used by TcInstDcls to check
-- data/type family instance declarations
kcDataDecl, tcConDecls, dataDeclChecks, checkValidTyCon,
- tcSynFamInstDecl, kcFamTyPats,
+ tcSynFamInstDecl, tcFamTyPats,
wrongKindOfFamily, badATErr, wrongATArgErr
) where
@@ -38,6 +38,7 @@ import TcMType
import TcType
import TysWiredIn ( unitTy )
import Type
+import Kind
import Class
import TyCon
import DataCon
@@ -73,80 +74,117 @@ import Data.List
%* *
%************************************************************************
+Note [Grouping of type and class declarations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+tcTyAndClassDecls is called on a list of `TyClGroup`s. Each group is a strongly
+connected component of mutually dependent types and classes. We kind check and
+type check each group separately to enhance kind polymorphism. Take the
+following example:
+
+ type Id a = a
+ data X = X (Id Int)
+
+If we were to kind check the two declarations together, we would give Id the
+kind * -> *, since we apply it to an Int in the definition of X. But we can do
+better than that, since Id really is kind polymorphic, and should get kind
+forall (k::BOX). k -> k. Since it does not depend on anything else, it can be
+kind-checked by itself, hence getting the most general kind. We then kind check
+X, which works fine because we then know the polymorphic kind of Id, and simply
+instantiate k to *.
+
\begin{code}
-tcTyAndClassDecls :: ModDetails
- -> [[LTyClDecl Name]] -- Mutually-recursive groups in dependency order
- -> TcM (TcGblEnv, -- Input env extended by types and classes
- -- and their implicit Ids,DataCons
- HsValBinds Name) -- Renamed bindings for record selectors
+tcTyAndClassDecls :: ModDetails
+ -> [TyClGroup Name] -- Mutually-recursive groups in dependency order
+ -> TcM (TcGblEnv) -- Input env extended by types and classes
+ -- and their implicit Ids,DataCons
-- Fails if there are any errors
-
tcTyAndClassDecls boot_details decls_s
- = checkNoErrs $ -- The code recovers internally, but if anything gave rise to
- -- an error we'd better stop now, to avoid a cascade
- do { let tyclds_s = map (filterOut (isFamInstDecl . unLoc)) decls_s
- -- Remove family instance decls altogether
- -- They are dealt with by TcInstDcls
-
- ; tyclss <- fixM $ \ rec_tyclss ->
- tcExtendRecEnv (zipRecTyClss tyclds_s rec_tyclss) $
- -- We must populate the environment with the loop-tied
- -- T's right away (even before kind checking), because
- -- the kind checker may "fault in" some type constructors
- -- that recursively mention T
-
- do { -- Kind-check in dependency order
- -- See Note [Kind checking for type and class decls]
- kc_decls <- kcTyClDecls tyclds_s
-
- -- And now build the TyCons/Classes
- ; let rec_flags = calcRecFlags boot_details rec_tyclss
- ; concatMapM (tcTyClDecl rec_flags) kc_decls }
-
- ; traceTc "tcTyAndCl" (ppr tyclss)
-
+ = checkNoErrs $ do -- The code recovers internally, but if anything gave rise to
+ -- an error we'd better stop now, to avoid a cascade
+ { let tyclds_s = map (filterOut (isFamInstDecl . unLoc)) decls_s
+ -- Remove family instance decls altogether
+ -- They are dealt with by TcInstDcls
+ ; fold_env tyclds_s } -- type check each group in dependency order folding the global env
+ where
+ fold_env :: [TyClGroup Name] -> TcM TcGblEnv
+ fold_env [] = getGblEnv
+ fold_env (tyclds:tyclds_s)
+ = do { env <- tcTyClGroup boot_details tyclds
+ ; setGblEnv env $ fold_env tyclds_s }
+ -- remaining groups are typecheck in the extended global env
+
+tcTyClGroup :: ModDetails -> TyClGroup Name -> TcM TcGblEnv
+-- Typecheck one strongly-connected component of type and class decls
+tcTyClGroup boot_details tyclds
+ = do { -- Step 1: kind-check this group and returns the final
+ -- (possibly-polymorphic) kind of each TyCon and Class
+ -- See Note [Kind checking for type and class decls]
+ names_w_poly_kinds <- kcTyClGroup tyclds
+ ; traceTc "tcTyAndCl generalized kinds" (ppr names_w_poly_kinds)
+
+ -- Step 2: type-check all groups together, returning
+ -- the final TyCons and Classes
+ ; tyclss <- fixM $ \ rec_tyclss -> do
+ { let rec_flags = calcRecFlags boot_details rec_tyclss
+
+ -- Populate environment with knot-tied ATyCon for TyCons
+ -- NB: if the decls mention any ill-staged data cons
+ -- (see Note [ANothing] in typecheck/TcRnTypes.lhs) we
+ -- will have failed already in kcTyClGroup, so no worries here
+ ; tcExtendRecEnv (zipRecTyClss tyclds rec_tyclss) $
+
+ -- Also extend the local type envt with bindings giving
+ -- the (polymorphic) kind of each knot-tied TyCon or Class
+ -- See Note [Type checking recursive type and class declarations]
+ tcExtendKindEnv names_w_poly_kinds $
+
+ -- Kind and type check declarations for this group
+ concatMapM (tcTyClDecl rec_flags) tyclds }
+
+ -- Step 3: Perform the validity chebck
+ -- We can do this now because we are done with the recursive knot
+ -- Do it before Step 4 (adding implicit things) because the latter
+ -- expects well-formed TyCons
; tcExtendGlobalEnv tyclss $ do
- { -- Perform the validity check
- -- We can do this now because we are done with the recursive knot
- traceTc "ready for validity check" empty
- ; mapM_ (addLocM checkValidTyCl) (concat tyclds_s)
- ; traceTc "done" empty
-
- -- Add the implicit things;
- -- we want them in the environment because
- -- they may be mentioned in interface files
- -- NB: All associated types and their implicit things will be added a
- -- second time here. This doesn't matter as the definitions are
- -- the same.
- ; let { implicit_things = concatMap implicitTyThings tyclss
- ; rec_sel_binds = mkRecSelBinds [tc | ATyCon tc <- tyclss]
- ; dm_ids = mkDefaultMethodIds tyclss }
-
- ; tcg_env <- tcExtendGlobalEnvImplicit implicit_things $
- tcExtendGlobalValEnv dm_ids $
- getGblEnv
-
- ; return (tcg_env, rec_sel_binds) } }
-
-zipRecTyClss :: [[LTyClDecl Name]]
+ { traceTc "Starting validity check" (ppr tyclss)
+ ; mapM_ (addLocM checkValidTyCl) tyclds
+
+ -- Step 4: Add the implicit things;
+ -- we want them in the environment because
+ -- they may be mentioned in interface files
+ ; let implicit_things = concatMap implicitTyThings tyclss
+ dm_ids = mkDefaultMethodIds tyclss
+ ; tcExtendGlobalEnvImplicit implicit_things $
+ tcExtendGlobalValEnv dm_ids $
+ getGblEnv } }
+
+zipRecTyClss :: TyClGroup Name
-> [TyThing] -- Knot-tied
-> [(Name,TyThing)]
-- Build a name-TyThing mapping for the things bound by decls
-- being careful not to look at the [TyThing]
-- The TyThings in the result list must have a visible ATyCon,
-- because typechecking types (in, say, tcTyClDecl) looks at this outer constructor
-zipRecTyClss decls_s rec_things
- = [ get decl | decls <- decls_s, L _ decl <- flattenATs decls ]
+zipRecTyClss decls rec_things
+ = [ (name, ATyCon (get name))
+ | name <- tyClsBinders decls ]
where
rec_type_env :: TypeEnv
rec_type_env = mkTypeEnv rec_things
- get :: TyClDecl Name -> (Name, TyThing)
- get decl = (name, ATyCon tc)
- where
- name = tcdName decl
- Just (ATyCon tc) = lookupTypeEnv rec_type_env name
+ get name = case lookupTypeEnv rec_type_env name of
+ Just (ATyCon tc) -> tc
+ other -> pprPanic "zipRecTyClss" (ppr name <+> ppr other)
+
+tyClsBinders :: TyClGroup Name -> [Name]
+-- Just the tycon and class binders of a group (not the data constructors)
+tyClsBinders decls
+ = concatMap get decls
+ where
+ get (L _ (ClassDecl { tcdLName = L _ n, tcdATs = ats })) = n : tyClsBinders ats
+ get (L _ d) = [tcdName d]
\end{code}
@@ -206,67 +244,90 @@ The kind of a type family is solely determinded by its kind signature;
hence, only kind signatures participate in the construction of the initial
kind environment (as constructed by `getInitialKind'). In fact, we ignore
instances of families altogether in the following. However, we need to
-include the kinds of associated families into the construction of the
+include the kinds of *associated* families into the construction of the
initial kind environment. (This is handled by `allDecls').
\begin{code}
-kcTyClDecls :: [[LTyClDecl Name]] -> TcM [LTyClDecl Name]
-kcTyClDecls [] = return []
-kcTyClDecls (decls : decls_s) = do { (tcl_env, kc_decls1) <- kcTyClDecls1 decls
- ; kc_decls2 <- setLclEnv tcl_env (kcTyClDecls decls_s)
- ; return (kc_decls1 ++ kc_decls2) }
-
-kcTyClDecls1 :: [LTyClDecl Name] -> TcM (TcLclEnv, [LTyClDecl Name])
-kcTyClDecls1 decls
- = do { -- Omit instances of type families; they are handled together
- -- with the *heads* of class instances
- ; let (syn_decls, alg_decls) = partition (isSynDecl . unLoc) decls
- alg_at_decls = flattenATs alg_decls
-
- ; mod <- getModule
- ; traceTc "tcTyAndCl" (ptext (sLit "module") <+> ppr mod $$ vcat (map ppr decls))
-
- -- Kind checking; see Note [Kind checking for type and class decls]
- ; alg_kinds <- mapM getInitialKind alg_at_decls
- ; tcExtendKindEnv alg_kinds $ do
-
- { (kc_syn_decls, tcl_env) <- kcSynDecls (calcSynCycles syn_decls)
-
+kcTyClGroup :: TyClGroup Name -> TcM [(Name,Kind)]
+-- Kind check this group, kind generalize, and return the resulting local env
+-- See Note [Kind checking for type and class decls]
+kcTyClGroup decls
+ = do { mod <- getModule
+ ; traceTc "kcTyClGroup" (ptext (sLit "module") <+> ppr mod $$ vcat (map ppr decls))
+
+ -- Kind checking;
+ -- 1. Bind kind variables for non-synonyms
+ -- 2. Kind-check synonyms, and bind kinds of those synonyms
+ -- 3. Kind-check non-synonyms
+ -- 4. Generalise the inferred kinds
+ -- See Note [Kind checking for type and class decls]
+
+ -- Step 1: Bind kind variables for non-synonyms
+ ; let (syn_decls, non_syn_decls) = partition (isSynDecl . unLoc) decls
+ ; initial_kinds <- concatMapM getInitialKinds non_syn_decls
+ ; tcExtendTcTyThingEnv initial_kinds $ do
+
+ -- Step 2: kind-check the synonyms, and extend envt
+ { tcl_env <- kcSynDecls (calcSynCycles syn_decls)
; setLclEnv tcl_env $ do
- { kc_alg_decls <- mapM (wrapLocM kcTyClDecl) alg_decls
-
- -- Kind checking done for this group, so zonk the kind variables
- -- See Note [Kind checking for type and class decls]
- ; mapM_ (zonkTcKindToKind . snd) alg_kinds
- ; return (tcl_env, kc_syn_decls ++ kc_alg_decls) } } }
+ -- Step 3: kind-check the synonyms
+ { mapM_ (wrapLocM kcTyClDecl) non_syn_decls
+
+ -- Step 4: generalisation
+ -- Kind checking done for this group
+ -- Now we have to kind generalize the flexis
+ ; mapM generalise (tyClsBinders decls) }}}
-flattenATs :: [LTyClDecl Name] -> [LTyClDecl Name]
-flattenATs decls = concatMap flatten decls
where
- flatten decl@(L _ (ClassDecl {tcdATs = ats})) = decl : ats
- flatten decl = [decl]
-
-getInitialKind :: LTyClDecl Name -> TcM (Name, TcKind)
--- Only for data type, class, and indexed type declarations
--- Get as much info as possible from the data, class, or indexed type decl,
--- so as to maximise usefulness of error messages
-getInitialKind (L _ decl)
+ generalise :: Name -> TcM (Name, Kind)
+ generalise name
+ = do { traceTc "Generalise type of" (ppr name)
+ ; thing <- tcLookup name
+ ; let kc_kind = case thing of
+ AThing k -> k
+ _ -> pprPanic "kcTyClGroup" (ppr thing)
+ ; (kvs, kc_kind') <- kindGeneralizeKind kc_kind
+ ; return (name, mkForAllTys kvs kc_kind') }
+
+getInitialKinds :: LTyClDecl Name -> TcM [(Name, TcTyThing)]
+-- Allocate a fresh kind variable for each TyCon and Class
+-- For each tycon, return (tc, AThing k)
+-- where k is the kind of tc, derived from the LHS
+-- of the definition (and probably including
+-- kind unification variables)
+-- Example: data T a b = ...
+-- return (T, kv1 -> kv2 -> *)
+--
+-- ALSO for each datacon, return (dc, ANothing)
+-- See Note [ANothing] in TcRnTypes
+
+getInitialKinds (L _ decl)
= do { arg_kinds <- mapM (mk_arg_kind . unLoc) (tyClDeclTyVars decl)
; res_kind <- mk_res_kind decl
- ; return (tcdName decl, mkArrowKinds arg_kinds res_kind) }
+ ; let main_pair = (tcdName decl, AThing (mkArrowKinds arg_kinds res_kind))
+ ; inner_pairs <- get_inner_kinds decl
+ ; return (main_pair : inner_pairs) }
where
- mk_arg_kind (UserTyVar _ _) = newKindVar
- mk_arg_kind (KindedTyVar _ kind) = return kind
+ mk_arg_kind (UserTyVar _ _) = newMetaKindVar
+ mk_arg_kind (KindedTyVar _ kind _) = scDsLHsKind kind
- mk_res_kind (TyFamily { tcdKind = Just kind }) = return kind
- mk_res_kind (TyData { tcdKindSig = Just kind }) = return kind
+ mk_res_kind (TyFamily { tcdKind = Just kind }) = scDsLHsKind kind
+ mk_res_kind (TyData { tcdKindSig = Just kind }) = scDsLHsKind kind
-- On GADT-style declarations we allow a kind signature
-- data T :: *->* where { ... }
mk_res_kind (ClassDecl {}) = return constraintKind
mk_res_kind _ = return liftedTypeKind
+ get_inner_kinds :: TyClDecl Name -> TcM [(Name,TcTyThing)]
+ get_inner_kinds (TyData { tcdCons = cons })
+ = return [ (unLoc (con_name con), ANothing) | L _ con <- cons ]
+ get_inner_kinds (ClassDecl { tcdATs = ats })
+ = concatMapM getInitialKinds ats
+ get_inner_kinds _
+ = return []
+
kcLookupKind :: Located Name -> TcM Kind
kcLookupKind nm = do
tc_ty_thing <- tcLookupLocated nm
@@ -277,55 +338,58 @@ kcLookupKind nm = do
----------------
-kcSynDecls :: [SCC (LTyClDecl Name)]
- -> TcM ([LTyClDecl Name], -- Kind-annotated decls
- TcLclEnv) -- Kind bindings
-kcSynDecls []
- = do { tcl_env <- getLclEnv; return ([], tcl_env) }
+kcSynDecls :: [SCC (LTyClDecl Name)] -> TcM (TcLclEnv) -- Kind bindings
+kcSynDecls [] = getLclEnv
kcSynDecls (group : groups)
- = do { (decl, nk) <- kcSynDecl group
- ; (decls, tcl_env) <- tcExtendKindEnv [nk] (kcSynDecls groups)
- ; return (decl:decls, tcl_env) }
-
+ = do { nk <- kcSynDecl1 group
+ ; tcExtendKindEnv [nk] (kcSynDecls groups) }
+
----------------
-kcSynDecl :: SCC (LTyClDecl Name)
- -> TcM (LTyClDecl Name, -- Kind-annotated decls
- (Name,TcKind)) -- Kind bindings
-kcSynDecl (AcyclicSCC (L loc decl))
- = tcAddDeclCtxt decl $
- kcHsTyVars (tcdTyVars decl) (\ k_tvs ->
- do { traceTc "kcd1" (ppr (unLoc (tcdLName decl)) <+> brackets (ppr (tcdTyVars decl))
+kcSynDecl1 :: SCC (LTyClDecl Name)
+ -> TcM (Name,TcKind) -- Kind bindings
+kcSynDecl1 (AcyclicSCC (L _ decl)) = kcSynDecl decl
+kcSynDecl1 (CyclicSCC decls) = do { recSynErr decls; failM }
+ -- Fail here to avoid error cascade
+ -- of out-of-scope tycons
+
+kcSynDecl :: TyClDecl Name -> TcM (Name, TcKind)
+kcSynDecl decl -- Vanilla type synonyoms only, not family instances
+ = tcAddDeclCtxt decl $
+ kcHsTyVars (tcdTyVars decl) $ \ k_tvs ->
+ do { traceTc "kcd1" (ppr (unLoc (tcdLName decl)) <+> brackets (ppr (tcdTyVars decl))
<+> brackets (ppr k_tvs))
- ; (k_rhs, rhs_kind) <- kcLHsType (tcdSynRhs decl)
- ; traceTc "kcd2" (ppr (unLoc (tcdLName decl)))
+ ; (_, rhs_kind) <- kcLHsType (tcdSynRhs decl)
+ ; traceTc "kcd2" (ppr (tcdName decl))
; let tc_kind = foldr (mkArrowKind . hsTyVarKind . unLoc) rhs_kind k_tvs
- ; return (L loc (decl { tcdTyVars = k_tvs, tcdSynRhs = k_rhs }),
- (unLoc (tcdLName decl), tc_kind)) })
-
-kcSynDecl (CyclicSCC decls)
- = do { recSynErr decls; failM } -- Fail here to avoid error cascade
- -- of out-of-scope tycons
+ ; return (tcdName decl, tc_kind) }
------------------------------------------------------------------------
-kcTyClDecl :: TyClDecl Name -> TcM (TyClDecl Name)
- -- Not used for type synonyms (see kcSynDecl)
+kcTyClDecl :: TyClDecl Name -> TcM ()
+-- This function is used solely for its side effect on kind variables
+
+kcTyClDecl (ForeignType {})
+ = return ()
+kcTyClDecl decl@(TyFamily {})
+ = kcFamilyDecl [] decl -- the empty list signals a toplevel decl
kcTyClDecl decl@(TyData {})
= ASSERT( not . isFamInstDecl $ decl ) -- must not be a family instance
- kcTyClDeclBody decl $
- kcDataDecl decl
-
-kcTyClDecl decl@(TyFamily {})
- = kcFamilyDecl [] decl -- the empty list signals a toplevel decl
+ kcTyClDeclBody decl $ \_ -> kcDataDecl decl
-kcTyClDecl decl@(ClassDecl {})
- = kcClassDecl decl
-
-kcTyClDecl decl@(ForeignType {})
- = return decl
+kcTyClDecl decl@(ClassDecl {tcdCtxt = ctxt, tcdSigs = sigs, tcdATs = ats})
+ = kcTyClDeclBody decl $ \ tvs' ->
+ do { discardResult (kcHsContext ctxt)
+ ; mapM_ (wrapLocM (kcFamilyDecl tvs')) ats
+ ; mapM_ (wrapLocM kc_sig) sigs }
+ where
+ kc_sig (TypeSig _ op_ty) = discardResult (kcHsLiftedSigType op_ty)
+ kc_sig (GenericSig _ op_ty) = discardResult (kcHsLiftedSigType op_ty)
+ kc_sig _ = return ()
-kcTyClDecl (TySynonym {}) = panic "kcTyClDecl TySynonym"
+kcTyClDecl (TySynonym {}) -- Type synonyms are never passed to kcTyClDecl
+ = panic "kcTyClDecl TySynonym"
+--------------------
kcTyClDeclBody :: TyClDecl Name
-> ([LHsTyVarBndr Name] -> TcM a)
-> TcM a
@@ -343,104 +407,84 @@ kcTyClDeclBody decl thing_inside
zipWith add_kind hs_tvs kinds
; tcExtendKindEnvTvs kinded_tvs thing_inside }
where
- add_kind (L loc (UserTyVar n _)) k = L loc (UserTyVar n k)
- add_kind (L loc (KindedTyVar n _)) k = L loc (KindedTyVar n k)
+ add_kind (L loc (UserTyVar n _)) k = L loc (UserTyVar n k)
+ add_kind (L loc (KindedTyVar n hsk _)) k = L loc (KindedTyVar n hsk k)
+-------------------
-- Kind check a data declaration, assuming that we already extended the
-- kind environment with the type variables of the left-hand side (these
-- kinded type variables are also passed as the second parameter).
--
-kcDataDecl :: TyClDecl Name -> [LHsTyVarBndr Name] -> TcM (TyClDecl Name)
-kcDataDecl decl@(TyData {tcdND = new_or_data, tcdCtxt = ctxt, tcdCons = cons})
- tvs
- = do { ctxt' <- kcHsContext ctxt
- ; cons' <- mapM (wrapLocM kc_con_decl) cons
- ; return (decl {tcdTyVars = tvs, tcdCtxt = ctxt', tcdCons = cons'}) }
- where
+kcDataDecl :: TyClDecl Name -> TcM ()
+kcDataDecl (TyData {tcdND = new_or_data, tcdCtxt = ctxt, tcdCons = cons})
+ = do { _ <- kcHsContext ctxt
+ ; _ <- mapM (wrapLocM (kcConDecl new_or_data)) cons
+ ; return () }
+kcDataDecl d = pprPanic "kcDataDecl" (ppr d)
+
+-------------------
+kcConDecl :: NewOrData -> ConDecl Name -> TcM (ConDecl Name)
-- doc comments are typechecked to Nothing here
- kc_con_decl con_decl@(ConDecl { con_name = name, con_qvars = ex_tvs
- , con_cxt = ex_ctxt, con_details = details, con_res = res })
- = addErrCtxt (dataConCtxt name) $
- kcHsTyVars ex_tvs $ \ex_tvs' -> do
- do { ex_ctxt' <- kcHsContext ex_ctxt
- ; details' <- kc_con_details details
- ; res' <- case res of
- ResTyH98 -> return ResTyH98
- ResTyGADT ty -> do { ty' <- kcHsSigType ty; return (ResTyGADT ty') }
- ; return (con_decl { con_qvars = ex_tvs', con_cxt = ex_ctxt'
- , con_details = details', con_res = res' }) }
-
- kc_con_details (PrefixCon btys)
- = do { btys' <- mapM kc_larg_ty btys
+kcConDecl new_or_data con_decl@(ConDecl { con_name = name, con_qvars = ex_tvs
+ , con_cxt = ex_ctxt, con_details = details, con_res = res })
+ = addErrCtxt (dataConCtxt name) $
+ kcHsTyVars ex_tvs $ \ex_tvs' ->
+ do { ex_ctxt' <- kcHsContext ex_ctxt
+ ; details' <- kc_con_details details
+ ; res' <- case res of
+ ResTyH98 -> return ResTyH98
+ ResTyGADT ty -> do { ty' <- kcHsSigType ty; return (ResTyGADT ty') }
+ ; return (con_decl { con_qvars = ex_tvs', con_cxt = ex_ctxt'
+ , con_details = details', con_res = res' }) }
+ where
+ kc_con_details (PrefixCon btys)
+ = do { btys' <- mapM kc_larg_ty btys
; return (PrefixCon btys') }
- kc_con_details (InfixCon bty1 bty2)
- = do { bty1' <- kc_larg_ty bty1
+ kc_con_details (InfixCon bty1 bty2)
+ = do { bty1' <- kc_larg_ty bty1
; bty2' <- kc_larg_ty bty2
; return (InfixCon bty1' bty2') }
- kc_con_details (RecCon fields)
- = do { fields' <- mapM kc_field fields
+ kc_con_details (RecCon fields)
+ = do { fields' <- mapM kc_field fields
; return (RecCon fields') }
kc_field (ConDeclField fld bty d) = do { bty' <- kc_larg_ty bty
- ; return (ConDeclField fld bty' d) }
+ ; return (ConDeclField fld bty' d) }
kc_larg_ty bty = case new_or_data of
- DataType -> kcHsSigType bty
- NewType -> kcHsLiftedSigType bty
- -- Can't allow an unlifted type for newtypes, because we're effectively
- -- going to remove the constructor while coercing it to a lifted type.
- -- And newtypes can't be bang'd
-kcDataDecl d _ = pprPanic "kcDataDecl" (ppr d)
+ DataType -> kcHsSigType bty
+ NewType -> kcHsLiftedSigType bty
+ -- Can't allow an unlifted type for newtypes, because we're effectively
+ -- going to remove the constructor while coercing it to a lifted type.
+ -- And newtypes can't be bang'd
+-------------------
-- Kind check a family declaration or type family default declaration.
--
kcFamilyDecl :: [LHsTyVarBndr Name] -- tyvars of enclosing class decl if any
- -> TyClDecl Name -> TcM (TyClDecl Name)
+ -> TyClDecl Name -> TcM ()
kcFamilyDecl classTvs decl@(TyFamily {tcdKind = kind})
= kcTyClDeclBody decl $ \tvs' ->
do { mapM_ unifyClassParmKinds tvs'
- ; return (decl {tcdTyVars = tvs',
- tcdKind = kind `mplus` Just liftedTypeKind})
- -- default result kind is '*'
- }
+ ; discardResult (scDsLHsMaybeKind kind) }
where
unifyClassParmKinds (L _ tv)
| (n,k) <- hsTyVarNameKind tv
, Just classParmKind <- lookup n classTyKinds
- = unifyKind k classParmKind
+ = let ctxt = ptext ( sLit "When kind checking family declaration")
+ <+> ppr (tcdLName decl)
+ in addErrCtxt ctxt $ unifyKind k classParmKind >> return ()
| otherwise = return ()
classTyKinds = [hsTyVarNameKind tv | L _ tv <- classTvs]
-kcFamilyDecl _ decl@(TySynonym {})
- = return decl
+kcFamilyDecl _ (TySynonym {}) = return ()
-- We don't have to do anything here for type family defaults:
-- tcClassATs will use tcAssocDecl to check them
kcFamilyDecl _ d = pprPanic "kcFamilyDecl" (ppr d)
-kcClassDecl :: TyClDecl Name -> TcM (TyClDecl Name)
-kcClassDecl decl@(ClassDecl {tcdCtxt = ctxt, tcdSigs = sigs, tcdATs = ats, tcdATDefs = atds})
- = kcTyClDeclBody decl $ \ tvs' ->
- do { ctxt' <- kcHsContext ctxt
- ; ats' <- mapM (wrapLocM (kcFamilyDecl tvs')) ats
- ; atds' <- mapM (\def_ldecl@(L loc def_decl) -> setSrcSpan loc $ tcAddDefaultAssocDeclCtxt def_decl $ wrapLocM kcFamInstDecl def_ldecl) atds
- ; sigs' <- mapM (wrapLocM kc_sig) sigs
- ; return (decl {tcdTyVars = tvs', tcdCtxt = ctxt', tcdSigs = sigs',
- tcdATs = ats', tcdATDefs = atds'}) }
- where
- kc_sig (TypeSig nm op_ty) = do { op_ty' <- kcHsLiftedSigType op_ty
- ; return (TypeSig nm op_ty') }
- kc_sig (GenericSig nm op_ty) = do { op_ty' <- kcHsLiftedSigType op_ty
- ; return (GenericSig nm op_ty') }
- kc_sig other_sig = return other_sig
-
-kcClassDecl d = pprPanic "kcClassDecl" (ppr d)
-
-kcFamInstDecl :: TyClDecl Name -> TcM (TyClDecl Name)
-kcFamInstDecl decl = kcFamTyPats decl $ \k_tvs k_typats resKind -> do
- -- kind check the right-hand side of the type equation
- k_rhs <- kcCheckLHsType (tcdSynRhs decl) (EK resKind EkUnk)
- -- ToDo: the ExpKind could be better
- return (decl { tcdTyVars = k_tvs, tcdTyPats = Just k_typats, tcdSynRhs = k_rhs })
+-------------------
+discardResult :: TcM a -> TcM ()
+discardResult a = a >> return ()
\end{code}
@@ -450,9 +494,52 @@ kcFamInstDecl decl = kcFamTyPats decl $ \k_tvs k_typats resKind -> do
%* *
%************************************************************************
+Note [Type checking recursive type and class declarations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+At this point we have completed *kind-checking* of a mutually
+recursive group of type/class decls (done in kcTyClGroup). However,
+we discarded the kind-checked types (eg RHSs of data type decls);
+note that kcTyClDecl returns (). There are two reasons:
+
+ * It's convenient, because we don't have to rebuild a
+ kinded HsDecl (a fairly elaborate type)
+
+ * It's necessary, because after kind-generalisation, the
+ TyCons/Classes may now be kind-polymorphic, and hence need
+ to be given kind arguments.
+
+Example:
+ data T f a = MkT (f a) (T f a)
+During kind-checking, we give T the kind T :: k1 -> k2 -> *
+and figure out constraints on k1, k2 etc. Then we generalise
+to get T :: forall k. (k->*) -> k -> *
+So now the (T f a) in the RHS must be elaborated to (T k f a).
+
+However, during tcTyClDecl of T (above) we will be in a recursive
+"knot". So we aren't allowed to look at the TyCon T itself; we are only
+allowed to put it (lazily) in the returned structures. But when
+kind-checking the RHS of T's decl, we *do* need to know T's kind (so
+that we can correctly elaboarate (T k f a). How can we get T's kind
+without looking at T? Delicate answer: during tcTyClDecl, we extend
+
+ *Global* env with T -> ATyCon (the (not yet built) TyCon for T)
+ *Local* env with T -> AThing (polymorphic kind of T)
+
+Then:
+
+ * During TcHsType.kcTyVar we look in the *local* env, to get the
+ known kind for T.
+
+ * But in TcHsType.ds_type (and ds_var_app in particular) we look in
+ the *global* env to get the TyCon. But we must be careful not to
+ force the TyCon or we'll get a loop.
+
+This fancy footwork (with two bindings for T) is only necesary for the
+TyCons or Classes of this recursive group. Earlier, finished groups,
+live in the global env only.
+
\begin{code}
tcTyClDecl :: (Name -> RecFlag) -> LTyClDecl Name -> TcM [TyThing]
-
tcTyClDecl calc_isrec (L loc decl)
= setSrcSpan loc $ tcAddDeclCtxt decl $
traceTc "tcTyAndCl-x" (ppr decl) >>
@@ -460,53 +547,48 @@ tcTyClDecl calc_isrec (L loc decl)
-- "type family" declarations
tcTyClDecl1 :: TyConParent -> (Name -> RecFlag) -> TyClDecl Name -> TcM [TyThing]
-tcTyClDecl1 parent _calc_isrec
- (TyFamily {tcdFlavour = TypeFamily,
- tcdLName = L _ tc_name, tcdTyVars = tvs,
- tcdKind = Just kind}) -- NB: kind at latest added during kind checking
- = tcTyVarBndrs tvs $ \ tvs' -> do
- { traceTc "type family:" (ppr tc_name)
+tcTyClDecl1 parent _calc_isrec
+ (TyFamily {tcdFlavour = TypeFamily, tcdLName = L _ tc_name, tcdTyVars = tvs})
+ = tcTyClTyVars tc_name tvs $ \ tvs' kind -> do
+ { traceTc "type family:" (ppr tc_name)
; checkFamFlag tc_name
; tycon <- buildSynTyCon tc_name tvs' SynFamilyTyCon kind parent Nothing
- ; return [ATyCon tycon]
- }
+ ; return [ATyCon tycon] }
-- "data family" declaration
-tcTyClDecl1 parent _calc_isrec
- (TyFamily {tcdFlavour = DataFamily,
- tcdLName = L _ tc_name, tcdTyVars = tvs, tcdKind = mb_kind})
- = tcTyVarBndrs tvs $ \ tvs' -> do
- { traceTc "data family:" (ppr tc_name)
+tcTyClDecl1 parent _calc_isrec
+ (TyFamily {tcdFlavour = DataFamily, tcdLName = L _ tc_name, tcdTyVars = tvs})
+ = tcTyClTyVars tc_name tvs $ \ tvs' kind -> do
+ { traceTc "data family:" (ppr tc_name)
; checkFamFlag tc_name
- ; extra_tvs <- tcDataKindSig mb_kind
+ ; extra_tvs <- tcDataKindSig kind
; let final_tvs = tvs' ++ extra_tvs -- we may not need these
- ; tycon <- buildAlgTyCon tc_name final_tvs []
- DataFamilyTyCon Recursive True
- parent Nothing
- ; return [ATyCon tycon]
- }
+ ; tycon <- buildAlgTyCon tc_name final_tvs []
+ DataFamilyTyCon Recursive True parent Nothing
+ ; return [ATyCon tycon] }
-- "type" synonym declaration
tcTyClDecl1 _parent _calc_isrec
- (TySynonym {tcdLName = L _ tc_name, tcdTyVars = tvs, tcdSynRhs = rhs_ty})
+ (TySynonym {tcdLName = L _ tc_name, tcdTyVars = tvs, tcdSynRhs = rhs_ty})
= ASSERT( isNoParent _parent )
- tcTyVarBndrs tvs $ \ tvs' -> do
- { traceTc "tcd1" (ppr tc_name)
- ; rhs_ty' <- tcHsKindedType rhs_ty
- ; tycon <- buildSynTyCon tc_name tvs' (SynonymTyCon rhs_ty')
- (typeKind rhs_ty') NoParentTyCon Nothing
+ tcTyClTyVars tc_name tvs $ \ tvs' kind -> do
+ { rhs_ty' <- tcCheckHsType rhs_ty kind
+ ; tycon <- buildSynTyCon tc_name tvs' (SynonymTyCon rhs_ty')
+ kind NoParentTyCon Nothing
; return [ATyCon tycon] }
-- "newtype" and "data"
-- NB: not used for newtype/data instances (whether associated or not)
tcTyClDecl1 _parent calc_isrec
- (TyData {tcdND = new_or_data, tcdCtxt = ctxt, tcdTyVars = tvs,
- tcdLName = L _ tc_name, tcdKindSig = mb_ksig, tcdCons = cons})
+ (TyData { tcdND = new_or_data, tcdCtxt = ctxt, tcdTyVars = tvs
+ , tcdLName = L _ tc_name, tcdKindSig = mb_ksig, tcdCons = cons })
= ASSERT( isNoParent _parent )
- tcTyVarBndrs tvs $ \ tvs' -> do
- { extra_tvs <- tcDataKindSig mb_ksig
+ let is_rec = calc_isrec tc_name
+ h98_syntax = consUseH98Syntax cons in
+ tcTyClTyVars tc_name tvs $ \ tvs' kind -> do
+ { extra_tvs <- tcDataKindSig kind
; let final_tvs = tvs' ++ extra_tvs
- ; stupid_theta <- tcHsKindedContext ctxt
+ ; stupid_theta <- tcHsKindedContext =<< kcHsContext ctxt
; kind_signatures <- xoptM Opt_KindSignatures
; existential_ok <- xoptM Opt_ExistentialQuantification
; gadt_ok <- xoptM Opt_GADTs
@@ -518,9 +600,9 @@ tcTyClDecl1 _parent calc_isrec
; dataDeclChecks tc_name new_or_data stupid_theta cons
- ; tycon <- fixM (\ tycon -> do
+ ; tycon <- fixM (\ tycon -> do
{ let res_ty = mkTyConApp tycon (mkTyVarTys final_tvs)
- ; data_cons <- tcConDecls ex_ok tycon (final_tvs, res_ty) cons
+ ; data_cons <- tcConDecls new_or_data ex_ok tycon (final_tvs, res_ty) cons
; tc_rhs <-
if null cons && is_boot -- In a hs-boot file, empty cons means
then return totallyAbstractTyConRhs -- "don't know"; hence totally Abstract
@@ -531,34 +613,34 @@ tcTyClDecl1 _parent calc_isrec
; buildAlgTyCon tc_name final_tvs stupid_theta tc_rhs is_rec
(not h98_syntax) NoParentTyCon Nothing
})
- ; return [ATyCon tycon]
- }
- where
- is_rec = calc_isrec tc_name
- h98_syntax = consUseH98Syntax cons
+ ; return [ATyCon tycon] }
-tcTyClDecl1 _parent calc_isrec
- (ClassDecl {tcdLName = L _ class_tycon_name, tcdTyVars = tvs,
- tcdCtxt = ctxt, tcdMeths = meths,
- tcdFDs = fundeps, tcdSigs = sigs, tcdATs = ats, tcdATDefs = at_defs} )
+tcTyClDecl1 _parent calc_isrec
+ (ClassDecl { tcdLName = L _ class_name, tcdTyVars = tvs
+ , tcdCtxt = ctxt, tcdMeths = meths
+ , tcdFDs = fundeps, tcdSigs = sigs, tcdATs = ats, tcdATDefs = at_defs })
= ASSERT( isNoParent _parent )
- tcTyVarBndrs tvs $ \ tvs' -> do
- { ctxt' <- tcHsKindedContext ctxt
- ; fds' <- mapM (addLocM tc_fundep) fundeps
- ; (sig_stuff, gen_dm_env) <- tcClassSigs class_tycon_name sigs meths
+ do
+ { (tvs', ctxt', fds', sig_stuff, gen_dm_env)
+ <- tcTyClTyVars class_name tvs $ \ tvs' kind -> do
+ { MASSERT( isConstraintKind kind )
+ ; ctxt' <- tcHsKindedContext =<< kcHsContext ctxt
+ ; fds' <- mapM (addLocM tc_fundep) fundeps
+ ; (sig_stuff, gen_dm_env) <- tcClassSigs class_name sigs meths
+ ; return (tvs', ctxt', fds', sig_stuff, gen_dm_env) }
; clas <- fixM $ \ clas -> do
{ let -- This little knot is just so we can get
-- hold of the name of the class TyCon, which we
-- need to look up its recursiveness
tycon_name = tyConName (classTyCon clas)
tc_isrec = calc_isrec tycon_name
-
- ; at_stuff <- tcClassATs clas tvs' ats at_defs
+
+ ; at_stuff <- tcClassATs class_name (AssocFamilyTyCon clas) ats at_defs
-- NB: 'ats' only contains "type family" and "data family" declarations
-- and 'at_defs' only contains associated-type defaults
-
+
; buildClass False {- Must include unfoldings for selectors -}
- class_tycon_name tvs' ctxt' fds' at_stuff
+ class_name tvs' ctxt' fds' at_stuff
sig_stuff tc_isrec }
; let gen_dm_ids = [ AnId (mkExportedLocalId gen_dm_name gen_dm_ty)
@@ -583,8 +665,6 @@ tcTyClDecl1 _parent calc_isrec
tcTyClDecl1 _ _
(ForeignType {tcdLName = L _ tc_name, tcdExtName = tc_ext_name})
= return [ATyCon (mkForeignTyCon tc_name tc_ext_name liftedTypeKind 0)]
-
-tcTyClDecl1 _ _ d = pprPanic "tcTyClDecl1" (ppr d)
\end{code}
%************************************************************************
@@ -594,24 +674,31 @@ tcTyClDecl1 _ _ d = pprPanic "tcTyClDecl1" (ppr d)
%* *
%************************************************************************
-Example: class C a where
+Note [Associated type defaults]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following is an example of associated type defaults:
+ class C a where
data D a
type F a b :: *
type F a Z = [a] -- Default
type F a (S n) = F a n -- Default
-We can get default defns only for type families, not data families
-
+Note that:
+ - We can have more than one default definition for a single associated type,
+ as long as they do not overlap (same rules as for instances)
+ - We can get default definitions only for type families, not data families
+
\begin{code}
-tcClassATs :: Class -- The class
- -> [TyVar] -- Class type variables (can't look them up in class b/c its knot-tied)
+tcClassATs :: Name -- The class name (not knot-tied)
+ -> TyConParent -- The class parent of this associated type
-> [LTyClDecl Name] -- Associated types. All FamTyCon
-> [LTyClDecl Name] -- Associated type defaults. All SynTyCon
-> TcM [ClassATItem]
-tcClassATs clas clas_tvs ats at_defs
+tcClassATs class_name parent ats at_defs
= do { -- Complain about associated type defaults for non associated-types
- sequence_ [ failWithTc (badATErr clas n)
+ sequence_ [ failWithTc (badATErr class_name n)
| n <- map (tcdName . unLoc) at_defs
, not (n `elemNameSet` at_names) ]
; mapM tc_at ats }
@@ -623,57 +710,41 @@ tcClassATs clas clas_tvs ats at_defs
at_defs_map = foldr (\at_def nenv -> extendNameEnv_C (++) nenv (tcdName (unLoc at_def)) [at_def])
emptyNameEnv at_defs
- tc_at at = do { [ATyCon fam_tc] <- addLocM (tcTyClDecl1 (AssocFamilyTyCon clas) (const Recursive)) at
- ; atd <- mapM (tcDefaultAssocDecl fam_tc clas_tvs)
- (lookupNameEnv at_defs_map (tyConName fam_tc) `orElse` [])
+ tc_at at = do { [ATyCon fam_tc] <- addLocM (tcTyClDecl1 parent
+ (const Recursive)) at
+ ; let at_defs = lookupNameEnv at_defs_map (tcdName (unLoc at))
+ `orElse` []
+ ; atd <- mapM (tcDefaultAssocDecl fam_tc) at_defs
; return (fam_tc, atd) }
-------------------------
tcDefaultAssocDecl :: TyCon -- ^ Family TyCon
- -> [TyVar] -- ^ TyVars of associated type's class
-> LTyClDecl Name -- ^ RHS
-> TcM ATDefault -- ^ Type checked RHS and free TyVars
-tcDefaultAssocDecl fam_tc clas_tvs (L loc decl)
+tcDefaultAssocDecl fam_tc (L loc decl)
= setSrcSpan loc $
- tcAddDefaultAssocDeclCtxt decl $
+ tcAddDefaultAssocDeclCtxt (tcdName decl) $
do { traceTc "tcDefaultAssocDecl" (ppr decl)
; (at_tvs, at_tys, at_rhs) <- tcSynFamInstDecl fam_tc decl
-
- -- See Note [Checking consistent instantiation]
- -- We only want to check this on the *class* TyVars,
- -- not the *family* TyVars (there may be more of these)
- ; zipWithM_ check_arg (tyConTyVars fam_tc) at_tys
-
- ; return (ATD at_tvs at_tys at_rhs) }
- where
- check_arg fam_tc_tv at_ty
- = checkTc (not (fam_tc_tv `elem` clas_tvs) || mkTyVarTy fam_tc_tv `eqType` at_ty)
- (wrongATArgErr at_ty (mkTyVarTy fam_tc_tv))
-
+ ; return (ATD at_tvs at_tys at_rhs loc) }
+-- We check for well-formedness and validity later, in checkValidClass
-------------------------
+
tcSynFamInstDecl :: TyCon -> TyClDecl Name -> TcM ([TyVar], [Type], Type)
-tcSynFamInstDecl fam_tc (decl@TySynonym {})
- = do { -- check that the family declaration is for a synonym
- checkTc (isSynTyCon fam_tc) (wrongKindOfFamily fam_tc)
+tcSynFamInstDecl fam_tc (TySynonym { tcdTyVars = tvs, tcdTyPats = Just pats
+ , tcdSynRhs = rhs })
+ = do { checkTc (isSynTyCon fam_tc) (wrongKindOfFamily fam_tc)
- -- we need the exact same number of type parameters as the family
- -- declaration
- ; let famArity = tyConArity fam_tc
- Just k_typats = tcdTyPats decl
- ; checkTc (length k_typats == famArity) $
- wrongNumberOfParmsErr famArity
+ ; let kc_rhs rhs kind = kcCheckLHsType rhs (EK kind EkUnk)
- -- type check type equation
- ; tcTyVarBndrs (tcdTyVars decl) $ \t_tvs -> do -- turn kinded into proper tyvars
- { t_typats <- mapM tcHsKindedType k_typats
- ; t_rhs <- tcHsKindedType (tcdSynRhs decl)
+ ; tcFamTyPats fam_tc tvs pats (kc_rhs rhs)
+ $ \tvs' pats' res_kind -> do
- -- NB: we don't check well-formedness of the instance here because we call
- -- this function from within the TcTyClsDecls fixpoint. The callers must do
- -- the check.
+ { rhs' <- kc_rhs rhs res_kind
+ ; rhs'' <- tcHsKindedType rhs'
- ; return (t_tvs, t_typats, t_rhs) }}
+ ; return (tvs', pats', rhs'') } }
tcSynFamInstDecl _ decl = pprPanic "tcSynFamInstDecl" (ppr decl)
@@ -684,33 +755,83 @@ tcSynFamInstDecl _ decl = pprPanic "tcSynFamInstDecl" (ppr decl)
-- not check whether there is a pattern for each type index; the latter
-- check is only required for type synonym instances.
-kcFamTyPats :: TyClDecl Name
- -> ([LHsTyVarBndr Name] -> [LHsType Name] -> TcKind -> TcM a)
- -- ^^kinded tvs ^^kinded ty pats ^^res kind
+-----------------
+tcFamTyPats :: TyCon
+ -> [LHsTyVarBndr Name] -> [LHsType Name]
+ -> (TcKind -> TcM any) -- Kind checker for RHS
+ -- result is ignored
+ -> ([KindVar] -> [TcKind] -> Kind -> TcM a)
-> TcM a
-kcFamTyPats decl thing_inside
- = kcHsTyVars (tcdTyVars decl) $ \tvs ->
- do { fam_tc_kind <- kcLookupKind (tcdLName decl)
-
- -- First, check that the shape of the kind implied by the
- -- instance syntax matches that of the corresponding family
- ; let hs_typats = fromJust $ tcdTyPats decl
- ; pat_kinds <- mapM (\_ -> newKindVar) hs_typats
- ; res_kind <- newKindVar
- ; checkExpectedKind (tcdLName decl) fam_tc_kind (EK (mkArrowKinds pat_kinds res_kind) EkUnk)
- -- TODO: better expected kind error?
-
- -- Next, ensure that the types in given patterns have the right kind
- ; typats <- zipWithM kcCheckLHsType hs_typats
- [ EK kind (EkArg (ppr (tcdLName decl)) n)
- | (kind,n) <- pat_kinds `zip` [1..]]
-
- -- It is the responsibliity of the thing_inside to check that the instance
- -- RHS has a kind matching that implied by the family
- ; thing_inside tvs typats res_kind
+-- Check the type patterns of a type or data family instance
+-- type instance F <pat1> <pat2> = <type>
+-- The 'tyvars' are the free type variables of pats
+--
+-- NB: The family instance declaration may be an associated one,
+-- nested inside an instance decl, thus
+-- instance C [a] where
+-- type F [a] = ...
+-- In that case, the type variable 'a' will *already be in scope*
+-- (and, if C is poly-kinded, so will its kind parameter).
+
+tcFamTyPats fam_tc tyvars pats kind_checker thing_inside
+ = kcHsTyVars tyvars $ \tvs ->
+ do { let (fam_kvs, body) = splitForAllTys (tyConKind fam_tc)
+
+ -- A family instance must have exactly the same number of type
+ -- parameters as the family declaration. You can't write
+ -- type family F a :: * -> *
+ -- type instance F Int y = y
+ -- because then the type (F Int) would be like (\y.y)
+ ; let fam_arity = tyConArity fam_tc - length fam_kvs
+ ; checkTc (length pats == fam_arity) $
+ wrongNumberOfParmsErr fam_arity
+
+ -- Instantiate with meta kind vars
+ ; fam_arg_kinds <- mapM (const newMetaKindVar) fam_kvs
+ ; let body' = substKiWith fam_kvs fam_arg_kinds body
+ (kinds, resKind) = splitKindFunTysN fam_arity body'
+ ; typats <- zipWithM kcCheckLHsType pats
+ [ EK kind (EkArg (ppr fam_tc) n)
+ | (kind,n) <- kinds `zip` [1..]]
+
+ -- Kind check the "thing inside"; this just works by
+ -- side-effecting any kind unification variables
+ ; _ <- kind_checker resKind
+
+ -- Type check indexed data type declaration
+ -- We kind generalize the kind patterns since they contain
+ -- all the meta kind variables
+ -- See Note [Quantifying over family patterns]
+ ; tcTyVarBndrsKindGen tvs $ \tvs' -> do {
+
+ ; (t_kvs, fam_arg_kinds') <- kindGeneralizeKinds fam_arg_kinds
+ ; k_typats <- mapM tcHsKindedType typats
+
+ ; thing_inside (t_kvs ++ tvs') (fam_arg_kinds' ++ k_typats) resKind }
}
\end{code}
+Note [Quantifying over family patterns]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We need to quantify over two different lots of kind variables:
+
+First, the ones that come from tcTyVarBndrsKindGen, as usual
+ data family Dist a
+
+ -- Proxy :: forall k. k -> *
+ data instance Dist (Proxy a) = DP
+ -- Generates data DistProxy = DP
+ -- ax8 k (a::k) :: Dist * (Proxy k a) ~ DistProxy k a
+ -- The 'k' comes from the tcTyVarBndrsKindGen (a::k)
+
+Second, the ones that come from the kind argument of the type family
+which we pick up using kindGeneralizeKinds:
+ -- Any :: forall k. k
+ data instance Dist Any = DA
+ -- Generates data DistAny k = DA
+ -- ax7 k :: Dist k (Any k) ~ DistAny k
+ -- The 'k' comes from kindGeneralizeKinds (Any k)
+
Note [Associated type instances]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We allow this:
@@ -779,29 +900,36 @@ dataDeclChecks tc_name new_or_data stupid_theta cons
(emptyConDeclsErr tc_name) }
-----------------------------------
-tcConDecls :: Bool -> TyCon -> ([TyVar], Type)
+tcConDecls :: NewOrData -> Bool -> TyCon -> ([TyVar], Type)
-> [LConDecl Name] -> TcM [DataCon]
-tcConDecls ex_ok rep_tycon res_tmpl cons
- = mapM (addLocM (tcConDecl ex_ok rep_tycon res_tmpl)) cons
+tcConDecls new_or_data ex_ok rep_tycon res_tmpl cons
+ = mapM (addLocM (tcConDecl new_or_data ex_ok rep_tycon res_tmpl)) cons
-tcConDecl :: Bool -- True <=> -XExistentialQuantificaton or -XGADTs
+tcConDecl :: NewOrData
+ -> Bool -- True <=> -XExistentialQuantificaton or -XGADTs
-> TyCon -- Representation tycon
-> ([TyVar], Type) -- Return type template (with its template tyvars)
-> ConDecl Name
-> TcM DataCon
-tcConDecl existential_ok rep_tycon res_tmpl -- Data types
- con@(ConDecl {con_name = name, con_qvars = tvs, con_cxt = ctxt
- , con_details = details, con_res = res_ty })
- = addErrCtxt (dataConCtxt name) $
- tcTyVarBndrs tvs $ \ tvs' -> do
+tcConDecl new_or_data existential_ok rep_tycon res_tmpl -- Data types
+ con@(ConDecl {con_name = name})
+ = do
+ { ConDecl { con_qvars = tvs, con_cxt = ctxt
+ , con_details = details, con_res = res_ty }
+ <- kcConDecl new_or_data con
+ ; addErrCtxt (dataConCtxt name) $
+ tcTyVarBndrsKindGen tvs $ \ tvs' -> do
{ ctxt' <- tcHsKindedContext ctxt
; checkTc (existential_ok || conRepresentibleWithH98Syntax con)
(badExistential name)
+ ; traceTc "tcConDecl 1" (ppr con)
; (univ_tvs, ex_tvs, eq_preds, res_ty') <- tcResultType res_tmpl tvs' res_ty
- ; let
+ ; let
tc_datacon is_infix field_lbls btys
= do { (arg_tys, stricts) <- mapAndUnzipM tcConArg btys
+ ; traceTc "tcConDecl 3" (ppr name)
+
; buildDataCon (unLoc name) is_infix
stricts field_lbls
univ_tvs ex_tvs eq_preds ctxt' arg_tys
@@ -810,6 +938,7 @@ tcConDecl existential_ok rep_tycon res_tmpl -- Data types
-- constructor type signature into the data constructor;
-- that way checkValidDataCon can complain if it's wrong.
+ ; traceTc "tcConDecl 2" (ppr name)
; case details of
PrefixCon btys -> tc_datacon False [] btys
InfixCon bty1 bty2 -> tc_datacon True [] [bty1,bty2]
@@ -817,7 +946,7 @@ tcConDecl existential_ok rep_tycon res_tmpl -- Data types
where
field_names = map (unLoc . cd_fld_name) fields
btys = map cd_fld_type fields
- }
+ } }
-- Example
-- data instance T (b,c) where
@@ -838,7 +967,7 @@ tcResultType :: ([TyVar], Type) -- Template for result type; e.g.
[(TyVar,Type)], -- Equality predicates
Type) -- Typechecked return type
-- We don't check that the TyCon given in the ResTy is
- -- the same as the parent tycon, becuase we are in the middle
+ -- the same as the parent tycon, because we are in the middle
-- of a recursive knot; so it's postponed until checkValidDataCon
tcResultType (tmpl_tvs, res_ty) dc_tvs ResTyH98
@@ -859,6 +988,11 @@ tcResultType (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
-- So we return ([a,b,z], [x,y], [a~(x,y),b~z], T [(x,y)] z z)
= do { res_ty' <- tcHsKindedType res_ty
; let Just subst = tcMatchTy (mkVarSet tmpl_tvs) res_tmpl res_ty'
+ -- This 'Just' pattern is sure to match, because if not
+ -- checkValidDataCon will complain first. The 'subst'
+ -- should not be looked at until after checkValidDataCon
+ -- We can't check eagerly because we are in a "knot" in
+ -- which 'tycon' is not yet fully defined
-- /Lazily/ figure out the univ_tvs etc
-- Each univ_tv is either a dc_tv or a tmpl_tv
@@ -868,7 +1002,9 @@ tcResultType (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
= case tcGetTyVar_maybe ty of
Just tv | not (tv `elem` univs)
-> (tv:univs, eqs)
- _other -> (tmpl:univs, (tmpl,ty):eqs)
+ _other -> (new_tmpl:univs, (new_tmpl,ty):eqs)
+ where -- see Note [Substitution in template variables kinds]
+ new_tmpl = updateTyVarKind (substTy subst) tmpl
| otherwise = pprPanic "tcResultType" (ppr res_ty)
ex_tvs = dc_tvs `minusList` univ_tvs
@@ -886,6 +1022,44 @@ tcResultType (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
name = tyVarName tv
(env', occ') = tidyOccName env (getOccName name)
+{-
+Note [Substitution in template variables kinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+data List a = Nil | Cons a (List a)
+data SList s as where
+ SNil :: SList s Nil
+
+We call tcResultType with
+ tmpl_tvs = [(k :: BOX), (s :: k -> *), (as :: List k)]
+ res_tmpl = SList k s as
+ res_ty = ResTyGADT (SList k1 (s1 :: k1 -> *) (Nil k1))
+
+We get subst:
+ k -> k1
+ s -> s1
+ as -> Nil k1
+
+Now we want to find out the universal variables and the equivalences
+between some of them and types (GADT).
+
+In this example, k and s are mapped to exactly variables which are not
+already present in the universal set, so we just add them without any
+coercion.
+
+But 'as' is mapped to 'Nil k1', so we add 'as' to the universal set,
+and add the equivalence with 'Nil k1' in 'eqs'.
+
+The problem is that with kind polymorphism, as's kind may now contain
+kind variables, and we have to apply the template substitution to it,
+which is why we create new_tmpl.
+
+The template substitution only maps kind variables to kind variables,
+since GADTs are not kind indexed.
+
+-}
+
+
consUseH98Syntax :: [LConDecl a] -> Bool
consUseH98Syntax (L _ (ConDecl { con_res = ResTyGADT _ }) : _) = False
consUseH98Syntax _ = True
@@ -909,7 +1083,9 @@ conRepresentibleWithH98Syntax
-------------------
tcConArg :: LHsType Name -> TcM (TcType, HsBang)
tcConArg bty
- = do { arg_ty <- tcHsBangType bty
+ = do { traceTc "tcConArg 1" (ppr bty)
+ ; arg_ty <- tcHsBangType bty
+ ; traceTc "tcConArg 2" (ppr bty)
; strict_mark <- chooseBoxingStrategy arg_ty (getBangStrictness bty)
; return (arg_ty, strict_mark) }
@@ -926,6 +1102,7 @@ chooseBoxingStrategy arg_ty bang
HsStrict -> do { unbox_strict <- doptM Opt_UnboxStrictFields
; if unbox_strict then return (can_unbox HsStrict arg_ty)
else return HsStrict }
+ HsNoUnpack -> return HsStrict
HsUnpack -> do { omit_prags <- doptM Opt_OmitInterfacePragmas
-- Do not respect UNPACK pragmas if OmitInterfacePragmas is on
-- See Trac #5252: unpacking means we must not conceal the
@@ -1002,10 +1179,15 @@ checkValidTyCl :: TyClDecl Name -> TcM ()
-- only so that we can add a nice context with tcAddDeclCtxt
checkValidTyCl decl
= tcAddDeclCtxt decl $
- do { thing <- tcLookupLocatedGlobal (tcdLName decl)
- ; traceTc "Validity of" (ppr thing)
+ do { traceTc "Validity of 1" (ppr decl)
+ ; env <- getGblEnv
+ ; traceTc "Validity of 1a" (ppr (tcg_type_env env))
+ ; thing <- tcLookupLocatedGlobal (tcdLName decl)
+ ; traceTc "Validity of 2" (ppr decl)
+ ; traceTc "Validity of" (ppr thing)
; case thing of
ATyCon tc -> do
+ traceTc " of kind" (ppr (tyConKind tc))
checkValidTyCon tc
case decl of
ClassDecl { tcdATs = ats } -> mapM_ (addLocM checkValidTyCl) ats
@@ -1041,14 +1223,16 @@ checkValidTyCon tc
SynFamilyTyCon {} -> return ()
SynonymTyCon ty -> checkValidType syn_ctxt ty
| otherwise
- = do -- Check the context on the data decl
- checkValidTheta (DataTyCtxt name) (tyConStupidTheta tc)
+ = do { -- Check the context on the data decl
+ ; traceTc "cvtc1" (ppr tc)
+ ; checkValidTheta (DataTyCtxt name) (tyConStupidTheta tc)
-- Check arg types of data constructors
- mapM_ (checkValidDataCon tc) data_cons
+ ; traceTc "cvtc2" (ppr tc)
+ ; mapM_ (checkValidDataCon tc) data_cons
-- Check that fields with the same name share a type
- mapM_ check_fields groups
+ ; mapM_ check_fields groups }
where
syn_ctxt = TySynCtxt name
@@ -1117,12 +1301,15 @@ checkValidDataCon tc con
res_ty_tmpl
actual_res_ty))
(badDataConTyCon con res_ty_tmpl actual_res_ty)
+ -- IA0_TODO: we should also check that kind variables
+ -- are only instantiated with kind variables
; checkValidMonoType (dataConOrigResTy con)
-- Disallow MkT :: T (forall a. a->a)
-- Reason: it's really the argument of an equality constraint
; checkValidType ctxt (dataConUserType con)
; when (isNewTyCon tc) (checkNewDataCon con)
; mapM_ check_bang (dataConStrictMarks con `zip` [1..])
+ ; traceTc "Done validity of data con" (ppr con <+> ppr (dataConRepType con))
}
where
ctxt = ConArgCtxt (dataConName con)
@@ -1170,8 +1357,9 @@ checkValidClass cls
-- Check the class operations
; mapM_ (check_op constrained_class_methods) op_stuff
- -- Check the associated type defaults are well-formed
- ; mapM_ check_at at_stuff
+ -- Check the associated type defaults are well-formed and instantiated
+ -- See Note [Checking consistent instantiation]
+ ; mapM_ check_at_defs at_stuff
-- Check that if the class has generic methods, then the
-- class has only one parameter. We can't do generic
@@ -1180,17 +1368,17 @@ checkValidClass cls
}
where
(tyvars, fundeps, theta, _, at_stuff, op_stuff) = classExtraBigSig cls
- unary = isSingleton tyvars
+ unary = isSingleton (snd (splitKiTyVars tyvars)) -- IA0_NOTE: only count type arguments
no_generics = null [() | (_, (GenDefMeth _)) <- op_stuff]
check_op constrained_class_methods (sel_id, dm)
= addErrCtxt (classOpCtxt sel_id tau) $ do
- { checkValidTheta SigmaCtxt (tail theta)
+ { checkValidTheta ctxt (tail theta)
-- The 'tail' removes the initial (C a) from the
-- class itself, leaving just the method type
; traceTc "class op type" (ppr op_ty <+> ppr tau)
- ; checkValidType (FunSigCtxt op_name) tau
+ ; checkValidType ctxt tau
-- Check that the type mentions at least one of
-- the class type variables...or at least one reachable
@@ -1208,6 +1396,7 @@ checkValidClass cls
_ -> return ()
}
where
+ ctxt = FunSigCtxt op_name
op_name = idName sel_id
op_ty = idType sel_id
(_,theta1,tau1) = tcSplitSigmaTy op_ty
@@ -1221,8 +1410,21 @@ checkValidClass cls
-- in the context of a for-all must mention at least one quantified
-- type variable. What a mess!
- check_at (_fam_tc, defs)
- = mapM_ (\(ATD _tvs pats rhs) -> checkValidFamInst pats rhs) defs
+ check_at_defs (fam_tc, defs)
+ = do mapM_ (\(ATD _tvs pats rhs _loc) -> checkValidFamInst pats rhs) defs
+ tcAddDefaultAssocDeclCtxt (tyConName fam_tc) $
+ mapM_ (check_loc_at_def fam_tc) defs
+
+ check_loc_at_def fam_tc (ATD _tvs pats _rhs loc)
+ -- Set the location for each of the default declarations
+ = setSrcSpan loc $ zipWithM_ check_arg (tyConTyVars fam_tc) pats
+
+ -- We only want to check this on the *class* TyVars,
+ -- not the *family* TyVars (there may be more of these)
+ check_arg fam_tc_tv at_ty
+ = checkTc ( not (fam_tc_tv `elem` tyvars)
+ || mkTyVarTy fam_tc_tv `eqType` at_ty)
+ (wrongATArgErr at_ty (mkTyVarTy fam_tc_tv))
checkFamFlag :: Name -> TcM ()
-- Check that we don't use families without -XTypeFamilies
@@ -1304,7 +1506,8 @@ mkRecSelBind (tycon, sel_name)
is_naughty = not (tyVarsOfType field_ty `subVarSet` data_tvs)
(field_tvs, field_theta, field_tau) = tcSplitSigmaTy field_ty
sel_ty | is_naughty = unitTy -- See Note [Naughty record selectors]
- | otherwise = mkForAllTys (varSetElems data_tvs ++ field_tvs) $
+ | otherwise = mkForAllTys (varSetElemsKvsFirst $
+ data_tvs `extendVarSetList` field_tvs) $
mkPhiTy (dataConStupidTheta con1) $ -- Urgh!
mkPhiTy field_theta $ -- Urgh!
mkFunTy data_ty field_tau
@@ -1446,12 +1649,12 @@ gotten by appying the eq_spec to the univ_tvs of the data con.
%************************************************************************
\begin{code}
-tcAddDefaultAssocDeclCtxt :: TyClDecl Name -> TcM a -> TcM a
-tcAddDefaultAssocDeclCtxt decl thing_inside
+tcAddDefaultAssocDeclCtxt :: Name -> TcM a -> TcM a
+tcAddDefaultAssocDeclCtxt name thing_inside
= addErrCtxt ctxt thing_inside
where
ctxt = hsep [ptext (sLit "In the type synonym instance default declaration for"),
- quotes (ppr (tcdName decl))]
+ quotes (ppr name)]
resultTypeMisMatch :: Name -> DataCon -> DataCon -> SDoc
resultTypeMisMatch field_name con1 con2
@@ -1521,7 +1724,7 @@ badDataConTyCon data_con res_ty_tmpl actual_res_ty
ptext (sLit "returns type") <+> quotes (ppr actual_res_ty))
2 (ptext (sLit "instead of an instance of its parent type") <+> quotes (ppr res_ty_tmpl))
-badATErr :: Outputable a => a -> Name -> SDoc
+badATErr :: Name -> Name -> SDoc
badATErr clas op
= hsep [ptext (sLit "Class"), quotes (ppr clas),
ptext (sLit "does not have an associated type"), quotes (ppr op)]
@@ -1583,7 +1786,12 @@ wrongATArgErr ty instTy =
, ptext (sLit "Found") <+> quotes (ppr ty)
<+> ptext (sLit "but expected") <+> quotes (ppr instTy)
]
-
+{-
+tooManyParmsErr :: Name -> SDoc
+tooManyParmsErr tc_name
+ = ptext (sLit "Family instance has too many parameters:") <+>
+ quotes (ppr tc_name)
+-}
wrongNumberOfParmsErr :: Arity -> SDoc
wrongNumberOfParmsErr exp_arity
= ptext (sLit "Number of parameters must match family declaration; expected")
diff --git a/compiler/typecheck/TcType.lhs b/compiler/typecheck/TcType.lhs
index cfbd4447f3..018655b04d 100644
--- a/compiler/typecheck/TcType.lhs
+++ b/compiler/typecheck/TcType.lhs
@@ -87,6 +87,7 @@ module TcType (
-- * Tidying type related things up for printing
tidyType, tidyTypes,
tidyOpenType, tidyOpenTypes,
+ tidyOpenKind,
tidyTyVarBndr, tidyFreeTyVars,
tidyOpenTyVar, tidyOpenTyVars,
tidyTopType,
@@ -117,7 +118,7 @@ module TcType (
openTypeKind, constraintKind, mkArrowKind, mkArrowKinds,
isLiftedTypeKind, isUnliftedTypeKind, isSubOpenTypeKind,
isSubArgTypeKind, isSubKind, splitKindFunTys, defaultKind,
- kindVarRef, mkKindVar,
+ mkMetaKindVar,
--------------------------------
-- Rexported from Type
@@ -346,16 +347,15 @@ data UserTypeCtxt
| ExprSigCtxt -- Expression type signature
| ConArgCtxt Name -- Data constructor argument
| TySynCtxt Name -- RHS of a type synonym decl
- | GenPatCtxt -- Pattern in generic decl
- -- f{| a+b |} (Inl x) = ...
| LamPatSigCtxt -- Type sig in lambda pattern
-- f (x::t) = ...
| BindPatSigCtxt -- Type sig in pattern binding pattern
-- (x::t, y) = e
| ResSigCtxt -- Result type sig
-- f x :: t = ....
- | ForSigCtxt Name -- Foreign inport or export signature
+ | ForSigCtxt Name -- Foreign import or export signature
| DefaultDeclCtxt -- Types in a default declaration
+ | InstDeclCtxt -- An instance declaration
| SpecInstCtxt -- SPECIALISE instance pragma
| ThBrackCtxt -- Template Haskell type brackets [t| ... |]
| GenSigCtxt -- Higher-rank or impredicative situations
@@ -363,6 +363,14 @@ data UserTypeCtxt
-- We might want to elaborate this
| GhciCtxt -- GHCi command :kind <type>
+ | ClassSCCtxt Name -- Superclasses of a class
+ | SigmaCtxt -- Theta part of a normal for-all type
+ -- f :: <S> => a -> a
+ | DataTyCtxt Name -- Theta part of a data decl
+ -- data <S> => T a = MkT a
+\end{code}
+
+
-- Notes re TySynCtxt
-- We allow type synonyms that aren't types; e.g. type List = []
--
@@ -375,26 +383,19 @@ data UserTypeCtxt
---------------------------------
-- Kind variables:
-
+\begin{code}
mkKindName :: Unique -> Name
mkKindName unique = mkSystemName unique kind_var_occ
-kindVarRef :: KindVar -> IORef MetaDetails
-kindVarRef tc =
- ASSERT ( isTcTyVar tc )
- case tcTyVarDetails tc of
- MetaTv TauTv ref -> ref
- _ -> pprPanic "kindVarRef" (ppr tc)
-
-mkKindVar :: Unique -> IORef MetaDetails -> KindVar
-mkKindVar u r
+mkMetaKindVar :: Unique -> IORef MetaDetails -> MetaKindVar
+mkMetaKindVar u r
= mkTcTyVar (mkKindName u)
tySuperKind -- not sure this is right,
-- do we need kind vars for
-- coercions?
(MetaTv TauTv r)
-kind_var_occ :: OccName -- Just one for all KindVars
+kind_var_occ :: OccName -- Just one for all MetaKindVars
-- They may be jiggled by tidying
kind_var_occ = mkOccName tvName "k"
\end{code}
@@ -422,16 +423,19 @@ pprUserTypeCtxt (FunSigCtxt n) = ptext (sLit "the type signature for") <+> qu
pprUserTypeCtxt ExprSigCtxt = ptext (sLit "an expression type signature")
pprUserTypeCtxt (ConArgCtxt c) = ptext (sLit "the type of the constructor") <+> quotes (ppr c)
pprUserTypeCtxt (TySynCtxt c) = ptext (sLit "the RHS of the type synonym") <+> quotes (ppr c)
-pprUserTypeCtxt GenPatCtxt = ptext (sLit "the type pattern of a generic definition")
pprUserTypeCtxt ThBrackCtxt = ptext (sLit "a Template Haskell quotation [t|...|]")
pprUserTypeCtxt LamPatSigCtxt = ptext (sLit "a pattern type signature")
pprUserTypeCtxt BindPatSigCtxt = ptext (sLit "a pattern type signature")
pprUserTypeCtxt ResSigCtxt = ptext (sLit "a result type signature")
pprUserTypeCtxt (ForSigCtxt n) = ptext (sLit "the foreign declaration for") <+> quotes (ppr n)
pprUserTypeCtxt DefaultDeclCtxt = ptext (sLit "a type in a `default' declaration")
+pprUserTypeCtxt InstDeclCtxt = ptext (sLit "an instance declaration")
pprUserTypeCtxt SpecInstCtxt = ptext (sLit "a SPECIALISE instance pragma")
pprUserTypeCtxt GenSigCtxt = ptext (sLit "a type expected by the context")
pprUserTypeCtxt GhciCtxt = ptext (sLit "a type in a GHCi command")
+pprUserTypeCtxt (ClassSCCtxt c) = ptext (sLit "the super-classes of class") <+> quotes (ppr c)
+pprUserTypeCtxt SigmaCtxt = ptext (sLit "the context of a polymorphic type")
+pprUserTypeCtxt (DataTyCtxt tc) = ptext (sLit "the context of the data type declaration for") <+> quotes (ppr tc)
\end{code}
@@ -447,13 +451,14 @@ pprUserTypeCtxt GhciCtxt = ptext (sLit "a type in a GHCi command")
--
-- It doesn't change the uniques at all, just the print names.
tidyTyVarBndr :: TidyEnv -> TyVar -> (TidyEnv, TyVar)
-tidyTyVarBndr (tidy_env, subst) tyvar
- = case tidyOccName tidy_env occ1 of
+tidyTyVarBndr tidy_env@(occ_env, subst) tyvar
+ = case tidyOccName occ_env occ1 of
(tidy', occ') -> ((tidy', subst'), tyvar')
where
subst' = extendVarEnv subst tyvar tyvar'
- tyvar' = setTyVarName tyvar name'
+ tyvar' = setTyVarKind (setTyVarName tyvar name') kind'
name' = tidyNameOcc name occ'
+ kind' = tidyKind tidy_env (tyVarKind tyvar)
where
name = tyVarName tyvar
occ = getOccName name
@@ -531,8 +536,11 @@ tidyTopType :: Type -> Type
tidyTopType ty = tidyType emptyTidyEnv ty
---------------
-tidyKind :: TidyEnv -> Kind -> (TidyEnv, Kind)
-tidyKind env k = tidyOpenType env k
+tidyOpenKind :: TidyEnv -> Kind -> (TidyEnv, Kind)
+tidyOpenKind = tidyOpenType
+
+tidyKind :: TidyEnv -> Kind -> Kind
+tidyKind = tidyType
\end{code}
%************************************************************************
@@ -973,13 +981,14 @@ tcInstHeadTyNotSynonym ty
tcInstHeadTyAppAllTyVars :: Type -> Bool
-- Used in Haskell-98 mode, for the argument types of an instance head
--- These must be a constructor applied to type variable arguments
+-- These must be a constructor applied to type variable arguments.
+-- But we allow kind instantiations.
tcInstHeadTyAppAllTyVars ty
| Just ty' <- tcView ty -- Look through synonyms
= tcInstHeadTyAppAllTyVars ty'
| otherwise
= case ty of
- TyConApp _ tys -> ok tys
+ TyConApp _ tys -> ok (filter (not . isKind) tys) -- avoid kinds
FunTy arg res -> ok [arg, res]
_ -> False
where
@@ -1014,7 +1023,7 @@ shallowPredTypePredTree ev_ty
() | Just clas <- tyConClass_maybe tc
-> ClassPred clas tys
() | tc `hasKey` eqTyConKey
- , let [ty1, ty2] = tys
+ , let [_, ty1, ty2] = tys
-> EqPred ty1 ty2
() | Just ip <- tyConIP_maybe tc
, let [ty] = tys
@@ -1154,9 +1163,7 @@ deNoteType :: Type -> Type
-- Remove all *outermost* type synonyms and other notes
deNoteType ty | Just ty' <- tcView ty = deNoteType ty'
deNoteType ty = ty
-\end{code}
-\begin{code}
tcTyVarsOfType :: Type -> TcTyVarSet
-- Just the *TcTyVars* free in the type
-- (Types.tyVarsOfTypes finds all free TyVars)
diff --git a/compiler/typecheck/TcUnify.lhs b/compiler/typecheck/TcUnify.lhs
index b73f70447d..67bafaca36 100644
--- a/compiler/typecheck/TcUnify.lhs
+++ b/compiler/typecheck/TcUnify.lhs
@@ -14,12 +14,12 @@ Type subsumption and unification
-- for details
module TcUnify (
- -- Full-blown subsumption
+ -- Full-blown subsumption
tcWrapResult, tcSubType, tcGen,
checkConstraints, newImplication, sigCtxt,
- -- Various unifications
- unifyType, unifyTypeList, unifyTheta, unifyKind,
+ -- Various unifications
+ unifyType, unifyTypeList, unifyTheta, unifyKind, unifyKindEq,
--------------------------------
-- Holes
@@ -31,7 +31,12 @@ module TcUnify (
matchExpectedFunTys,
matchExpectedFunKind,
wrapFunResCoercion,
- failWithMisMatch
+ failWithMisMatch,
+
+ --------------------------------
+ -- Errors
+ mkKindErrorCtxt
+
) where
#include "HsVersions.h"
@@ -46,17 +51,17 @@ import TcRnMonad
import TcType
import Type
import Coercion
+import Name ( isSystemName )
import Inst
-import Kind ( isConstraintKind, isConstraintKindCon )
+import Kind
import TyCon
import TysWiredIn
import Var
import VarSet
import VarEnv
-import Name
import ErrUtils
import BasicTypes
-import Maybes ( allMaybes )
+import Maybes ( allMaybes )
import Util
import Outputable
import FastString
@@ -198,10 +203,10 @@ matchExpectedPArrTy exp_ty
; return (co, elt_ty) }
----------------------
-matchExpectedTyConApp :: TyCon -- T :: k1 -> ... -> kn -> *
+matchExpectedTyConApp :: TyCon -- T :: forall kv1 ... kvm. k1 -> ... -> kn -> *
-> TcRhoType -- orig_ty
- -> TcM (LCoercion, -- T a b c ~ orig_ty
- [TcSigmaType]) -- Element types, a b c
+ -> TcM (LCoercion, -- T k1 k2 k3 a b c ~ orig_ty
+ [TcSigmaType]) -- Element types, k1 k2 k3 a b c
-- It's used for wired-in tycons, so we call checkWiredInTyCon
-- Precondition: never called with FunTyCon
@@ -239,11 +244,14 @@ matchExpectedTyConApp tc orig_ty
----------
defer n_req ty tys
- = do { tau_tys <- mapM newFlexiTyVarTy arg_kinds
- ; co <- unifyType (mkTyConApp tc tau_tys) ty
- ; return (co, tau_tys ++ tys) }
+ = do { kappa_tys <- mapM (const newMetaKindVar) kvs
+ ; let arg_kinds' = map (substKiWith kvs kappa_tys) arg_kinds
+ ; tau_tys <- mapM newFlexiTyVarTy arg_kinds'
+ ; co <- unifyType (mkTyConApp tc (kappa_tys ++ tau_tys)) ty
+ ; return (co, kappa_tys ++ tau_tys ++ tys) }
where
- (arg_kinds, _) = splitKindFunTysN n_req (tyConKind tc)
+ (kvs, body) = splitForAllTys (tyConKind tc)
+ (arg_kinds, _) = splitKindFunTysN (n_req - length kvs) body
----------------------
matchExpectedAppTy :: TcRhoType -- orig_ty
@@ -574,10 +582,7 @@ uType_np origin orig_ty1 orig_ty2
go (TyVarTy tyvar1) ty2 = uVar origin NotSwapped tyvar1 ty2
go ty1 (TyVarTy tyvar2) = uVar origin IsSwapped tyvar2 ty1
- -- Expand synonyms:
- -- see Note [Unification and synonyms]
- -- Do this after the variable case so that we tend to unify
- -- variables with un-expanded type synonym
+ -- See Note [Expanding synonyms during unification]
--
-- Also NB that we recurse to 'go' so that we don't push a
-- new item on the origin stack. As a result if we have
@@ -715,48 +720,19 @@ So either
Currently we adopt (b) since it seems more robust -- no need to maintain
a global invariant.
-Note [Unification and synonyms]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If you are tempted to make a short cut on synonyms, as in this
-pseudocode...
-
- uTys (SynTy con1 args1 ty1) (SynTy con2 args2 ty2)
- = if (con1 == con2) then
- -- Good news! Same synonym constructors, so we can shortcut
- -- by unifying their arguments and ignoring their expansions.
- unifyTypepeLists args1 args2
- else
- -- Never mind. Just expand them and try again
- uTys ty1 ty2
-
-then THINK AGAIN. Here is the whole story, as detected and reported
-by Chris Okasaki:
-
-Here's a test program that should detect the problem:
-
- type Bogus a = Int
- x = (1 :: Bogus Char) :: Bogus Bool
-
-The problem with [the attempted shortcut code] is that
-
- con1 == con2
-
-is not a sufficient condition to be able to use the shortcut!
-You also need to know that the type synonym actually USES all
-its arguments. For example, consider the following type synonym
-which does not use all its arguments.
-
- type Bogus a = Int
-
-If you ever tried unifying, say, (Bogus Char) with )Bogus Bool), the
-unifier would blithely try to unify Char with Bool and would fail,
-even though the expanded forms (both Int) should match. Similarly,
-unifying (Bogus Char) with (Bogus t) would unnecessarily bind t to
-Char.
+Note [Expanding synonyms during unification]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We expand synonyms during unification, but:
+ * We expand *after* the variable case so that we tend to unify
+ variables with un-expanded type synonym. This just makes it
+ more likely that the inferred types will mention type synonyms
+ understandable to the user
-... You could explicitly test for the problem synonyms and mark them
-somehow as needing expansion, perhaps also issuing a warning to the
-user.
+ * We expand *before* the TyConApp case. For example, if we have
+ type Phantom a = Int
+ and are unifying
+ Phantom Int ~ Phantom Char
+ it is *wrong* to unify Int and Char.
Note [Deferred Unification]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -857,29 +833,31 @@ uUnfilledVars :: [EqOrigin]
-- Neither is filled in yet
uUnfilledVars origin swapped tv1 details1 tv2 details2
- = case (details1, details2) of
- (MetaTv i1 ref1, MetaTv i2 ref2)
- | k1_sub_k2 -> if k2_sub_k1 && nicer_to_update_tv1 i1 i2
- then updateMeta tv1 ref1 ty2
- else updateMeta tv2 ref2 ty1
- | k2_sub_k1 -> updateMeta tv1 ref1 ty2
-
- (_, MetaTv _ ref2) | k1_sub_k2 -> updateMeta tv2 ref2 ty1
- (MetaTv _ ref1, _) | k2_sub_k1 -> updateMeta tv1 ref1 ty2
-
- (_, _) -> unSwap swapped (uType_defer origin) ty1 ty2
- -- Defer for skolems of all sorts
+ = do { traceTc "uUnfilledVars" ( text "trying to unify" <+> ppr k1
+ <+> text "with" <+> ppr k2)
+ ; let ctxt = mkKindErrorCtxt ty1 ty2 k1 k2
+ ; sub_kind <- addErrCtxtM ctxt $ unifyKind k1 k2
+
+ ; case (sub_kind, details1, details2) of
+ -- k1 <= k2, so update tv2
+ (LT, _, MetaTv _ ref2) -> updateMeta tv2 ref2 ty1
+ -- k2 <= k1, so update tv1
+ (GT, MetaTv _ ref1, _) -> updateMeta tv1 ref1 ty2
+ (EQ, MetaTv i1 ref1, MetaTv i2 ref2)
+ | nicer_to_update_tv1 i1 i2 -> updateMeta tv1 ref1 ty2
+ | otherwise -> updateMeta tv2 ref2 ty1
+
+ (_, _, _) -> unSwap swapped (uType_defer origin) ty1 ty2 }
+ -- Defer for skolems of all sorts
where
- k1 = tyVarKind tv1
- k2 = tyVarKind tv2
- k1_sub_k2 = k1 `isSubKind` k2
- k2_sub_k1 = k2 `isSubKind` k1
- ty1 = mkTyVarTy tv1
- ty2 = mkTyVarTy tv2
+ k1 = tyVarKind tv1
+ k2 = tyVarKind tv2
+ ty1 = mkTyVarTy tv1
+ ty2 = mkTyVarTy tv2
nicer_to_update_tv1 _ SigTv = True
nicer_to_update_tv1 SigTv _ = False
- nicer_to_update_tv1 _ _ = isSystemName (Var.varName tv1)
+ nicer_to_update_tv1 _ _ = isSystemName (Var.varName tv1)
-- Try not to update SigTvs; and try to update sys-y type
-- variables in preference to ones gotten (say) by
-- instantiating a polymorphic function with a user-written
@@ -890,7 +868,7 @@ checkTauTvUpdate :: TcTyVar -> TcType -> TcM (Maybe TcType)
-- (checkTauTvUpdate tv ty)
-- We are about to update the TauTv tv with ty.
-- Check (a) that tv doesn't occur in ty (occurs check)
--- (b) that kind(ty) is a sub-kind of kind(tv)
+-- (b) that kind(ty) is a sub-kind of kind(tv)
-- (c) that ty does not contain any type families, see Note [Type family sharing]
--
-- We have two possible outcomes:
@@ -910,26 +888,36 @@ checkTauTvUpdate :: TcTyVar -> TcType -> TcM (Maybe TcType)
checkTauTvUpdate tv ty
= do { ty' <- zonkTcType ty
- ; if typeKind ty' `isSubKind` tyVarKind tv then
- case ok ty' of
- Nothing -> return Nothing
- Just ty'' -> return (Just ty'')
- else return Nothing }
-
- where ok :: TcType -> Maybe TcType
- ok (TyVarTy tv') | not (tv == tv') = Just (TyVarTy tv')
- ok this_ty@(TyConApp tc tys)
- | not (isSynFamilyTyCon tc), Just tys' <- allMaybes (map ok tys)
- = Just (TyConApp tc tys')
- | isSynTyCon tc, Just ty_expanded <- tcView this_ty
- = ok ty_expanded -- See Note [Type synonyms and the occur check]
- ok (FunTy arg res) | Just arg' <- ok arg, Just res' <- ok res
- = Just (FunTy arg' res')
- ok (AppTy fun arg) | Just fun' <- ok fun, Just arg' <- ok arg
- = Just (AppTy fun' arg')
- ok (ForAllTy tv1 ty1) | Just ty1' <- ok ty1 = Just (ForAllTy tv1 ty1')
- -- Fall-through
- ok _ty = Nothing
+ ; let k2 = typeKind ty'
+ ; k1 <- zonkTcKind (tyVarKind tv)
+ ; let ctxt = mkKindErrorCtxt (mkTyVarTy tv) ty' k1 k2
+ ; sub_k <- addErrCtxtM ctxt $
+ unifyKind (tyVarKind tv) (typeKind ty')
+
+ ; case sub_k of
+ LT -> return Nothing
+ _ -> return (ok ty') }
+ where
+ ok :: TcType -> Maybe TcType
+ -- Checks that tv does not occur in the arg type
+ -- expanding type synonyms where necessary to make this so
+ -- eg type Phantom a = Bool
+ -- ok (tv -> Int) = Nothing
+ -- ok (x -> Int) = Just (x -> Int)
+ -- ok (Phantom tv -> Int) = Just (Bool -> Int)
+ ok (TyVarTy tv') | not (tv == tv') = Just (TyVarTy tv')
+ ok this_ty@(TyConApp tc tys)
+ | not (isSynFamilyTyCon tc), Just tys' <- allMaybes (map ok tys)
+ = Just (TyConApp tc tys')
+ | isSynTyCon tc, Just ty_expanded <- tcView this_ty
+ = ok ty_expanded -- See Note [Type synonyms and the occur check]
+ ok (FunTy arg res) | Just arg' <- ok arg, Just res' <- ok res
+ = Just (FunTy arg' res')
+ ok (AppTy fun arg) | Just fun' <- ok fun, Just arg' <- ok arg
+ = Just (AppTy fun' arg')
+ ok (ForAllTy tv1 ty1) | Just ty1' <- ok ty1 = Just (ForAllTy tv1 ty1')
+ -- Fall-through
+ ok _ty = Nothing
\end{code}
Note [Avoid deferring]
@@ -1130,115 +1118,144 @@ matchExpectedFunKind :: TcKind -> TcM (Maybe (TcKind, TcKind))
-- Like unifyFunTy, but does not fail; instead just returns Nothing
matchExpectedFunKind (TyVarTy kvar) = do
- maybe_kind <- readKindVar kvar
+ maybe_kind <- readMetaTyVar kvar
case maybe_kind of
Indirect fun_kind -> matchExpectedFunKind fun_kind
Flexi ->
- do { arg_kind <- newKindVar
- ; res_kind <- newKindVar
- ; writeKindVar kvar (mkArrowKind arg_kind res_kind)
+ do { arg_kind <- newMetaKindVar
+ ; res_kind <- newMetaKindVar
+ ; writeMetaTyVar kvar (mkArrowKind arg_kind res_kind)
; return (Just (arg_kind,res_kind)) }
matchExpectedFunKind (FunTy arg_kind res_kind) = return (Just (arg_kind,res_kind))
matchExpectedFunKind _ = return Nothing
------------------
-unifyKind :: TcKind -- Expected
- -> TcKind -- Actual
- -> TcM ()
-
-unifyKind (TyConApp kc1 []) (TyConApp kc2 [])
- | isSubKindCon kc2 kc1
- , not (isConstraintKindCon kc2) || isConstraintKindCon kc1 = return ()
- -- For the purposes of the front end ONLY, only allow
- -- the Constraint kind to unify with itself.
- --
- -- This prevents the user from writing constraints types
- -- on the left or right of an arrow.
-
-unifyKind (FunTy a1 r1) (FunTy a2 r2)
- = do { unifyKind a2 a1; unifyKind r1 r2 }
- -- Notice the flip in the argument,
- -- so that the sub-kinding works right
+-----------------
+unifyKind :: TcKind -- k1 (actual)
+ -> TcKind -- k2 (expected)
+ -> TcM Ordering -- Returns the relation between the kinds
+ -- LT <=> k1 is a sub-kind of k2
+
unifyKind (TyVarTy kv1) k2 = uKVar False kv1 k2
-unifyKind k1 (TyVarTy kv2) = uKVar True kv2 k1
-unifyKind k1 k2 = unifyKindMisMatch k1 k2
+unifyKind k1 (TyVarTy kv2) = uKVar True kv2 k1
+
+unifyKind k1 k2 -- See Note [Expanding synonyms during unification]
+ | Just k1' <- tcView k1 = unifyKind k1' k2
+ | Just k2' <- tcView k2 = unifyKind k1 k2'
+
+unifyKind k1@(TyConApp kc1 []) k2@(TyConApp kc2 [])
+ | kc1 == kc2 = return EQ
+ | kc1 `tcIsSubKindCon` kc2 = return LT
+ | kc2 `tcIsSubKindCon` kc1 = return GT
+ | otherwise = unifyKindMisMatch k1 k2
+
+unifyKind k1 k2 = do { unifyKindEq k1 k2; return EQ }
+ -- In all other cases, let unifyKindEq do the work
+
+uKVar :: Bool -> MetaKindVar -> TcKind -> TcM Ordering
+uKVar isFlipped kv1 k2
+ | isMetaTyVar kv1
+ = do { mb_k1 <- readMetaTyVar kv1
+ ; case mb_k1 of
+ Flexi -> uUnboundKVar kv1 k2 >> return EQ
+ Indirect k1 -> unifyKind k1 k2 }
+ | TyVarTy kv2 <- k2, isMetaTyVar kv2
+ = uKVar (not isFlipped) kv2 (TyVarTy kv1)
+ | TyVarTy kv2 <- k2, kv1 == kv2 = return EQ
+ | otherwise = if isFlipped
+ then unifyKindMisMatch k2 (TyVarTy kv1)
+ else unifyKindMisMatch (TyVarTy kv1) k2
+
+---------------------------
+unifyKindEq :: TcKind -> TcKind -> TcM ()
+unifyKindEq (TyVarTy kv1) k2 = uKVarEq False kv1 k2
+unifyKindEq k1 (TyVarTy kv2) = uKVarEq True kv2 k1
+
+unifyKindEq (FunTy a1 r1) (FunTy a2 r2)
+ = do { unifyKindEq a1 a2; unifyKindEq r1 r2 }
+
+unifyKindEq (TyConApp kc1 k1s) (TyConApp kc2 k2s)
+ | kc1 == kc2
+ = ASSERT (length k1s == length k2s)
+ -- Should succeed since the kind constructors are the same,
+ -- and the kinds are sort-checked, thus fully applied
+ zipWithM_ unifyKindEq k1s k2s
+
+unifyKindEq k1 k2 = unifyKindMisMatch k1 k2
----------------
-uKVar :: Bool -> KindVar -> TcKind -> TcM ()
-uKVar swapped kv1 k2
- = do { mb_k1 <- readKindVar kv1
+-- For better error messages, we record whether we've flipped the kinds
+-- during the process.
+uKVarEq :: Bool -> MetaKindVar -> TcKind -> TcM ()
+uKVarEq isFlipped kv1 k2
+ | isMetaTyVar kv1
+ = do { mb_k1 <- readMetaTyVar kv1
; case mb_k1 of
- Flexi -> uUnboundKVar swapped kv1 k2
- Indirect k1 | swapped -> unifyKind k2 k1
- | otherwise -> unifyKind k1 k2 }
+ Flexi -> uUnboundKVar kv1 k2
+ Indirect k1 -> unifyKindEq k1 k2 }
+ | TyVarTy kv2 <- k2, isMetaTyVar kv2
+ = uKVarEq (not isFlipped) kv2 (TyVarTy kv1)
+ | TyVarTy kv2 <- k2, kv1 == kv2 = return ()
+ | otherwise = if isFlipped
+ then unifyKindMisMatch k2 (TyVarTy kv1)
+ else unifyKindMisMatch (TyVarTy kv1) k2
----------------
-uUnboundKVar :: Bool -> KindVar -> TcKind -> TcM ()
-uUnboundKVar swapped kv1 k2@(TyVarTy kv2)
+uUnboundKVar :: MetaKindVar -> TcKind -> TcM ()
+uUnboundKVar kv1 k2@(TyVarTy kv2)
| kv1 == kv2 = return ()
- | otherwise -- Distinct kind variables
- = do { mb_k2 <- readKindVar kv2
+ | isMetaTyVar kv2 -- Distinct kind variables
+ = do { mb_k2 <- readMetaTyVar kv2
; case mb_k2 of
- Indirect k2 -> uUnboundKVar swapped kv1 k2
- Flexi -> writeKindVar kv1 k2 }
+ Indirect k2 -> uUnboundKVar kv1 k2
+ Flexi -> writeMetaTyVar kv1 k2 }
+ | otherwise = writeMetaTyVar kv1 k2
-uUnboundKVar swapped kv1 non_var_k2
+uUnboundKVar kv1 non_var_k2
= do { k2' <- zonkTcKind non_var_k2
; kindOccurCheck kv1 k2'
- ; k2'' <- kindSimpleKind swapped k2'
- -- KindVars must be bound only to simple kinds
- -- Polarities: (kindSimpleKind True ?) succeeds
- -- returning *, corresponding to unifying
- -- expected: ?
- -- actual: kind-ver
- ; writeKindVar kv1 k2'' }
+ ; let k2'' = kindSimpleKind k2'
+ -- MetaKindVars must be bound only to simple kinds
+ ; writeMetaTyVar kv1 k2'' }
----------------
kindOccurCheck :: TyVar -> Type -> TcM ()
kindOccurCheck kv1 k2 -- k2 is zonked
- = checkTc (not_in k2) (kindOccurCheckErr kv1 k2)
- where
- not_in (TyVarTy kv2) = kv1 /= kv2
- not_in (FunTy a2 r2) = not_in a2 && not_in r2
- not_in _ = True
-
-kindSimpleKind :: Bool -> Kind -> TcM SimpleKind
--- (kindSimpleKind True k) returns a simple kind sk such that sk <: k
--- If the flag is False, it requires k <: sk
--- E.g. kindSimpleKind False ?? = *
--- What about (kv -> *) ~ ?? -> *
-kindSimpleKind orig_swapped orig_kind
- = go orig_swapped orig_kind
- where
- go sw (FunTy k1 k2) = do { k1' <- go (not sw) k1
- ; k2' <- go sw k2
- ; return (mkArrowKind k1' k2') }
- go True k
- | isOpenTypeKind k = return liftedTypeKind
- | isArgTypeKind k = return liftedTypeKind
- go _ k
- | isLiftedTypeKind k = return liftedTypeKind
- | isUnliftedTypeKind k = return unliftedTypeKind
- | isConstraintKind k = return constraintKind
- go _ k@(TyVarTy _) = return k -- KindVars are always simple
- go _ _ = failWithTc (ptext (sLit "Unexpected kind unification failure:")
- <+> ppr orig_swapped <+> ppr orig_kind)
- -- I think this can't actually happen
-
--- T v = MkT v v must be a type
--- T v w = MkT (v -> w) v must not be an umboxed tuple
-
-unifyKindMisMatch :: TcKind -- Expected
- -> TcKind -- Actual
- -> TcM ()
-unifyKindMisMatch ty1 ty2 = do
- ty1' <- zonkTcKind ty1
- ty2' <- zonkTcKind ty2
- failWithTc $ hang (ptext (sLit "Couldn't match kind"))
- 2 (sep [quotes (ppr ty1'),
- ptext (sLit "against"),
- quotes (ppr ty2')])
+ = if elemVarSet kv1 (tyVarsOfType k2)
+ then failWithTc (kindOccurCheckErr kv1 k2)
+ else return ()
+
+kindSimpleKind :: Kind -> SimpleKind
+-- (kindSimpleKind k) returns a simple kind k' such that k' <= k
+kindSimpleKind k
+ | isOpenTypeKind k = liftedTypeKind
+ | isArgTypeKind k = liftedTypeKind
+ | otherwise = k
+
+mkKindErrorCtxt :: Type -> Type -> Kind -> Kind -> TidyEnv -> TcM (TidyEnv, SDoc)
+mkKindErrorCtxt ty1 ty2 k1 k2 env0
+ = let (env1, ty1') = tidyOpenType env0 ty1
+ (env2, ty2') = tidyOpenType env1 ty2
+ (env3, k1' ) = tidyOpenKind env2 k1
+ (env4, k2' ) = tidyOpenKind env3 k2
+ in do ty1 <- zonkTcType ty1'
+ ty2 <- zonkTcType ty2'
+ k1 <- zonkTcKind k1'
+ k2 <- zonkTcKind k2'
+ return (env4,
+ vcat [ ptext (sLit "Kind incompatibility when matching types:")
+ , nest 2 (vcat [ ppr ty1 <+> dcolon <+> ppr k1
+ , ppr ty2 <+> dcolon <+> ppr k2 ]) ])
+
+unifyKindMisMatch :: TcKind -> TcKind -> TcM a
+unifyKindMisMatch ki1 ki2 = do
+ ki1' <- zonkTcKind ki1
+ ki2' <- zonkTcKind ki2
+ let msg = hang (ptext (sLit "Couldn't match kind"))
+ 2 (sep [quotes (ppr ki1'),
+ ptext (sLit "against"),
+ quotes (ppr ki2')])
+ failWithTc msg
----------------
kindOccurCheckErr :: Var -> Type -> SDoc
diff --git a/compiler/typecheck/TcUnify.lhs-boot b/compiler/typecheck/TcUnify.lhs-boot
index 431bfaabdc..ac4d5ddc78 100644
--- a/compiler/typecheck/TcUnify.lhs-boot
+++ b/compiler/typecheck/TcUnify.lhs-boot
@@ -7,12 +7,16 @@
-- for details
module TcUnify where
-import TcType ( TcTauType )
-import TcRnTypes( TcM )
-import Coercion (LCoercion)
+import TcType ( TcTauType, TcKind, Type, Kind )
+import VarEnv ( TidyEnv )
+import TcRnTypes ( TcM )
+import Coercion ( LCoercion )
+import Outputable ( SDoc )
-- This boot file exists only to tie the knot between
--- TcUnify and Inst
+-- TcUnify and Inst
unifyType :: TcTauType -> TcTauType -> TcM LCoercion
+unifyKindEq :: TcKind -> TcKind -> TcM ()
+mkKindErrorCtxt :: Type -> Type -> Kind -> Kind -> TidyEnv -> TcM (TidyEnv, SDoc)
\end{code}
diff --git a/compiler/types/Class.lhs b/compiler/types/Class.lhs
index 1878237499..cda98de45e 100644
--- a/compiler/types/Class.lhs
+++ b/compiler/types/Class.lhs
@@ -39,6 +39,7 @@ import BasicTypes
import Unique
import Util
import Outputable
+import SrcLoc
import FastString
import Data.Typeable (Typeable)
@@ -56,14 +57,16 @@ A @Class@ corresponds to a Greek kappa in the static semantics:
\begin{code}
data Class
= Class {
- classTyCon :: TyCon, -- The data type constructor for
- -- dictionaries of this class
+ classTyCon :: TyCon, -- The data type constructor for
+ -- dictionaries of this class
+ -- See Note [ATyCon for classes] in TypeRep
className :: Name, -- Just the cached name of the TyCon
classKey :: Unique, -- Cached unique of TyCon
- classTyVars :: [TyVar], -- The class type variables;
+ classTyVars :: [TyVar], -- The class kind and type variables;
-- identical to those of the TyCon
+
classFunDeps :: [FunDep TyVar], -- The functional dependencies
-- Superclasses: eg: (F a ~ b, F b ~ G a, Eq a, Show b)
@@ -97,12 +100,19 @@ type ClassATItem = (TyCon, [ATDefault])
-- Default associated types from these templates. If the template list is empty,
-- we assume that there is no default -- not that the default is to generate no
-- instances (this only makes a difference for warnings).
-
-data ATDefault = ATD [TyVar] [Type] Type
- -- Each associated type default template is a triple of:
- -- 1. TyVars of the RHS and family arguments (including the class TVs)
- -- 3. The instantiated family arguments
- -- 2. The RHS of the synonym
+ -- We can have more than one default per type; see
+ -- Note [Associated type defaults] in TcTyClsDecls
+
+-- Each associated type default template is a triple of:
+data ATDefault = ATD { -- TyVars of the RHS and family arguments
+ -- (including the class TVs)
+ atDefaultTys :: [TyVar],
+ -- The instantiated family arguments
+ atDefaultPats :: [Type],
+ -- The RHS of the synonym
+ atDefaultRhs :: Type,
+ -- The source location of the synonym
+ atDefaultSrcSpan :: SrcSpan }
-- | Convert a `DefMethSpec` to a `DefMeth`, which discards the name field in
-- the `DefMeth` constructor of the `DefMeth`.
diff --git a/compiler/types/Coercion.lhs b/compiler/types/Coercion.lhs
index 4437a3e783..228768baf7 100644
--- a/compiler/types/Coercion.lhs
+++ b/compiler/types/Coercion.lhs
@@ -19,19 +19,7 @@ module Coercion (
Coercion(..), Var, CoVar,
LCoercion,
- -- ** Deconstructing Kinds
- kindFunResult, kindAppResult, synTyConResKind,
- splitKindFunTys, splitKindFunTysN, splitKindFunTy_maybe,
-
- -- ** Predicates on Kinds
- isLiftedTypeKind, isUnliftedTypeKind, isOpenTypeKind,
- isUbxTupleKind, isArgTypeKind, isKind, isTySuperKind,
- isSuperKind,
- mkArrowKind, mkArrowKinds,
-
- isSubArgTypeKind, isSubOpenTypeKind, isSubKind, defaultKind, eqKind,
- isSubKindCon,
-
+ -- ** Functions over coercions
coVarKind, coVarKind_maybe,
coercionType, coercionKind, coercionKinds, isReflCo, liftedCoercionKind,
mkCoercionType,
@@ -90,7 +78,6 @@ import Unify ( MatchEnv(..), matchList )
import TypeRep
import qualified Type
import Type hiding( substTy, substTyVarBndr, extendTvSubst )
-import Kind
import TyCon
import Var
import VarEnv
@@ -162,21 +149,22 @@ data Coercion
deriving (Data.Data, Data.Typeable)
\end{code}
+Note [LCoercions]
+~~~~~~~~~~~~~~~~~
+| LCoercions are a hack used by the typechecker. Normally,
+Coercions have free variables of type (a ~# b): we call these
+CoVars. However, the type checker passes around equality evidence
+(boxed up) at type (a ~ b).
+
+An LCoercion is simply a Coercion whose free variables have the
+boxed type (a ~ b). After we are done with typechecking the
+desugarer finds the free variables, unboxes them, and creates a
+resulting real Coercion with kosher free variables.
+
+We can use most of the Coercion "smart constructors" to build LCoercions. However,
+mkCoVarCo will not work! The equivalent is mkEqVarLCo.
+
\begin{code}
--- Note [LCoercions]
--- ~~~~~~~~~~~~~~~~~
--- | LCoercions are a hack used by the typechecker. Normally,
--- Coercions have free variables of type (a ~# b): we call these
--- CoVars. However, the type checker passes around equality evidence
--- (boxed up) at type (a ~ b).
---
--- An LCoercion is simply a Coercion whose free variables have the
--- boxed type (a ~ b). After we are done with typechecking the
--- desugarer finds the free variables, unboxes them, and creates a
--- resulting real Coercion with kosher free variables.
---
--- We can use most of the Coercion "smart constructors" to build LCoercions. However,
--- mkCoVarCo will not work! The equivalent is mkEqVarLCo.
type LCoercion = Coercion
\end{code}
@@ -282,6 +270,30 @@ predicates too:
Nth 1 ((~) [c] g) = g
See Simplify.simplCoercionF, which generates such selections.
+Note [Kind coercions]
+~~~~~~~~~~~~~~~~~~~~~
+Suppose T :: * -> *, and g :: A ~ B
+Then the coercion
+ TyConAppCo T [g] T g : T A ~ T B
+
+Now suppose S :: forall k. k -> *, and g :: A ~ B
+Then the coercion
+ TyConAppCo S [Refl *, g] T <*> g : T * A ~ T * B
+
+Notice that the arguments to TyConAppCo are coercions, but the first
+represents a *kind* coercion. Now, we don't allow any non-trivial kind
+coercions, so it's an invariant that any such kind coercions are Refl.
+Lint checks this.
+
+However it's inconvenient to insist that these kind coercions are always
+*structurally* (Refl k), because the key function exprIsConApp_maybe
+pushes coercions into constructor arguments, so
+ C k ty e |> g
+may turn into
+ C (Nth 0 g) ....
+Now (Nth 0 g) will optimise to Refl, but perhaps not instantly.
+
+
%************************************************************************
%* *
\subsection{Coercion variables}
@@ -453,6 +465,7 @@ pprCoAxiom ax
-- > decomposeCo 3 c = [nth 0 c, nth 1 c, nth 2 c]
decomposeCo :: Arity -> Coercion -> [Coercion]
decomposeCo arity co = [mkNthCo n co | n <- [0..(arity-1)] ]
+ -- Remember, Nth is zero-indexed
-- | Attempts to obtain the type variable underlying a 'Coercion'
getCoVar_maybe :: Coercion -> Maybe CoVar
@@ -495,7 +508,7 @@ coVarKind cv = case coVarKind_maybe cv of
coVarKind_maybe :: CoVar -> Maybe (Type,Type)
coVarKind_maybe cv = case splitTyConApp_maybe (varType cv) of
- Just (tc, [ty1, ty2]) | tc `hasKey` eqPrimTyConKey -> Just (ty1, ty2)
+ Just (tc, [_, ty1, ty2]) | tc `hasKey` eqPrimTyConKey -> Just (ty1, ty2)
_ -> Nothing
-- | Makes a coercion type from two types: the types whose equality
@@ -932,6 +945,9 @@ ty_co_subst subst ty
-- won't be in the substitution
go (AppTy ty1 ty2) = mkAppCo (go ty1) (go ty2)
go (TyConApp tc tys) = mkTyConAppCo tc (map go tys)
+ -- IA0_NOTE: Do we need to do anything
+ -- about kind instantiations? I don't think
+ -- so. see Note [Kind coercions]
go (FunTy ty1 ty2) = mkFunCo (go ty1) (go ty2)
go (ForAllTy v ty) = mkForAllCo v' $! (ty_co_subst subst' ty)
where
@@ -1107,6 +1123,7 @@ coercionKinds :: [Coercion] -> Pair [Type]
coercionKinds tys = sequenceA $ map coercionKind tys
getNth :: Int -> Type -> Type
+-- Executing Nth
getNth n ty | Just tys <- tyConAppArgs_maybe ty
= ASSERT2( n < length tys, ppr n <+> ppr tys ) tys !! n
getNth n ty = pprPanic "getNth" (ppr n <+> ppr ty)
@@ -1119,3 +1136,9 @@ applyCo ty co | Just ty' <- coreView ty = applyCo ty' co
applyCo (FunTy _ ty) _ = ty
applyCo _ _ = panic "applyCo"
\end{code}
+
+Note [Kind coercions]
+~~~~~~~~~~~~~~~~~~~~~
+Kind coercions are only of the form: Refl kind. They are only used to
+instantiate kind polymorphic type constructors in TyConAppCo. Remember
+that kind instantiation only happens with TyConApp, not AppTy.
diff --git a/compiler/types/FamInstEnv.lhs b/compiler/types/FamInstEnv.lhs
index 6e9abe0d3e..236185168b 100644
--- a/compiler/types/FamInstEnv.lhs
+++ b/compiler/types/FamInstEnv.lhs
@@ -309,58 +309,6 @@ lookupFamInstEnv
where
match _ tpl_tvs tpl_tys tys = tcMatchTys tpl_tvs tpl_tys tys
-lookupFamInstEnvConflicts'
- :: FamInstEnv
- -> FamInst -- Putative new instance
- -> [TyVar] -- Unique tyvars, matching arity of FamInst
- -> [FamInstMatch] -- Conflicting matches
--- E.g. when we are about to add
--- f : type instance F [a] = a->a
--- we do (lookupFamInstConflicts f [b])
--- to find conflicting matches
--- The skolem tyvars are needed because we don't have a
--- unique supply to hand
---
--- Precondition: the tycon is saturated (or over-saturated)
-
-lookupFamInstEnvConflicts' env fam_inst skol_tvs
- = lookup_fam_inst_env' my_unify False env fam tys'
- where
- inst_tycon = famInstTyCon fam_inst
- (fam, tys) = expectJust "FamInstEnv.lookuFamInstEnvConflicts"
- (tyConFamInst_maybe inst_tycon)
- skol_tys = mkTyVarTys skol_tvs
- tys' = substTys (zipTopTvSubst (tyConTyVars inst_tycon) skol_tys) tys
- -- In example above, fam tys' = F [b]
-
- my_unify old_fam_inst tpl_tvs tpl_tys match_tys
- = ASSERT2( tyVarsOfTypes tys `disjointVarSet` tpl_tvs,
- (ppr fam <+> ppr tys) $$
- (ppr tpl_tvs <+> ppr tpl_tys) )
- -- Unification will break badly if the variables overlap
- -- They shouldn't because we allocate separate uniques for them
- case tcUnifyTys instanceBindFun tpl_tys match_tys of
- Just subst | conflicting old_fam_inst subst -> Just subst
- _other -> Nothing
-
- -- - In the case of data family instances, any overlap is fundamentally a
- -- conflict (as these instances imply injective type mappings).
- -- - In the case of type family instances, overlap is admitted as long as
- -- the right-hand sides of the overlapping rules coincide under the
- -- overlap substitution. We require that they are syntactically equal;
- -- anything else would be difficult to test for at this stage.
- conflicting old_fam_inst subst
- | isAlgTyCon fam = True
- | otherwise = not (old_rhs `eqType` new_rhs)
- where
- old_tycon = famInstTyCon old_fam_inst
- old_tvs = tyConTyVars old_tycon
- old_rhs = mkTyConApp old_tycon (substTyVars subst old_tvs)
- new_rhs = mkTyConApp inst_tycon (substTyVars subst skol_tvs)
-
-
-
-
lookupFamInstEnvConflicts
:: FamInstEnvs
-> FamInst -- Putative new instance
@@ -376,18 +324,18 @@ lookupFamInstEnvConflicts
-- Precondition: the tycon is saturated (or over-saturated)
lookupFamInstEnvConflicts envs fam_inst skol_tvs
- = lookup_fam_inst_env my_unify False envs fam tys'
+ = lookup_fam_inst_env my_unify False envs fam tys1
where
inst_tycon = famInstTyCon fam_inst
(fam, tys) = expectJust "FamInstEnv.lookuFamInstEnvConflicts"
(tyConFamInst_maybe inst_tycon)
skol_tys = mkTyVarTys skol_tvs
- tys' = substTys (zipTopTvSubst (tyConTyVars inst_tycon) skol_tys) tys
+ tys1 = substTys (zipTopTvSubst (tyConTyVars inst_tycon) skol_tys) tys
-- In example above, fam tys' = F [b]
my_unify old_fam_inst tpl_tvs tpl_tys match_tys
- = ASSERT2( tyVarsOfTypes tys `disjointVarSet` tpl_tvs,
- (ppr fam <+> ppr tys) $$
+ = ASSERT2( tyVarsOfTypes tys1 `disjointVarSet` tpl_tvs,
+ (ppr fam <+> ppr tys1) $$
(ppr tpl_tvs <+> ppr tpl_tys) )
-- Unification will break badly if the variables overlap
-- They shouldn't because we allocate separate uniques for them
@@ -395,12 +343,7 @@ lookupFamInstEnvConflicts envs fam_inst skol_tvs
Just subst | conflicting old_fam_inst subst -> Just subst
_other -> Nothing
- -- - In the case of data family instances, any overlap is fundamentally a
- -- conflict (as these instances imply injective type mappings).
- -- - In the case of type family instances, overlap is admitted as long as
- -- the right-hand sides of the overlapping rules coincide under the
- -- overlap substitution. We require that they are syntactically equal;
- -- anything else would be difficult to test for at this stage.
+ -- Note [Family instance overlap conflicts]
conflicting old_fam_inst subst
| isAlgTyCon fam = True
| otherwise = not (old_rhs `eqType` new_rhs)
@@ -409,8 +352,29 @@ lookupFamInstEnvConflicts envs fam_inst skol_tvs
old_tvs = tyConTyVars old_tycon
old_rhs = mkTyConApp old_tycon (substTyVars subst old_tvs)
new_rhs = mkTyConApp inst_tycon (substTyVars subst skol_tvs)
+
+-- This variant is called when we want to check if the conflict is only in the
+-- home environment (see FamInst.addLocalFamInst)
+lookupFamInstEnvConflicts' :: FamInstEnv -> FamInst -> [TyVar] -> [FamInstMatch]
+lookupFamInstEnvConflicts' env fam_inst skol_tvs
+ = lookupFamInstEnvConflicts (emptyFamInstEnv, env) fam_inst skol_tvs
\end{code}
+Note [Family instance overlap conflicts]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- In the case of data family instances, any overlap is fundamentally a
+ conflict (as these instances imply injective type mappings).
+
+- In the case of type family instances, overlap is admitted as long as
+ the right-hand sides of the overlapping rules coincide under the
+ overlap substitution. eg
+ type instance F a Int = a
+ type instance F Int b = b
+ These two overlap on (F Int Int) but then both RHSs are Int,
+ so all is well. We require that they are syntactically equal;
+ anything else would be difficult to test for at this stage.
+
+
While @lookupFamInstEnv@ uses a one-way match, the next function
@lookupFamInstEnvConflicts@ uses two-way matching (ie, unification). This is
needed to check for overlapping instances.
diff --git a/compiler/types/Kind.lhs b/compiler/types/Kind.lhs
index e5ef583c99..13585783e0 100644
--- a/compiler/types/Kind.lhs
+++ b/compiler/types/Kind.lhs
@@ -15,13 +15,14 @@ module Kind (
Kind, typeKind,
-- Kinds
- liftedTypeKind, unliftedTypeKind, openTypeKind,
+ anyKind, liftedTypeKind, unliftedTypeKind, openTypeKind,
argTypeKind, ubxTupleKind, constraintKind,
mkArrowKind, mkArrowKinds,
-- Kind constructors...
- liftedTypeKindTyCon, openTypeKindTyCon, unliftedTypeKindTyCon,
- argTypeKindTyCon, ubxTupleKindTyCon, constraintKindTyCon,
+ anyKindTyCon, liftedTypeKindTyCon, openTypeKindTyCon,
+ unliftedTypeKindTyCon, argTypeKindTyCon, ubxTupleKindTyCon,
+ constraintKindTyCon,
-- Super Kinds
tySuperKind, tySuperKindTyCon,
@@ -34,24 +35,38 @@ module Kind (
-- ** Predicates on Kinds
isLiftedTypeKind, isUnliftedTypeKind, isOpenTypeKind,
- isUbxTupleKind, isArgTypeKind, isConstraintKind, isKind, isTySuperKind,
- isSuperKind,
+ isUbxTupleKind, isArgTypeKind, isConstraintKind, isKind,
+ isSuperKind, noHashInKind,
isLiftedTypeKindCon, isConstraintKindCon,
+ isAnyKind, isAnyKindCon,
- isSubArgTypeKind, isSubOpenTypeKind, isSubKind, defaultKind,
- isSubKindCon,
+ isSubArgTypeKind, tcIsSubArgTypeKind,
+ isSubOpenTypeKind, tcIsSubOpenTypeKind,
+ isSubKind, defaultKind,
+ isSubKindCon, tcIsSubKindCon, isSubOpenTypeKindCon,
+
+ -- ** Functions on variables
+ isKiVar, splitKiTyVars, partitionKiTyVars,
+ kiVarsOfKind, kiVarsOfKinds,
+
+ -- ** Promotion related functions
+ promoteType, isPromotableType, isPromotableKind,
) where
#include "HsVersions.h"
-import {-# SOURCE #-} Type (typeKind)
+import {-# SOURCE #-} Type ( typeKind, substKiWith, eqKind )
import TypeRep
import TysPrim
import TyCon
+import Var
+import VarSet
import PrelNames
import Outputable
+
+import Data.List ( partition )
\end{code}
%************************************************************************
@@ -61,15 +76,23 @@ import Outputable
%************************************************************************
\begin{code}
-isTySuperKind :: SuperKind -> Bool
-isTySuperKind (TyConApp kc []) = kc `hasKey` tySuperKindTyConKey
-isTySuperKind _ = False
-
-------------------
-- Lastly we need a few functions on Kinds
isLiftedTypeKindCon :: TyCon -> Bool
isLiftedTypeKindCon tc = tc `hasKey` liftedTypeKindTyConKey
+
+-- This checks that its argument does not contain # or (#).
+-- It is used in tcTyVarBndrs.
+noHashInKind :: Kind -> Bool
+noHashInKind (TyVarTy {}) = True
+noHashInKind (FunTy k1 k2) = noHashInKind k1 && noHashInKind k2
+noHashInKind (ForAllTy _ ki) = noHashInKind ki
+noHashInKind (TyConApp kc kis)
+ = not (kc `hasKey` unliftedTypeKindTyConKey)
+ && not (kc `hasKey` ubxTupleKindTyConKey)
+ && all noHashInKind kis
+noHashInKind _ = panic "noHashInKind"
\end{code}
%************************************************************************
@@ -79,14 +102,15 @@ isLiftedTypeKindCon tc = tc `hasKey` liftedTypeKindTyConKey
%************************************************************************
\begin{code}
--- | Essentially 'funResultTy' on kinds
-kindFunResult :: Kind -> Kind
-kindFunResult (FunTy _ res) = res
-kindFunResult k = pprPanic "kindFunResult" (ppr k)
+-- | Essentially 'funResultTy' on kinds handling pi-types too
+kindFunResult :: Kind -> KindOrType -> Kind
+kindFunResult (FunTy _ res) _ = res
+kindFunResult (ForAllTy kv res) arg = substKiWith [kv] [arg] res
+kindFunResult k _ = pprPanic "kindFunResult" (ppr k)
-kindAppResult :: Kind -> [arg] -> Kind
+kindAppResult :: Kind -> [Type] -> Kind
kindAppResult k [] = k
-kindAppResult k (_:as) = kindAppResult (kindFunResult k) as
+kindAppResult k (a:as) = kindAppResult (kindFunResult k a) as
-- | Essentially 'splitFunTys' on kinds
splitKindFunTys :: Kind -> ([Kind],Kind)
@@ -110,12 +134,21 @@ splitKindFunTysN n k = pprPanic "splitKindFunTysN" (ppr n <+> ppr k)
-- Actually this function works fine on data types too,
-- but they'd always return '*', so we never need to ask
synTyConResKind :: TyCon -> Kind
-synTyConResKind tycon = kindAppResult (tyConKind tycon) (tyConTyVars tycon)
+synTyConResKind tycon = kindAppResult (tyConKind tycon) (map mkTyVarTy (tyConTyVars tycon))
-- | See "Type#kind_subtyping" for details of the distinction between these 'Kind's
-isUbxTupleKind, isOpenTypeKind, isArgTypeKind, isUnliftedTypeKind, isConstraintKind :: Kind -> Bool
+isUbxTupleKind, isOpenTypeKind, isArgTypeKind, isUnliftedTypeKind,
+ isConstraintKind, isAnyKind :: Kind -> Bool
+
isOpenTypeKindCon, isUbxTupleKindCon, isArgTypeKindCon,
- isUnliftedTypeKindCon, isSubArgTypeKindCon, isConstraintKindCon :: TyCon -> Bool
+ isUnliftedTypeKindCon, isSubArgTypeKindCon, tcIsSubArgTypeKindCon,
+ isSubOpenTypeKindCon, tcIsSubOpenTypeKindCon, isConstraintKindCon,
+ isAnyKindCon :: TyCon -> Bool
+
+isAnyKindCon tc = tyConUnique tc == anyKindTyConKey
+
+isAnyKind (TyConApp tc _) = isAnyKindCon tc
+isAnyKind _ = False
isOpenTypeKindCon tc = tyConUnique tc == openTypeKindTyConKey
@@ -142,16 +175,31 @@ isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey
isConstraintKind (TyConApp tc _) = isConstraintKindCon tc
isConstraintKind _ = False
-isSubOpenTypeKind :: Kind -> Bool
--- ^ True of any sub-kind of OpenTypeKind (i.e. anything except arrow)
-isSubOpenTypeKind (FunTy k1 k2) = ASSERT2 ( isKind k1, text "isSubOpenTypeKind" <+> ppr k1 <+> text "::" <+> ppr (typeKind k1) )
- ASSERT2 ( isKind k2, text "isSubOpenTypeKind" <+> ppr k2 <+> text "::" <+> ppr (typeKind k2) )
- False
-isSubOpenTypeKind (TyConApp kc []) = ASSERT( isKind (TyConApp kc []) ) True
-isSubOpenTypeKind other = ASSERT( isKind other ) False
- -- This is a conservative answer
- -- It matters in the call to isSubKind in
- -- checkExpectedKind.
+
+-- Subkinding
+-- The tc variants are used during type-checking, where we don't want the
+-- Constraint kind to be a subkind of anything
+-- After type-checking (in core), Constraint is a subkind of argTypeKind
+isSubOpenTypeKind, tcIsSubOpenTypeKind :: Kind -> Bool
+-- ^ True of any sub-kind of OpenTypeKind
+isSubOpenTypeKind (TyConApp kc []) = isSubOpenTypeKindCon kc
+isSubOpenTypeKind _ = False
+
+-- ^ True of any sub-kind of OpenTypeKind
+tcIsSubOpenTypeKind (TyConApp kc []) = tcIsSubOpenTypeKindCon kc
+tcIsSubOpenTypeKind _ = False
+
+isSubOpenTypeKindCon kc
+ | isSubArgTypeKindCon kc = True
+ | isUbxTupleKindCon kc = True
+ | isOpenTypeKindCon kc = True
+ | otherwise = False
+
+tcIsSubOpenTypeKindCon kc
+ | tcIsSubArgTypeKindCon kc = True
+ | isUbxTupleKindCon kc = True
+ | isOpenTypeKindCon kc = True
+ | otherwise = False
isSubArgTypeKindCon kc
| isUnliftedTypeKindCon kc = True
@@ -160,11 +208,18 @@ isSubArgTypeKindCon kc
| isConstraintKindCon kc = True
| otherwise = False
-isSubArgTypeKind :: Kind -> Bool
+tcIsSubArgTypeKindCon kc
+ | isConstraintKindCon kc = False
+ | otherwise = isSubArgTypeKindCon kc
+
+isSubArgTypeKind, tcIsSubArgTypeKind :: Kind -> Bool
-- ^ True of any sub-kind of ArgTypeKind
isSubArgTypeKind (TyConApp kc []) = isSubArgTypeKindCon kc
isSubArgTypeKind _ = False
+tcIsSubArgTypeKind (TyConApp kc []) = tcIsSubArgTypeKindCon kc
+tcIsSubArgTypeKind _ = False
+
-- | Is this a super-kind (i.e. a type-of-kinds)?
isSuperKind :: Type -> Bool
isSuperKind (TyConApp (skc) []) = isSuperKindTyCon skc
@@ -176,25 +231,44 @@ isKind k = isSuperKind (typeKind k)
isSubKind :: Kind -> Kind -> Bool
-- ^ @k1 \`isSubKind\` k2@ checks that @k1@ <: @k2@
-isSubKind (TyConApp kc1 []) (TyConApp kc2 []) = kc1 `isSubKindCon` kc2
-isSubKind (FunTy a1 r1) (FunTy a2 r2) = (a2 `isSubKind` a1) && (r1 `isSubKind` r2)
-isSubKind _ _ = False
+
+isSubKind (FunTy a1 r1) (FunTy a2 r2)
+ = (a2 `isSubKind` a1) && (r1 `isSubKind` r2)
+
+isSubKind k1@(TyConApp kc1 k1s) k2@(TyConApp kc2 k2s)
+ | isPromotedTypeTyCon kc1 || isPromotedTypeTyCon kc2
+ -- handles promoted kinds (List *, Nat, etc.)
+ = eqKind k1 k2
+
+ | isSuperKindTyCon kc1 || isSuperKindTyCon kc2
+ -- handles BOX
+ = ASSERT2( isSuperKindTyCon kc2 && null k1s && null k2s, ppr kc1 <+> ppr kc2 )
+ True
+
+ | otherwise = -- handles usual kinds (*, #, (#), etc.)
+ ASSERT2( null k1s && null k2s, ppr k1 <+> ppr k2 )
+ kc1 `isSubKindCon` kc2
+
+
+isSubKind k1 k2 = eqKind k1 k2
isSubKindCon :: TyCon -> TyCon -> Bool
-- ^ @kc1 \`isSubKindCon\` kc2@ checks that @kc1@ <: @kc2@
isSubKindCon kc1 kc2
- | isLiftedTypeKindCon kc1 && isLiftedTypeKindCon kc2 = True
- | isUnliftedTypeKindCon kc1 && isUnliftedTypeKindCon kc2 = True
- | isUbxTupleKindCon kc1 && isUbxTupleKindCon kc2 = True
- | isConstraintKindCon kc1 && isConstraintKindCon kc2 = True
- | isOpenTypeKindCon kc2 = True
- -- we already know kc1 is not a fun, its a TyCon
- | isArgTypeKindCon kc2 && isSubArgTypeKindCon kc1 = True
+ | kc1 == kc2 = True
+ | isSubArgTypeKindCon kc1 && isArgTypeKindCon kc2 = True
+ | isSubOpenTypeKindCon kc1 && isOpenTypeKindCon kc2 = True
| otherwise = False
+tcIsSubKindCon :: TyCon -> TyCon -> Bool
+tcIsSubKindCon kc1 kc2
+ | kc1 == kc2 = True
+ | isConstraintKindCon kc1 || isConstraintKindCon kc2 = False
+ | otherwise = isSubKindCon kc1 kc2
+
defaultKind :: Kind -> Kind
--- ^ Used when generalising: default kind ? and ?? to *. See "Type#kind_subtyping" for more
--- information on what that means
+-- ^ Used when generalising: default kind ? and ?? to *.
+-- See "Type#kind_subtyping" for more information on what that means
-- When we generalise, we make generic type variables whose kind is
-- simple (* or *->* etc). So generic type variables (other than
@@ -206,9 +280,78 @@ defaultKind :: Kind -> Kind
-- Not
-- f :: forall (a::??). a -> Bool
-- because that would allow a call like (f 3#) as well as (f True),
---and the calling conventions differ. This defaulting is done in TcMType.zonkTcTyVarBndr.
-defaultKind k
+-- and the calling conventions differ.
+-- This defaulting is done in TcMType.zonkTcTyVarBndr.
+defaultKind k
| isSubOpenTypeKind k = liftedTypeKind
- | isSubArgTypeKind k = liftedTypeKind
- | otherwise = k
-\end{code} \ No newline at end of file
+ | otherwise = k
+
+splitKiTyVars :: [TyVar] -> ([KindVar], [TyVar])
+-- Precondition: kind variables should precede type variables
+-- Postcondition: appending the two result lists gives the input!
+splitKiTyVars = span (isSuperKind . tyVarKind)
+
+partitionKiTyVars :: [TyVar] -> ([KindVar], [TyVar])
+partitionKiTyVars = partition (isSuperKind . tyVarKind)
+
+-- Checks if this "type or kind" variable is a kind variable
+isKiVar :: TyVar -> Bool
+isKiVar v = isSuperKind (varType v)
+
+-- Returns the free kind variables in a kind
+kiVarsOfKind :: Kind -> VarSet
+kiVarsOfKind = tyVarsOfType
+
+kiVarsOfKinds :: [Kind] -> VarSet
+kiVarsOfKinds = tyVarsOfTypes
+
+-- Datatype promotion
+isPromotableType :: Type -> Bool
+isPromotableType = go emptyVarSet
+ where
+ go vars (TyConApp tc tys) = ASSERT( not (isPromotedDataTyCon tc) ) all (go vars) tys
+ go vars (FunTy arg res) = all (go vars) [arg,res]
+ go vars (TyVarTy tvar) = tvar `elemVarSet` vars
+ go vars (ForAllTy tvar ty) = isPromotableTyVar tvar && go (vars `extendVarSet` tvar) ty
+ go _ _ = panic "isPromotableType" -- argument was not kind-shaped
+
+isPromotableTyVar :: TyVar -> Bool
+isPromotableTyVar = isLiftedTypeKind . varType
+
+-- | Promotes a type to a kind. Assumes the argument is promotable.
+promoteType :: Type -> Kind
+promoteType (TyConApp tc tys) = mkTyConApp (mkPromotedTypeTyCon tc)
+ (map promoteType tys)
+ -- T t1 .. tn ~~> 'T k1 .. kn where ti ~~> ki
+promoteType (FunTy arg res) = mkArrowKind (promoteType arg) (promoteType res)
+ -- t1 -> t2 ~~> k1 -> k2 where ti ~~> ki
+promoteType (TyVarTy tvar) = mkTyVarTy (promoteTyVar tvar)
+ -- a :: * ~~> a :: BOX
+promoteType (ForAllTy tvar ty) = ForAllTy (promoteTyVar tvar) (promoteType ty)
+ -- forall (a :: *). t ~~> forall (a :: BOX). k where t ~~> k
+promoteType _ = panic "promoteType" -- argument was not kind-shaped
+
+promoteTyVar :: TyVar -> KindVar
+promoteTyVar tvar = mkKindVar (tyVarName tvar) tySuperKind
+
+-- If kind is [ *^n -> * ] returns [ Just n ], else returns [ Nothing ]
+isPromotableKind :: Kind -> Maybe Int
+isPromotableKind kind =
+ let (args, res) = splitKindFunTys kind in
+ if all isLiftedTypeKind (res:args)
+ then Just $ length args
+ else Nothing
+
+{- Note [Promoting a Type to a Kind]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We only promote the followings.
+- Type variables: a
+- Fully applied arrow types: tau -> sigma
+- Fully applied type constructors of kind:
+ n >= 0
+ /-----------\
+ * -> ... -> * -> *
+- Polymorphic types over type variables of kind star:
+ forall (a::*). tau
+-}
+\end{code}
diff --git a/compiler/types/TyCon.lhs b/compiler/types/TyCon.lhs
index 6db746bc76..f8745e62fb 100644
--- a/compiler/types/TyCon.lhs
+++ b/compiler/types/TyCon.lhs
@@ -36,7 +36,8 @@ module TyCon(
mkSynTyCon,
mkSuperKindTyCon,
mkForeignTyCon,
- mkAnyTyCon,
+ mkPromotedDataTyCon,
+ mkPromotedTypeTyCon,
-- ** Predicates on TyCons
isAlgTyCon,
@@ -46,7 +47,8 @@ module TyCon(
isTupleTyCon, isUnboxedTupleTyCon, isBoxedTupleTyCon,
isSynTyCon, isClosedSynTyCon,
isSuperKindTyCon, isDecomposableTyCon,
- isForeignTyCon, isAnyTyCon, tyConHasKind,
+ isForeignTyCon, tyConHasKind,
+ isPromotedDataTyCon, isPromotedTypeTyCon,
isInjectiveTyCon,
isDataTyCon, isProductTyCon, isEnumerationTyCon,
@@ -90,7 +92,7 @@ module TyCon(
#include "HsVersions.h"
import {-# SOURCE #-} TypeRep ( Kind, Type, PredType )
-import {-# SOURCE #-} DataCon ( DataCon, isVanillaDataCon )
+import {-# SOURCE #-} DataCon ( DataCon, isVanillaDataCon, dataConName )
import {-# SOURCE #-} IParam ( ipTyConName )
import Var
@@ -341,7 +343,7 @@ data TyCon
tc_kind :: Kind,
tyConArity :: Arity,
- tyConTyVars :: [TyVar], -- ^ The type variables used in the type constructor.
+ tyConTyVars :: [TyVar], -- ^ The kind and type variables used in the type constructor.
-- Invariant: length tyvars = arity
-- Precisely, this list scopes over:
--
@@ -427,19 +429,6 @@ data TyCon
-- holds the name of the imported thing
}
- -- | Any types. Like tuples, this is a potentially-infinite family of TyCons
- -- one for each distinct Kind. They have no values at all.
- -- Because there are infinitely many of them (like tuples) they are
- -- defined in GHC.Prim and have names like "Any(*->*)".
- -- Their Unique is derived from the OccName.
- -- See Note [Any types] in TysPrim
- | AnyTyCon {
- tyConUnique :: Unique,
- tyConName :: Name,
- tc_kind :: Kind -- Never = *; that is done via PrimTyCon
- -- See Note [Any types] in TysPrim
- }
-
-- | Super-kinds. These are "kinds-of-kinds" and are never seen in
-- Haskell source programs. There are only two super-kinds: TY (aka
-- "box"), which is the super-kind of kinds that construct types
@@ -451,6 +440,23 @@ data TyCon
tyConUnique :: Unique,
tyConName :: Name
}
+
+ -- | Represents promoted data constructor.
+ | PromotedDataTyCon { -- See Note [Promoted data constructors]
+ tyConUnique :: Unique, -- ^ Same Unique as the data constructor
+ tyConName :: Name, -- ^ Same Name as the data constructor
+ tc_kind :: Kind, -- ^ Translated type of the data constructor
+ dataCon :: DataCon -- ^ Corresponding data constructor
+ }
+
+ -- | Represents promoted type constructor.
+ | PromotedTypeTyCon {
+ tyConUnique :: Unique, -- ^ Same Unique as the type constructor
+ tyConName :: Name, -- ^ Same Name as the type constructor
+ tyConArity :: Arity, -- ^ n if ty_con :: * -> ... -> * n times
+ ty_con :: TyCon -- ^ Corresponding type constructor
+ }
+
deriving Typeable
-- | Names of the fields in an algebraic record type
@@ -551,6 +557,7 @@ data TyConParent
NoParentTyCon
-- | Type constructors representing a class dictionary.
+ -- See Note [ATyCon for classes] in TypeRep
| ClassTyCon
Class -- INVARIANT: the classTyCon of this Class is the current tycon
@@ -619,6 +626,34 @@ data SynTyConRhs
| SynFamilyTyCon
\end{code}
+Note [Promoted data constructors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A data constructor can be promoted to become a type constructor,
+via the PromotedDataTyCon alternative in TyCon.
+
+* Only "vanilla" data constructors are promoted; ones with no GADT
+ stuff, no existentials, etc. We might generalise this later.
+
+* The TyCon promoted from a DataCon has the *same* Name and Unique as
+ the DataCon. Eg. If the data constructor Data.Maybe.Just(unique 78,
+ say) is promoted to a TyCon whose name is Data.Maybe.Just(unique 78)
+
+* The *kind* of a promoted DataCon may be polymorphic. Example:
+ type of DataCon Just :: forall (a:*). a -> Maybe a
+ kind of (promoted) tycon Just :: forall (a:box). a -> Maybe a
+ The kind is not identical to the type, because of the */box
+ kind signature on the forall'd variable; so the tc_kind field of
+ PromotedDataTyCon is not identical to the dataConUserType of the
+ DataCon. But it's the same modulo changing the variable kinds,
+ done by Kind.promoteType.
+
+* Small note: We promote the *user* type of the DataCon. Eg
+ data T = MkT {-# UNPACK #-} !(Bool, Bool)
+ The promoted kind is
+ MkT :: (Bool,Bool) -> T
+ *not*
+ MkT :: Bool -> Bool -> T
+
Note [Enumeration types]
~~~~~~~~~~~~~~~~~~~~~~~~
We define datatypes with no constructors to *not* be
@@ -933,12 +968,6 @@ mkSynTyCon name kind tyvars rhs parent
synTcParent = parent
}
-mkAnyTyCon :: Name -> Kind -> TyCon
-mkAnyTyCon name kind
- = AnyTyCon { tyConName = name,
- tc_kind = kind,
- tyConUnique = nameUnique name }
-
-- | Create a super-kind 'TyCon'
mkSuperKindTyCon :: Name -> TyCon -- Super kinds always have arity zero
mkSuperKindTyCon name
@@ -946,6 +975,27 @@ mkSuperKindTyCon name
tyConName = name,
tyConUnique = nameUnique name
}
+
+-- | Create a promoted data constructor 'TyCon'
+mkPromotedDataTyCon :: DataCon -> Name -> Unique -> Kind -> TyCon
+mkPromotedDataTyCon con name unique kind
+ = PromotedDataTyCon {
+ tyConName = name,
+ tyConUnique = unique,
+ tc_kind = kind,
+ dataCon = con
+ }
+
+-- | Create a promoted type constructor 'TyCon'
+mkPromotedTypeTyCon :: TyCon -> TyCon
+mkPromotedTypeTyCon con
+ = PromotedTypeTyCon {
+ tyConName = getName con,
+ tyConUnique = getUnique con,
+ tyConArity = tyConArity con,
+ ty_con = con
+ }
+
\end{code}
\begin{code}
@@ -1016,6 +1066,7 @@ isDistinctTyCon (AlgTyCon {algTcRhs = rhs}) = isDistinctAlgRhs rhs
isDistinctTyCon (FunTyCon {}) = True
isDistinctTyCon (TupleTyCon {}) = True
isDistinctTyCon (PrimTyCon {}) = True
+isDistinctTyCon (PromotedDataTyCon {}) = True
isDistinctTyCon _ = False
isDistinctAlgRhs :: AlgTyConRhs -> Bool
@@ -1178,10 +1229,15 @@ isSuperKindTyCon :: TyCon -> Bool
isSuperKindTyCon (SuperKindTyCon {}) = True
isSuperKindTyCon _ = False
--- | Is this an AnyTyCon?
-isAnyTyCon :: TyCon -> Bool
-isAnyTyCon (AnyTyCon {}) = True
-isAnyTyCon _ = False
+-- | Is this a PromotedDataTyCon?
+isPromotedDataTyCon :: TyCon -> Bool
+isPromotedDataTyCon (PromotedDataTyCon {}) = True
+isPromotedDataTyCon _ = False
+
+-- | Is this a PromotedTypeTyCon?
+isPromotedTypeTyCon :: TyCon -> Bool
+isPromotedTypeTyCon (PromotedTypeTyCon {}) = True
+isPromotedTypeTyCon _ = False
-- | Identifies implicit tycons that, in particular, do not go into interface
-- files (because they are implicitly reconstructed when the interface is
@@ -1249,12 +1305,12 @@ expand tvs rhs tys
\begin{code}
tyConKind :: TyCon -> Kind
-tyConKind (FunTyCon { tc_kind = k }) = k
-tyConKind (AlgTyCon { tc_kind = k }) = k
-tyConKind (TupleTyCon { tc_kind = k }) = k
-tyConKind (SynTyCon { tc_kind = k }) = k
-tyConKind (PrimTyCon { tc_kind = k }) = k
-tyConKind (AnyTyCon { tc_kind = k }) = k
+tyConKind (FunTyCon { tc_kind = k }) = k
+tyConKind (AlgTyCon { tc_kind = k }) = k
+tyConKind (TupleTyCon { tc_kind = k }) = k
+tyConKind (SynTyCon { tc_kind = k }) = k
+tyConKind (PrimTyCon { tc_kind = k }) = k
+tyConKind (PromotedDataTyCon { tc_kind = k }) = k
tyConKind tc = pprPanic "tyConKind" (ppr tc) -- SuperKindTyCon and CoTyCon
tyConHasKind :: TyCon -> Bool
@@ -1458,7 +1514,8 @@ instance Uniquable TyCon where
getUnique tc = tyConUnique tc
instance Outputable TyCon where
- ppr tc = ppr (getName tc)
+ ppr (PromotedDataTyCon {dataCon = dc}) = quote (ppr (dataConName dc))
+ ppr tc = ppr (getName tc)
instance NamedThing TyCon where
getName = tyConName
diff --git a/compiler/types/Type.lhs b/compiler/types/Type.lhs
index 69c31823ab..cb253d82fc 100644
--- a/compiler/types/Type.lhs
+++ b/compiler/types/Type.lhs
@@ -21,7 +21,7 @@ module Type (
-- $type_classification
-- $representation_types
- TyThing(..), Type, PredType, ThetaType,
+ TyThing(..), Type, KindOrType, PredType, ThetaType,
Var, TyVar, isTyVar,
-- ** Constructing and deconstructing types
@@ -34,11 +34,12 @@ module Type (
splitFunTys, splitFunTysN,
funResultTy, funArgTy, zipFunTys,
- mkTyConApp, mkTyConTy,
+ mkTyConApp, mkTyConTy,
tyConAppTyCon_maybe, tyConAppArgs_maybe, tyConAppTyCon, tyConAppArgs,
splitTyConApp_maybe, splitTyConApp,
mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys,
+ mkForAllArrowKinds,
applyTy, applyTys, applyTysD, isForAllTy, dropForAlls,
-- (Newtypes)
@@ -62,7 +63,7 @@ module Type (
funTyCon,
-- ** Predicates on types
- isTyVarTy, isFunTy, isDictTy, isPredTy,
+ isTyVarTy, isFunTy, isDictTy, isPredTy, isKindTy,
-- (Lifting and boxity)
isUnLiftedType, isUnboxedTupleType, isAlgType, isClosedAlgType,
@@ -70,24 +71,25 @@ module Type (
-- * Main data types representing Kinds
-- $kind_subtyping
- Kind, SimpleKind, KindVar,
+ Kind, SimpleKind, MetaKindVar,
-- ** Finding the kind of a type
typeKind,
-- ** Common Kinds and SuperKinds
- liftedTypeKind, unliftedTypeKind, openTypeKind,
+ anyKind, liftedTypeKind, unliftedTypeKind, openTypeKind,
argTypeKind, ubxTupleKind, constraintKind,
tySuperKind,
-- ** Common Kind type constructors
liftedTypeKindTyCon, openTypeKindTyCon, unliftedTypeKindTyCon,
argTypeKindTyCon, ubxTupleKindTyCon, constraintKindTyCon,
+ anyKindTyCon,
-- * Type free variables
tyVarsOfType, tyVarsOfTypes,
expandTypeSynonyms,
- typeSize,
+ typeSize, varSetElemsKvsFirst, sortQuantVars,
-- * Type comparison
eqType, eqTypeX, eqTypes, cmpType, cmpTypes,
@@ -121,17 +123,16 @@ module Type (
isInScope, composeTvSubst, zipTyEnv,
isEmptyTvSubst, unionTvSubst,
- -- ** Performing substitution on types
+ -- ** Performing substitution on types and kinds
substTy, substTys, substTyWith, substTysWith, substTheta,
substTyVar, substTyVars, substTyVarBndr,
- cloneTyVarBndr, deShadowTy, lookupTyVar,
+ cloneTyVarBndr, deShadowTy, lookupTyVar,
+ substKiWith, substKisWith,
-- * Pretty-printing
pprType, pprParendType, pprTypeApp, pprTyThingCategory, pprTyThing, pprForAll,
pprEqPred, pprTheta, pprThetaArrowTy, pprClassPred,
- pprKind, pprParendKind,
-
- pprSourceTyCon
+ pprKind, pprParendKind, pprSourceTyCon,
) where
#include "HsVersions.h"
@@ -139,7 +140,7 @@ module Type (
-- We import the representation and primitive functions from TypeRep.
-- Many things are reexported, but not the representation!
-import Kind ( kindAppResult, kindFunResult, isTySuperKind, isSubOpenTypeKind )
+import Kind
import TypeRep
-- friends:
@@ -151,7 +152,7 @@ import Class
import TyCon
import TysPrim
import {-# SOURCE #-} TysWiredIn ( eqTyCon, mkBoxedTupleTy )
-import PrelNames ( eqTyConKey, eqPrimTyConKey )
+import PrelNames ( eqTyConKey )
-- others
import {-# SOURCE #-} IParam ( ipTyCon )
@@ -674,6 +675,13 @@ mkForAllTy tyvar ty
mkForAllTys :: [TyVar] -> Type -> Type
mkForAllTys tyvars ty = foldr ForAllTy ty tyvars
+mkForAllArrowKinds :: [TyVar] -> Kind -> Kind
+-- mkForAllArrowKinds [k1, k2, (a:k1 -> *)] k2
+-- returns forall k1 k2. (k1 -> *) -> k2
+mkForAllArrowKinds ktvs res =
+ mkForAllTys kvs $ mkArrowKinds (map tyVarKind tvs) res
+ where (kvs, tvs) = splitKiTyVars ktvs
+
isForAllTy :: Type -> Bool
isForAllTy (ForAllTy _ _) = True
isForAllTy _ = False
@@ -715,12 +723,12 @@ applyTy, applyTys
--
-- We use @applyTys type-of-f [t1,t2]@ to compute the type of the expression.
-- Panics if no application is possible.
-applyTy :: Type -> Type -> Type
+applyTy :: Type -> KindOrType -> Type
applyTy ty arg | Just ty' <- coreView ty = applyTy ty' arg
applyTy (ForAllTy tv ty) arg = substTyWith [tv] [arg] ty
applyTy _ _ = panic "applyTy"
-applyTys :: Type -> [Type] -> Type
+applyTys :: Type -> [KindOrType] -> Type
-- ^ This function is interesting because:
--
-- 1. The function may have more for-alls than there are args
@@ -731,12 +739,12 @@ applyTys :: Type -> [Type] -> Type
--
-- > applyTys (forall a.a) [forall b.b, Int]
--
--- This really can happen, via dressing up polymorphic types with newtype
--- clothing. Here's an example:
---
--- > newtype R = R (forall a. a->a)
--- > foo = case undefined :: R of
--- > R f -> f ()
+-- This really can happen, but only (I think) in situations involving
+-- undefined. For example:
+-- undefined :: forall a. a
+-- Term: undefined @(forall b. b->b) @Int
+-- This term should have type (Int -> Int), but notice that
+-- there are more type args than foralls in 'undefined's type.
applyTys ty args = applyTysD empty ty args
@@ -776,7 +784,12 @@ noParenPred :: PredType -> Bool
noParenPred p = isClassPred p || isEqPred p
isPredTy :: Type -> Bool
-isPredTy ty = typeKind ty `eqKind` constraintKind
+isPredTy ty
+ | isSuperKind ty = False
+ | otherwise = typeKind ty `eqKind` constraintKind
+
+isKindTy :: Type -> Bool
+isKindTy = isSuperKind . typeKind
isClassPred, isEqPred, isIPPred :: PredType -> Bool
isClassPred ty = case tyConAppTyCon_maybe ty of
@@ -796,10 +809,16 @@ Make PredTypes
\begin{code}
-- | Creates a type equality predicate
mkEqPred :: (Type, Type) -> PredType
-mkEqPred (ty1, ty2) = TyConApp eqTyCon [ty1, ty2]
+mkEqPred (ty1, ty2)
+ -- IA0_TODO: The caller should give the kind.
+ = TyConApp eqTyCon [k, ty1, ty2]
+ where k = defaultKind (typeKind ty1)
mkPrimEqType :: (Type, Type) -> Type
-mkPrimEqType (ty1, ty2) = TyConApp eqPrimTyCon [ty1, ty2]
+mkPrimEqType (ty1, ty2)
+ -- IA0_TODO: The caller should give the kind.
+ = TyConApp eqPrimTyCon [k, ty1, ty2]
+ where k = defaultKind (typeKind ty1)
\end{code}
--------------------- Implicit parameters ---------------------------------
@@ -877,7 +896,7 @@ classifyPredType ev_ty = case splitTyConApp_maybe ev_ty of
Just (tc, tys) | Just clas <- tyConClass_maybe tc
-> ClassPred clas tys
Just (tc, tys) | tc `hasKey` eqTyConKey
- , let [ty1, ty2] = tys
+ , let [_, ty1, ty2] = tys
-> EqPred ty1 ty2
Just (tc, tys) | Just ip <- tyConIP_maybe tc
, let [ty] = tys
@@ -905,7 +924,7 @@ getEqPredTys ty = case getEqPredTys_maybe ty of
getEqPredTys_maybe :: PredType -> Maybe (Type, Type)
getEqPredTys_maybe ty = case splitTyConApp_maybe ty of
- Just (tc, [ty1, ty2]) | tc `hasKey` eqTyConKey -> Just (ty1, ty2)
+ Just (tc, [_, ty1, ty2]) | tc `hasKey` eqTyConKey -> Just (ty1, ty2)
_ -> Nothing
getIPPredTy_maybe :: PredType -> Maybe (IPName Name, Type)
@@ -927,6 +946,26 @@ typeSize (AppTy t1 t2) = typeSize t1 + typeSize t2
typeSize (FunTy t1 t2) = typeSize t1 + typeSize t2
typeSize (ForAllTy _ t) = 1 + typeSize t
typeSize (TyConApp _ ts) = 1 + sum (map typeSize ts)
+
+varSetElemsKvsFirst :: VarSet -> [TyVar]
+-- {k1,a,k2,b} --> [k1,k2,a,b]
+varSetElemsKvsFirst set = uncurry (++) $ partitionKiTyVars (varSetElems set)
+
+sortQuantVars :: [Var] -> [Var]
+-- Sort the variables so the true kind then type variables come first
+sortQuantVars = sortLe le
+ where
+ v1 `le` v2 = case (is_tv v1, is_tv v2) of
+ (True, False) -> True
+ (False, True) -> False
+ (True, True) ->
+ case (is_kv v1, is_kv v2) of
+ (True, False) -> True
+ (False, True) -> False
+ _ -> v1 <= v2 -- Same family
+ (False, False) -> v1 <= v2
+ is_tv v = isTyVar v
+ is_kv v = isSuperKind (tyVarKind v)
\end{code}
@@ -1158,6 +1197,29 @@ cmpTypesX _ [] _ = LT
cmpTypesX _ _ [] = GT
\end{code}
+Note [cmpTypeX]
+~~~~~~~~~~~~~~~
+
+When we compare foralls, we should look at the kinds. But if we do so,
+we get a corelint error like the following (in
+libraries/ghc-prim/GHC/PrimopWrappers.hs):
+
+ Binder's type: forall (o_abY :: *).
+ o_abY
+ -> GHC.Prim.State# GHC.Prim.RealWorld
+ -> GHC.Prim.State# GHC.Prim.RealWorld
+ Rhs type: forall (a_12 :: ?).
+ a_12
+ -> GHC.Prim.State# GHC.Prim.RealWorld
+ -> GHC.Prim.State# GHC.Prim.RealWorld
+
+This is why we don't look at the kind. Maybe we should look if the
+kinds are compatible.
+
+-- cmpTypeX env (ForAllTy tv1 t1) (ForAllTy tv2 t2)
+-- = cmpTypeX env (tyVarKind tv1) (tyVarKind tv2) `thenCmp`
+-- cmpTypeX (rnBndr2 env tv1 tv2) t1 t2
+
%************************************************************************
%* *
Type substitutions
@@ -1308,7 +1370,7 @@ instance Outputable TvSubst where
%************************************************************************
%* *
- Performing type substitutions
+ Performing type or kind substitutions
%* *
%************************************************************************
@@ -1319,12 +1381,18 @@ substTyWith :: [TyVar] -> [Type] -> Type -> Type
substTyWith tvs tys = ASSERT( length tvs == length tys )
substTy (zipOpenTvSubst tvs tys)
+substKiWith :: [KindVar] -> [Kind] -> Kind -> Kind
+substKiWith = substTyWith
+
-- | Type substitution making use of an 'TvSubst' that
-- is assumed to be open, see 'zipOpenTvSubst'
substTysWith :: [TyVar] -> [Type] -> [Type] -> [Type]
substTysWith tvs tys = ASSERT( length tvs == length tys )
substTys (zipOpenTvSubst tvs tys)
+substKisWith :: [KindVar] -> [Kind] -> [Kind] -> [Kind]
+substKisWith = substTysWith
+
-- | Substitute within a 'Type'
substTy :: TvSubst -> Type -> Type
substTy subst ty | isEmptyTvSubst subst = ty
@@ -1397,7 +1465,9 @@ substTyVarBndr subst@(TvSubst in_scope tenv) old_var
_no_capture = not (new_var `elemVarSet` tyVarsOfTypes (varEnvElts tenv))
-- Assertion check that we are not capturing something in the substitution
- no_change = new_var == old_var
+ old_ki = tyVarKind old_var
+ no_kind_change = isEmptyVarSet (tyVarsOfType old_ki) -- verify that kind is closed
+ no_change = no_kind_change && (new_var == old_var)
-- no_change means that the new_var is identical in
-- all respects to the old_var (same unique, same kind)
-- See Note [Extending the TvSubst]
@@ -1408,7 +1478,8 @@ substTyVarBndr subst@(TvSubst in_scope tenv) old_var
-- (\x.e) with id_subst = [x |-> e']
-- Here we must simply zap the substitution for x
- new_var = uniqAway in_scope old_var
+ new_var | no_kind_change = uniqAway in_scope old_var
+ | otherwise = uniqAway in_scope $ updateTyVarKind (substTy subst) old_var
-- The uniqAway part makes sure the new variable is not already in scope
cloneTyVarBndr :: TvSubst -> TyVar -> Unique -> (TvSubst, TyVar)
@@ -1454,9 +1525,9 @@ Kinds
--
-- Where in the last example @t :: ??@ (i.e. is not an unboxed tuple)
-type KindVar = TyVar -- invariant: KindVar will always be a
- -- TcTyVar with details MetaTv TauTv ...
--- kind var constructors and functions are in TcType
+type MetaKindVar = TyVar -- invariant: MetaKindVar will always be a
+ -- TcTyVar with details MetaTv TauTv ...
+-- meta kind var constructors and functions are in TcType
type SimpleKind = Kind
\end{code}
@@ -1469,13 +1540,13 @@ type SimpleKind = Kind
\begin{code}
typeKind :: Type -> Kind
-typeKind ty@(TyConApp tc tys)
- = ASSERT2( not (tc `hasKey` eqPrimTyConKey) || length tys == 2, ppr ty )
- -- Assertion checks for unsaturated application of ~#
- -- See Note [The ~# TyCon] in TysPrim
- kindAppResult (tyConKind tc) tys
+typeKind (TyConApp tc tys)
+ | isPromotedTypeTyCon tc
+ = ASSERT( tyConArity tc == length tys ) tySuperKind
+ | otherwise
+ = kindAppResult (tyConKind tc) tys
-typeKind (AppTy fun _) = kindFunResult (typeKind fun)
+typeKind (AppTy fun arg) = kindAppResult (typeKind fun) [arg]
typeKind (ForAllTy _ ty) = typeKind ty
typeKind (TyVarTy tyvar) = tyVarKind tyvar
typeKind (FunTy _arg res)
@@ -1484,8 +1555,8 @@ typeKind (FunTy _arg res)
-- The only things that can be after a function arrow are
-- (a) types (of kind openTypeKind or its sub-kinds)
-- (b) kinds (of super-kind TY) (e.g. * -> (* -> *))
- | isTySuperKind k = k
- | otherwise = ASSERT( isSubOpenTypeKind k) liftedTypeKind
+ | isSuperKind k = k
+ | otherwise = ASSERT( isSubOpenTypeKind k ) liftedTypeKind
where
k = typeKind res
diff --git a/compiler/types/Type.lhs-boot b/compiler/types/Type.lhs-boot
index c9378fb214..c2d2dec093 100644
--- a/compiler/types/Type.lhs-boot
+++ b/compiler/types/Type.lhs-boot
@@ -1,9 +1,12 @@
\begin{code}
module Type where
import {-# SOURCE #-} TypeRep( Type, Kind )
+import Var
noParenPred :: Type -> Bool
isPredTy :: Type -> Bool
typeKind :: Type -> Kind
+substKiWith :: [KindVar] -> [Kind] -> Kind -> Kind
+eqKind :: Kind -> Kind -> Bool
\end{code}
diff --git a/compiler/types/TypeRep.lhs b/compiler/types/TypeRep.lhs
index 31664dcf5d..ea95c606ae 100644
--- a/compiler/types/TypeRep.lhs
+++ b/compiler/types/TypeRep.lhs
@@ -18,7 +18,7 @@
module TypeRep (
TyThing(..),
Type(..),
- Kind, SuperKind,
+ KindOrType, Kind, SuperKind,
PredType, ThetaType, -- Synonyms
-- Functions over types
@@ -117,7 +117,7 @@ to cut all loops. The other members of the loop may be marked 'non-recursive'.
\begin{code}
-- | The key representation of types within the compiler
data Type
- = TyVarTy TyVar -- ^ Vanilla type variable (*never* a coercion variable)
+ = TyVarTy Var -- ^ Vanilla type or kind variable (*never* a coercion variable)
| AppTy
Type
@@ -130,7 +130,7 @@ data Type
| TyConApp
TyCon
- [Type] -- ^ Application of a 'TyCon', including newtypes /and/ synonyms.
+ [KindOrType] -- ^ Application of a 'TyCon', including newtypes /and/ synonyms.
-- Invariant: saturated appliations of 'FunTyCon' must
-- use 'FunTy' and saturated synonyms must use their own
-- constructors. However, /unsaturated/ 'FunTyCon's
@@ -151,11 +151,13 @@ data Type
-- See Note [Equality-constrained types]
| ForAllTy
- TyVar -- Type variable
+ Var -- Type or kind variable
Type -- ^ A polymorphic type
deriving (Data.Data, Data.Typeable)
+type KindOrType = Type -- See Note [Arguments to type constructors]
+
-- | The key type representing kinds in the compiler.
-- Invariant: a kind is always in one of these forms:
--
@@ -172,6 +174,30 @@ type Kind = Type
type SuperKind = Type
\end{code}
+
+Note [Arguments to type constructors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Because of kind polymorphism, in addition to type application we now
+have kind instantiation. We reuse the same notations to do so.
+
+For example:
+
+ Just (* -> *) Maybe
+ Right * Nat Zero
+
+are represented by:
+
+ TyConApp (PromotedDataCon Just) [* -> *, Maybe]
+ TyConApp (PromotedDataCon Right) [*, Nat, (PromotedDataCon Zero)]
+
+Important note: Nat is used as a *kind* and not as a type. This can be
+confusing, since type-level Nat and kind-level Nat are identical. We
+use the kind of (PromotedDataCon Right) to know if its arguments are
+kinds or types.
+
+This kind instantiation only happens in TyConApp currently.
+
+
Note [Equality-constrained types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The type forall ab. (a ~ [b]) => blah
@@ -266,9 +292,12 @@ isLiftedTypeKind _ = False
%* *
%************************************************************************
-\begin{code}
+\begin{code}
tyVarsOfType :: Type -> VarSet
-- ^ NB: for type synonyms tyVarsOfType does /not/ expand the synonym
+-- tyVarsOfType returns only the free *type* variables of a type
+-- For example, tyVarsOfType (a::k) returns {a}, not including the
+-- kind variable {k}
tyVarsOfType (TyVarTy v) = unitVarSet v
tyVarsOfType (TyConApp _ tys) = tyVarsOfTypes tys
tyVarsOfType (FunTy arg res) = tyVarsOfType arg `unionVarSet` tyVarsOfType res
@@ -289,13 +318,22 @@ Despite the fact that DataCon has to be imported via a hi-boot route,
this module seems the right place for TyThing, because it's needed for
funTyCon and all the types in TysPrim.
+Note [ATyCon for classes]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Both classes and type constructors are represented in the type environment
+as ATyCon. You can tell the difference, and get to the class, with
+ isClassTyCon :: TyCon -> Bool
+ tyConClass_maybe :: TyCon -> Maybe Class
+The Class and its associated TyCon have the same Name.
+
\begin{code}
-- | A typecheckable-thing, essentially anything that has a name
-data TyThing = AnId Id
- | ADataCon DataCon
- | ATyCon TyCon
- | ACoAxiom CoAxiom
- deriving (Eq, Ord)
+data TyThing
+ = AnId Id
+ | ADataCon DataCon
+ | ATyCon TyCon -- TyCons and classes; see Note [ATyCon for classes]
+ | ACoAxiom CoAxiom
+ deriving (Eq, Ord)
instance Outputable TyThing where
ppr = pprTyThing
@@ -343,12 +381,13 @@ instance NamedThing TyThing where -- Can't put this with the type
-- 3. The substition is only applied ONCE! This is because
-- in general such application will not reached a fixed point.
data TvSubst
- = TvSubst InScopeSet -- The in-scope type variables
- TvSubstEnv -- Substitution of types
+ = TvSubst InScopeSet -- The in-scope type and kind variables
+ TvSubstEnv -- Substitutes both type and kind variables
-- See Note [Apply Once]
-- and Note [Extending the TvSubstEnv]
-- | A substitition of 'Type's for 'TyVar's
+-- and 'Kind's for 'KindVar's
type TvSubstEnv = TyVarEnv Type
-- A TvSubstEnv is used both inside a TvSubst (with the apply-once
-- invariant discussed in Note [Apply Once]), and also independently
@@ -591,7 +630,7 @@ pprTcApp p pp tc tys
= tupleParens (tupleTyConSort tc) (sep (punctuate comma (map (pp TopPrec) tys)))
| tc `hasKey` eqTyConKey -- We need to special case the type equality TyCon because
-- its not a SymOcc so won't get printed infix
- , [ty1,ty2] <- tys
+ , [_, ty1,ty2] <- tys
= pprInfixApp p pp (getName tc) ty1 ty2
| otherwise
= pprTypeNameApp p pp (getName tc) tys
diff --git a/compiler/types/TypeRep.lhs-boot b/compiler/types/TypeRep.lhs-boot
index 05c9d9b7cd..aef7067ca7 100644
--- a/compiler/types/TypeRep.lhs-boot
+++ b/compiler/types/TypeRep.lhs-boot
@@ -8,6 +8,7 @@ data TyThing
type PredType = Type
type Kind = Type
+type SuperKind = Type
instance Outputable Type
\end{code}
diff --git a/compiler/types/Unify.lhs b/compiler/types/Unify.lhs
index 575bcfbeea..9a8cafc9ec 100644
--- a/compiler/types/Unify.lhs
+++ b/compiler/types/Unify.lhs
@@ -41,8 +41,6 @@ import ErrUtils
import Util
import Maybes
import FastString
-
-import Control.Monad (guard)
\end{code}
@@ -175,7 +173,7 @@ match menv subst (TyVarTy tv1) ty2
| tv1' `elemVarSet` me_tmpls menv
= if any (inRnEnvR rn_env) (varSetElems (tyVarsOfType ty2))
then Nothing -- Occurs check
- else do { subst1 <- match_kind menv subst tv1 ty2
+ else do { subst1 <- match_kind menv subst (tyVarKind tv1) (typeKind ty2)
-- Note [Matching kinds]
; return (extendVarEnv subst1 tv1' ty2) }
@@ -188,7 +186,8 @@ match menv subst (TyVarTy tv1) ty2
tv1' = rnOccL rn_env tv1
match menv subst (ForAllTy tv1 ty1) (ForAllTy tv2 ty2)
- = match menv' subst ty1 ty2
+ = do { subst' <- match_kind menv subst (tyVarKind tv1) (tyVarKind tv2)
+ ; match menv' subst' ty1 ty2 }
where -- Use the magic of rnBndr2 to go under the binders
menv' = menv { me_env = rnBndr2 (me_env menv) tv1 tv2 }
@@ -207,11 +206,15 @@ match _ _ _ _
= Nothing
--------------
-match_kind :: MatchEnv -> TvSubstEnv -> TyVar -> Type -> Maybe TvSubstEnv
+match_kind :: MatchEnv -> TvSubstEnv -> Kind -> Kind -> Maybe TvSubstEnv
-- Match the kind of the template tyvar with the kind of Type
-- Note [Matching kinds]
-match_kind _ subst tv ty
- = guard (typeKind ty `isSubKind` tyVarKind tv) >> return subst
+match_kind menv subst k1 k2
+ | k2 `isSubKind` k1
+ = return subst
+
+ | otherwise
+ = match menv subst k1 k2
-- Note [Matching kinds]
-- ~~~~~~~~~~~~~~~~~~~~~
@@ -509,25 +512,29 @@ uUnrefined subst tv1 ty2 (TyVarTy tv2)
| Just ty' <- lookupVarEnv subst tv2
= uUnrefined subst tv1 ty' ty'
+ | otherwise
-- So both are unrefined; next, see if the kinds force the direction
- | eqKind k1 k2 -- Can update either; so check the bind-flags
- = do { b1 <- tvBindFlag tv1
- ; b2 <- tvBindFlag tv2
- ; case (b1,b2) of
- (BindMe, _) -> bind tv1 ty2
- (Skolem, Skolem) -> failWith (misMatch ty1 ty2)
- (Skolem, _) -> bind tv2 ty1
- }
-
- | k1 `isSubKind` k2 = bindTv subst tv2 ty1 -- Must update tv2
- | k2 `isSubKind` k1 = bindTv subst tv1 ty2 -- Must update tv1
-
- | otherwise = failWith (kindMisMatch tv1 ty2)
- where
- ty1 = TyVarTy tv1
- k1 = tyVarKind tv1
- k2 = tyVarKind tv2
- bind tv ty = return $ extendVarEnv subst tv ty
+ = case (k1_sub_k2, k2_sub_k1) of
+ (True, True) -> choose subst
+ (True, False) -> bindTv subst tv2 ty1
+ (False, True) -> bindTv subst tv1 ty2
+ (False, False) -> do
+ { subst' <- unify subst k1 k2
+ ; choose subst' }
+ where subst_kind = mkTvSubst (mkInScopeSet (tyVarsOfTypes [k1,k2])) subst
+ k1 = substTy subst_kind (tyVarKind tv1)
+ k2 = substTy subst_kind (tyVarKind tv2)
+ k1_sub_k2 = k1 `isSubKind` k2
+ k2_sub_k1 = k2 `isSubKind` k1
+ ty1 = TyVarTy tv1
+ bind subst tv ty = return $ extendVarEnv subst tv ty
+ choose subst = do
+ { b1 <- tvBindFlag tv1
+ ; b2 <- tvBindFlag tv2
+ ; case (b1, b2) of
+ (BindMe, _) -> bind subst tv1 ty2
+ (Skolem, Skolem) -> failWith (misMatch ty1 ty2)
+ (Skolem, _) -> bind subst tv2 ty1 }
uUnrefined subst tv1 ty2 ty2' -- ty2 is not a type variable
| tv1 `elemVarSet` niSubstTvSet subst (tyVarsOfType ty2')
diff --git a/compiler/utils/Binary.hs b/compiler/utils/Binary.hs
index afbb665b46..bfddf5b322 100644
--- a/compiler/utils/Binary.hs
+++ b/compiler/utils/Binary.hs
@@ -447,20 +447,30 @@ instance (Binary a, Binary b, Binary c) => Binary (a,b,c) where
instance (Binary a, Binary b, Binary c, Binary d) => Binary (a,b,c,d) where
put_ bh (a,b,c,d) = do put_ bh a; put_ bh b; put_ bh c; put_ bh d
- get bh = do a <- get bh
- b <- get bh
- c <- get bh
- d <- get bh
- return (a,b,c,d)
+ get bh = do a <- get bh
+ b <- get bh
+ c <- get bh
+ d <- get bh
+ return (a,b,c,d)
instance (Binary a, Binary b, Binary c, Binary d, Binary e) => Binary (a,b,c,d, e) where
put_ bh (a,b,c,d, e) = do put_ bh a; put_ bh b; put_ bh c; put_ bh d; put_ bh e;
- get bh = do a <- get bh
- b <- get bh
- c <- get bh
- d <- get bh
- e <- get bh
- return (a,b,c,d,e)
+ get bh = do a <- get bh
+ b <- get bh
+ c <- get bh
+ d <- get bh
+ e <- get bh
+ return (a,b,c,d,e)
+
+instance (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f) => Binary (a,b,c,d, e, f) where
+ put_ bh (a,b,c,d, e, f) = do put_ bh a; put_ bh b; put_ bh c; put_ bh d; put_ bh e; put_ bh f;
+ get bh = do a <- get bh
+ b <- get bh
+ c <- get bh
+ d <- get bh
+ e <- get bh
+ f <- get bh
+ return (a,b,c,d,e,f)
instance Binary a => Binary (Maybe a) where
put_ bh Nothing = putByte bh 0
diff --git a/compiler/utils/Outputable.lhs b/compiler/utils/Outputable.lhs
index d69e8ada63..60fbe5b29a 100644
--- a/compiler/utils/Outputable.lhs
+++ b/compiler/utils/Outputable.lhs
@@ -30,7 +30,7 @@ module Outputable (
char,
text, ftext, ptext,
int, integer, float, double, rational,
- parens, cparen, brackets, braces, quotes, doubleQuotes, angleBrackets,
+ parens, cparen, brackets, braces, quotes, quote, doubleQuotes, angleBrackets,
semi, comma, colon, dcolon, space, equals, dot, arrow, darrow,
lparen, rparen, lbrack, rbrack, lbrace, rbrace, underscore,
blankLine,
@@ -449,11 +449,12 @@ float n = docToSDoc $ Pretty.float n
double n = docToSDoc $ Pretty.double n
rational n = docToSDoc $ Pretty.rational n
-parens, braces, brackets, quotes, doubleQuotes, angleBrackets :: SDoc -> SDoc
+parens, braces, brackets, quotes, quote, doubleQuotes, angleBrackets :: SDoc -> SDoc
parens d = SDoc $ Pretty.parens . runSDoc d
braces d = SDoc $ Pretty.braces . runSDoc d
brackets d = SDoc $ Pretty.brackets . runSDoc d
+quote d = SDoc $ Pretty.quote . runSDoc d
doubleQuotes d = SDoc $ Pretty.doubleQuotes . runSDoc d
angleBrackets d = char '<' <> d <> char '>'
diff --git a/compiler/utils/Pretty.lhs b/compiler/utils/Pretty.lhs
index 0493daabee..cc8f235f2c 100644
--- a/compiler/utils/Pretty.lhs
+++ b/compiler/utils/Pretty.lhs
@@ -106,7 +106,7 @@ Relative to John's original paper, there are the following new features:
These new ones do the obvious things:
char, semi, comma, colon, space,
parens, brackets, braces,
- quotes, doubleQuotes
+ quotes, quote, doubleQuotes
4. The "above" combinator, $$, now overlaps its two arguments if the
last line of the top argument stops before the first line of the second begins.
@@ -165,7 +165,7 @@ module Pretty (
char, text, ftext, ptext, zeroWidthText,
int, integer, float, double, rational,
- parens, brackets, braces, quotes, doubleQuotes,
+ parens, brackets, braces, quotes, quote, doubleQuotes,
semi, comma, colon, space, equals,
lparen, rparen, lbrack, rbrack, lbrace, rbrace, cparen,
@@ -233,8 +233,8 @@ char :: Char -> Doc
semi, comma, colon, space, equals :: Doc
lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Doc
-parens, brackets, braces :: Doc -> Doc
-quotes, doubleQuotes :: Doc -> Doc
+parens, brackets, braces :: Doc -> Doc
+quotes, quote, doubleQuotes :: Doc -> Doc
int :: Int -> Doc
integer :: Integer -> Doc
@@ -409,6 +409,7 @@ rational n = text (show (fromRat n :: Double))
--rational n = text (show (fromRationalX n)) -- _showRational 30 n)
quotes p = char '`' <> p <> char '\''
+quote p = char '\'' <> p
doubleQuotes p = char '"' <> p <> char '"'
parens p = char '(' <> p <> char ')'
brackets p = char '[' <> p <> char ']'
diff --git a/compiler/vectorise/Vectorise/Builtins/Initialise.hs b/compiler/vectorise/Vectorise/Builtins/Initialise.hs
index 76f79bcec3..6c26f099d7 100644
--- a/compiler/vectorise/Vectorise/Builtins/Initialise.hs
+++ b/compiler/vectorise/Vectorise/Builtins/Initialise.hs
@@ -30,9 +30,7 @@ import Data.Array
--
initBuiltins :: DsM Builtins
initBuiltins
- = do { assertDAPPLoaded -- complain if 'Data.Array.Parallel.Prim' is not available
-
- -- 'PArray': desugared array type
+ = do { -- 'PArray': desugared array type
; parrayTyCon <- externalTyCon (fsLit "PArray")
; parray_tcs <- mapM externalTyCon (suffixed "PArray" aLL_DPH_PRIM_TYCONS)
; let parray_PrimTyCons = mkNameEnv (zip aLL_DPH_PRIM_TYCONS parray_tcs)
@@ -206,19 +204,19 @@ initBuiltinTyCons bi
-- Lookup a variable given its name and the module that contains it.
--
externalVar :: FastString -> DsM Var
-externalVar fs = lookupDAPPRdrEnv (mkVarOccFS fs) >>= dsLookupGlobalId
+externalVar fs = dsLookupDPHRdrEnv (mkVarOccFS fs) >>= dsLookupGlobalId
-- Like `externalVar` but wrap the `Var` in a `CoreExpr`.
--
externalFun :: FastString -> DsM CoreExpr
-externalFun fs = liftM Var $ externalVar fs
+externalFun fs = Var <$> externalVar fs
-- Lookup a 'TyCon' in 'Data.Array.Parallel.Prim', given its name.
--
externalTyCon :: FastString -> DsM TyCon
-externalTyCon fs = lookupDAPPRdrEnv (mkTcOccFS fs) >>= dsLookupTyCon
+externalTyCon fs = dsLookupDPHRdrEnv (mkTcOccFS fs) >>= dsLookupTyCon
--- Lookup some `Type` given its name and the module that contains it.
+-- Lookup some `Type` in 'Data.Array.Parallel.Prim', given its name.
--
externalType :: FastString -> DsM Type
externalType fs
@@ -229,7 +227,7 @@ externalType fs
--
externalClass :: FastString -> DsM Class
externalClass fs
- = do { tycon <- lookupDAPPRdrEnv (mkClsOccFS fs) >>= dsLookupTyCon
+ = do { tycon <- dsLookupDPHRdrEnv (mkClsOccFS fs) >>= dsLookupTyCon
; case tyConClass_maybe tycon of
Nothing -> pprPanic "Vectorise.Builtins.Initialise" $
ptext (sLit "Data.Array.Parallel.Prim.") <>
diff --git a/compiler/vectorise/Vectorise/Env.hs b/compiler/vectorise/Vectorise/Env.hs
index 2de71a5e3f..0020d67412 100644
--- a/compiler/vectorise/Vectorise/Env.hs
+++ b/compiler/vectorise/Vectorise/Env.hs
@@ -21,6 +21,7 @@ import InstEnv
import FamInstEnv
import CoreSyn
import Type
+import Class
import TyCon
import DataCon
import VarEnv
@@ -31,15 +32,20 @@ import Name
import NameEnv
import FastString
+import Data.Maybe
--- | Indicates what scope something (a variable) is in.
+
+-- |Indicates what scope something (a variable) is in.
+--
data Scope a b
= Global a
| Local b
-- LocalEnv -------------------------------------------------------------------
--- | The local environment.
+
+-- |The local environment.
+--
data LocalEnv
= LocalEnv {
-- Mapping from local variables to their vectorised and lifted versions.
@@ -55,8 +61,8 @@ data LocalEnv
, local_bind_name :: FastString
}
-
--- | Create an empty local environment.
+-- |Create an empty local environment.
+--
emptyLocalEnv :: LocalEnv
emptyLocalEnv = LocalEnv {
local_vars = emptyVarEnv
@@ -188,6 +194,8 @@ setPRFunsEnv ps genv = genv { global_pr_funs = mkNameEnv ps }
-- data constructors referenced in VECTORISE pragmas, even if they are defined in an imported
-- module.
--
+-- The variables explicitly include class selectors and dfuns.
+--
modVectInfo :: GlobalEnv -> [Id] -> [TyCon] -> [CoreVect]-> VectInfo -> VectInfo
modVectInfo env mg_ids mg_tyCons vectDecls info
= info
@@ -198,13 +206,17 @@ modVectInfo env mg_ids mg_tyCons vectDecls info
, vectInfoScalarTyCons = global_scalar_tycons env `minusNameSet` vectInfoScalarTyCons info
}
where
- vectIds = [id | Vect id _ <- vectDecls]
- vectTypeTyCons = [tycon | VectType _ tycon _ <- vectDecls] ++
- [tycon | VectClass tycon <- vectDecls]
- vectDataCons = concatMap tyConDataCons vectTypeTyCons
- ids = mg_ids ++ vectIds
- tyCons = mg_tyCons ++ vectTypeTyCons
- dataCons = concatMap tyConDataCons mg_tyCons ++ vectDataCons
+ vectIds = [id | Vect id _ <- vectDecls] ++
+ [id | VectInst _ id <- vectDecls]
+ vectTypeTyCons = [tycon | VectType _ tycon _ <- vectDecls] ++
+ [tycon | VectClass tycon <- vectDecls]
+ vectDataCons = concatMap tyConDataCons vectTypeTyCons
+ ids = mg_ids ++ vectIds ++ selIds
+ tyCons = mg_tyCons ++ vectTypeTyCons
+ dataCons = concatMap tyConDataCons mg_tyCons ++ vectDataCons
+ selIds = concat [ classAllSelIds cls
+ | tycon <- tyCons
+ , cls <- maybeToList . tyConClass_maybe $ tycon]
-- Produce an entry for every declaration that is mentioned in the domain of the 'inspectedEnv'
mk_env decls inspectedEnv
diff --git a/compiler/vectorise/Vectorise/Exp.hs b/compiler/vectorise/Vectorise/Exp.hs
index 1a5701cc0f..bf6fe3165e 100644
--- a/compiler/vectorise/Vectorise/Exp.hs
+++ b/compiler/vectorise/Vectorise/Exp.hs
@@ -398,16 +398,6 @@ unVectDict ty e
Nothing -> panic "Vectorise.Exp.unVectDict: no class"
selIds = classAllSelIds cls
-{-
-!!!How about 'isClassOpId_maybe'? Do we need to treat them specially to get the class ops for
-!!!the vectorised instances or do they just work out?? (We may want to make sure that the
-!!!vectorised Ids at least get the right IdDetails...)
-!!!NB: For *locally defined* instances, the selector functions are part of the vectorised bindings,
-!!! but not so for *imported* instances, where we need to generate the vectorised versions from
-!!! scratch.
-!!!Also need to take care of the builtin rules for selectors (see mkDictSelId).
- -}
-
-- | Vectorise a lambda abstraction.
--
vectLam :: Bool -- ^ When the RHS of a binding, whether that binding should be inlined.
diff --git a/compiler/vectorise/Vectorise/Monad.hs b/compiler/vectorise/Vectorise/Monad.hs
index a7d984cf83..6fbdb4e3ad 100644
--- a/compiler/vectorise/Vectorise/Monad.hs
+++ b/compiler/vectorise/Vectorise/Monad.hs
@@ -54,7 +54,7 @@ initV :: HscEnv
-> IO (Maybe (VectInfo, a))
initV hsc_env guts info thing_inside
= do {
- let type_env = typeEnvFromEntities ids (mg_tcs guts) (mg_clss guts) (mg_fam_insts guts)
+ let type_env = typeEnvFromEntities ids (mg_tcs guts) (mg_fam_insts guts)
; (_, Just res) <- initDs hsc_env (mg_module guts)
(mg_rdr_env guts) type_env go
@@ -89,7 +89,6 @@ initV hsc_env guts info thing_inside
builtin_prs = initClassDicts instEnvs (prClass builtins) -- ..'PR' class instances
-- construct the initial global environment
- ; let thing_inside' = traceVt "VectDecls" (ppr (mg_vect_decls guts)) >> thing_inside
; let genv = extendImportedVarsEnv builtin_vars
. extendTyConsEnv builtin_tycons
. setPAFunsEnv builtin_pas
@@ -97,7 +96,7 @@ initV hsc_env guts info thing_inside
$ initGlobalEnv info (mg_vect_decls guts) instEnvs famInstEnvs
-- perform vectorisation
- ; r <- runVM thing_inside' builtins genv emptyLocalEnv
+ ; r <- runVM thing_inside builtins genv emptyLocalEnv
; case r of
Yes genv _ x -> return $ Just (new_info genv, x)
No reason -> do { unqual <- mkPrintUnqualifiedDs
diff --git a/compiler/vectorise/Vectorise/Monad/Naming.hs b/compiler/vectorise/Vectorise/Monad/Naming.hs
index adc2d0ca01..ecf0e81306 100644
--- a/compiler/vectorise/Vectorise/Monad/Naming.hs
+++ b/compiler/vectorise/Vectorise/Monad/Naming.hs
@@ -46,8 +46,8 @@ mkLocalisedName mk_occ name =
; return new_name
}
--- |Produce the vectorised variant of an `Id` with the given type, while taking care that vectorised
--- dfun ids must be dfuns again.
+-- |Produce the vectorised variant of an `Id` with the given vectorised type, while taking care that
+-- vectorised dfun ids must be dfuns again.
--
-- Force the new name to be a system name and, if the original was an external name, disambiguate
-- the new name with the module name of the original.
diff --git a/compiler/vectorise/Vectorise/Type/Classify.hs b/compiler/vectorise/Vectorise/Type/Classify.hs
index 1a0a434adc..7122cb7664 100644
--- a/compiler/vectorise/Vectorise/Type/Classify.hs
+++ b/compiler/vectorise/Vectorise/Type/Classify.hs
@@ -28,7 +28,9 @@ import Digraph
-- |From a list of type constructors, extract those that can be vectorised, returning them in two
-- sets, where the first result list /must be/ vectorised and the second result list /need not be/
--- vectroised.
+-- vectorised. The third result list are those type constructors that we cannot convert (either
+-- because they use language extensions or because they dependent on type constructors for which
+-- no vectorised version is available).
-- The first argument determines the /conversion status/ of external type constructors as follows:
--
@@ -36,19 +38,19 @@ import Digraph
-- * tycons which are not changed by vectorisation are mapped to 'False'
-- * tycons which can't be converted are not elements of the map
--
-classifyTyCons :: UniqFM Bool -- ^type constructor conversion status
- -> [TyCon] -- ^type constructors that need to be classified
- -> ([TyCon], [TyCon]) -- ^tycons to be converted & not to be converted
-classifyTyCons convStatus tcs = classify [] [] convStatus (tyConGroups tcs)
+classifyTyCons :: UniqFM Bool -- ^type constructor conversion status
+ -> [TyCon] -- ^type constructors that need to be classified
+ -> ([TyCon], [TyCon], [TyCon]) -- ^tycons to be converted & not to be converted
+classifyTyCons convStatus tcs = classify [] [] [] convStatus (tyConGroups tcs)
where
- classify conv keep _ [] = (conv, keep)
- classify conv keep cs ((tcs, ds) : rs)
+ classify conv keep ignored _ [] = (conv, keep, ignored)
+ classify conv keep ignored cs ((tcs, ds) : rs)
| can_convert && must_convert
- = classify (tcs ++ conv) keep (cs `addListToUFM` [(tc, True) | tc <- tcs]) rs
+ = classify (tcs ++ conv) keep ignored (cs `addListToUFM` [(tc, True) | tc <- tcs]) rs
| can_convert
- = classify conv (tcs ++ keep) (cs `addListToUFM` [(tc, False) | tc <- tcs]) rs
+ = classify conv (tcs ++ keep) ignored (cs `addListToUFM` [(tc, False) | tc <- tcs]) rs
| otherwise
- = classify conv keep cs rs
+ = classify conv keep (tcs ++ ignored) cs rs
where
refs = ds `delListFromUniqSet` tcs
diff --git a/compiler/vectorise/Vectorise/Type/Env.hs b/compiler/vectorise/Vectorise/Type/Env.hs
index a6112c714c..042d127258 100644
--- a/compiler/vectorise/Vectorise/Type/Env.hs
+++ b/compiler/vectorise/Vectorise/Type/Env.hs
@@ -162,9 +162,10 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
-- appear in vectorised code. (We also drop the local type constructors appearing in a
-- VECTORISE SCALAR pragma or a VECTORISE pragma with an explicit right-hand side, as
-- these are being handled separately.)
- ; let maybeVectoriseTyCons = filter notLocalScalarTyCon tycons ++ impVectTyCons
- (conv_tcs, keep_tcs) = classifyTyCons vectTyConFlavour maybeVectoriseTyCons
- orig_tcs = keep_tcs ++ conv_tcs
+ -- Furthermore, 'drop_tcs' are those type constructors that we cannot vectorise.
+ ; let maybeVectoriseTyCons = filter notLocalScalarTyCon tycons ++ impVectTyCons
+ (conv_tcs, keep_tcs, drop_tcs) = classifyTyCons vectTyConFlavour maybeVectoriseTyCons
+ orig_tcs = keep_tcs ++ conv_tcs
; traceVt " VECT SCALAR : " $ ppr localScalarTyCons
; traceVt " VECT [class] : " $ ppr impVectTyCons
@@ -172,6 +173,13 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
; traceVt " -- after classification (local and VECT [class] tycons) --" empty
; traceVt " reuse : " $ ppr keep_tcs
; traceVt " convert : " $ ppr conv_tcs
+
+ -- warn the user about unvectorised type constructors
+ ; let explanation = ptext (sLit "(They use unsupported language extensions") $$
+ ptext (sLit "or depend on type constructors that are not vectorised)")
+ ; unless (null drop_tcs) $
+ emitVt "Warning: cannot vectorise these type constructors:" $
+ pprQuotedList drop_tcs $$ explanation
; let defTyConDataCons origTyCon vectTyCon
= do { defTyCon origTyCon vectTyCon
diff --git a/compiler/vectorise/Vectorise/Type/TyConDecl.hs b/compiler/vectorise/Vectorise/Type/TyConDecl.hs
index 38af2dc846..859056cd1a 100644
--- a/compiler/vectorise/Vectorise/Type/TyConDecl.hs
+++ b/compiler/vectorise/Vectorise/Type/TyConDecl.hs
@@ -48,8 +48,12 @@ vectTyConDecl tycon
-- vectorise superclass constraint (types)
; theta' <- mapM vectType (classSCTheta cls)
- -- vectorise method selectors and add them to the vectorisation map
- ; methods' <- sequence [ vectMethod id meth | (id, meth) <- classOpItems cls]
+ -- vectorise method selectors
+ ; let opItems = classOpItems cls
+ Just datacon = tyConSingleDataCon_maybe tycon
+ argTys = dataConRepArgTys datacon -- all selector types
+ opTys = drop (length argTys - length opItems) argTys -- only method types
+ ; methods' <- sequence [ vectMethod id meth ty | ((id, meth), ty) <- zip opItems opTys]
-- keep the original recursiveness flag
; let rec_flag = boolToRecFlag (isRecursiveTyCon tycon)
@@ -75,6 +79,11 @@ vectTyConDecl tycon
Just datacon' = tyConSingleDataCon_maybe tycon'
; defDataCon datacon datacon'
+ -- the original superclass and methods selectors must map to the vectorised ones
+ ; let selIds = classAllSelIds cls
+ selIds' = classAllSelIds cls'
+ ; zipWithM_ defGlobalVar selIds selIds'
+
-- return the type constructor of the vectorised class
; return tycon'
}
@@ -110,25 +119,17 @@ vectTyConDecl tycon
| otherwise
= cantVectorise "Can't vectorise exotic type constructor" (ppr tycon)
--- |Vectorise a class method.
+-- |Vectorise a class method. (Don't enter it into the vectorisation map yet.)
--
-vectMethod :: Id -> DefMeth -> VM (Name, DefMethSpec, Type)
-vectMethod id defMeth
+vectMethod :: Id -> DefMeth -> Type -> VM (Name, DefMethSpec, Type)
+vectMethod id defMeth ty
= do { -- Vectorise the method type.
- ; typ' <- vectType (varType id)
+ ; ty' <- vectType ty
-- Create a name for the vectorised method.
- ; id' <- mkVectId id typ'
- ; defGlobalVar id id'
-
- -- When we call buildClass in vectTyConDecl, it adds foralls and dictionaries
- -- to the types of each method. However, the types we get back from vectType
- -- above already already have these, so we need to chop them off here otherwise
- -- we'll get two copies in the final version.
- ; let (_tyvars, tyBody) = splitForAllTys typ'
- ; let (_dict, tyRest) = splitFunTy tyBody
+ ; id' <- mkVectId id ty'
- ; return (Var.varName id', defMethSpecOfDefMeth defMeth, tyRest)
+ ; return (Var.varName id', defMethSpecOfDefMeth defMeth, ty')
}
-- |Vectorise the RHS of an algebraic type.
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 5123e1026c..6d1b293701 100755
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -8575,6 +8575,26 @@ data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int
constructor field.</para>
</sect2>
+ <sect2 id="nounpack-pragma">
+ <title>NOUNPACK pragma</title>
+
+ <indexterm><primary>NOUNPACK</primary></indexterm>
+
+ <para>The <literal>NOUNPACK</literal> pragma indicates to the compiler
+ that it should not unpack the contents of a constructor field.
+ Example:
+ </para>
+<programlisting>
+data T = T {-# NOUNPACK #-} !(Int,Int)
+</programlisting>
+ <para>
+ Even with the flags
+ <option>-funbox-strict-fields</option> and <option>-O</option>,
+ the field of the constructor <function>T</function> is not
+ unpacked.
+ </para>
+ </sect2>
+
<sect2 id="source-pragma">
<title>SOURCE pragma</title>
diff --git a/docs/users_guide/using.xml b/docs/users_guide/using.xml
index eccd6f967e..4cace1ee88 100644
--- a/docs/users_guide/using.xml
+++ b/docs/users_guide/using.xml
@@ -1932,7 +1932,12 @@ f "2" = 2
<para>This option is a bit of a sledgehammer: it might
sometimes make things worse. Selectively unboxing fields
by using <literal>UNPACK</literal> pragmas might be
- better.</para>
+ better. An alternative is to use
+ <option>-funbox-strict-fields</option> to turn on
+ unboxing by default but disable it for certain constructor
+ fields using the <literal>NOUNPACK</literal> pragma
+ (see <xref linkend="nounpack-pragma"/>).
+ </para>
</listitem>
</varlistentry>
diff --git a/ghc.mk b/ghc.mk
index 8ae3e04d26..2d8aaf419c 100644
--- a/ghc.mk
+++ b/ghc.mk
@@ -313,9 +313,12 @@ endif
# Packages that are built but not installed
PKGS_THAT_ARE_INTREE_ONLY := haskeline mtl terminfo utf8-string xhtml
-PKGS_THAT_ARE_DPH := dph/dph-base dph/dph-prim-interface dph/dph-prim-seq \
- dph/dph-common dph/dph-prim-par dph/dph-par dph/dph-seq \
- vector primitive random
+PKGS_THAT_ARE_DPH := \
+ dph/dph-base \
+ dph/dph-prim-interface dph/dph-prim-seq dph/dph-prim-par \
+ dph/dph-lifted-base \
+ dph/dph-lifted-boxed dph/dph-lifted-copy dph/dph-lifted-vseg \
+ vector primitive random
# Packages that, if present, must be built by the stage2 compiler,
# because they use TH and/or annotations, or depend on other stage2
@@ -539,8 +542,6 @@ endif
# these cases, so we just skip checking them.
# NB. these must come before we include the ghc.mk files below, because
# they disable the relevant rules.
-CHECKED_libraries/dph/dph-seq = YES
-CHECKED_libraries/dph/dph-par = YES
# In compiler's case, include-dirs points outside of the source tree
CHECKED_compiler = YES
diff --git a/libffi/package.conf.in b/libffi/package.conf.in
deleted file mode 100644
index fa07e5f8fe..0000000000
--- a/libffi/package.conf.in
+++ /dev/null
@@ -1,35 +0,0 @@
-name: ffi
-version: 1.0
-id: builtin_ffi
-license: BSD3
-maintainer: glasgow-haskell-users@haskell.org
-exposed: True
-
-exposed-modules:
-hidden-modules:
-import-dirs:
-
-#ifdef INSTALLING
-library-dirs: LIB_DIR
-#else /* !INSTALLING */
-library-dirs: TOP"/libffi/dist-install/build"
-#endif
-
-hs-libraries: "HSffi"
-
-#ifdef INSTALLING
-include-dirs: INCLUDE_DIR
-#else /* !INSTALLING */
-include-dirs: TOP"/libffi/dist-install/build"
-#endif
-
-depends:
-hugs-options:
-cc-options:
-
-framework-dirs:
-frameworks:
-
-haddock-interfaces:
-haddock-html:
-
diff --git a/mk/validate-settings.mk b/mk/validate-settings.mk
index 6afac177a6..0516be8f56 100644
--- a/mk/validate-settings.mk
+++ b/mk/validate-settings.mk
@@ -21,7 +21,7 @@ SRC_HC_OPTS += -Wall $(WERROR) -H64m -O0
GhcStage1HcOpts += -O -fwarn-tabs
-GhcStage2HcOpts += -O -fwarn-tabs
+GhcStage2HcOpts += -O -fwarn-tabs -dcore-lint
# Using -O (rather than -O0) here bringes my validate down from 22mins to 16 mins.
# Compiling stage2 takes longer, but we gain a faster haddock, faster
# running of the tests, and faster building of the utils to be installed
@@ -99,8 +99,7 @@ libraries/dph/dph-base_dist-install_EXTRA_HC_OPTS += -Wwarn
libraries/dph/dph-prim-interface_dist-install_EXTRA_HC_OPTS += -Wwarn
libraries/dph/dph-prim-seq_dist-install_EXTRA_HC_OPTS += -Wwarn
libraries/dph/dph-prim-par_dist-install_EXTRA_HC_OPTS += -Wwarn
-libraries/dph/dph-seq_dist-install_EXTRA_HC_OPTS += -Wwarn
-libraries/dph/dph-par_dist-install_EXTRA_HC_OPTS += -Wwarn
+libraries/dph/dph-lifted-common-install_EXTRA_HC_OPTS += -Wwarn
# We need to turn of deprecated warnings for SafeHaskell transition
libraries/array_dist-install_EXTRA_HC_OPTS += -fno-warn-warnings-deprecations
diff --git a/rts/Exception.cmm b/rts/Exception.cmm
index 9f48f5d8f5..586086ebf3 100644
--- a/rts/Exception.cmm
+++ b/rts/Exception.cmm
@@ -427,7 +427,9 @@ stg_raisezh
*/
if (RtsFlags_ProfFlags_showCCSOnException(RtsFlags) != 0::I32) {
SAVE_THREAD_STATE();
- foreign "C" fprintCCS_stderr(W_[CCCS] "ptr", CurrentTSO "ptr") [];
+ foreign "C" fprintCCS_stderr(W_[CCCS] "ptr",
+ exception "ptr",
+ CurrentTSO "ptr") [];
LOAD_THREAD_STATE();
}
#endif
diff --git a/rts/Profiling.c b/rts/Profiling.c
index c75a344c7f..38191ff4bd 100644
--- a/rts/Profiling.c
+++ b/rts/Profiling.c
@@ -17,6 +17,7 @@
#include "ProfHeap.h"
#include "Arena.h"
#include "RetainerProfile.h"
+#include "Printer.h"
#include <string.h>
@@ -1001,7 +1002,7 @@ static rtsBool fprintCallStack (CostCentreStack *ccs)
/* For calling from .cmm code, where we can't reliably refer to stderr */
void
-fprintCCS_stderr (CostCentreStack *ccs, StgTSO *tso)
+fprintCCS_stderr (CostCentreStack *ccs, StgClosure *exception, StgTSO *tso)
{
rtsBool is_caf;
StgPtr frame;
@@ -1010,7 +1011,26 @@ fprintCCS_stderr (CostCentreStack *ccs, StgTSO *tso)
nat depth = 0;
const nat MAX_DEPTH = 10; // don't print gigantic chains of stacks
- fprintf(stderr, "*** Exception raised (reporting due to +RTS -xc), stack trace:\n ");
+ {
+ char *desc;
+ StgInfoTable *info;
+ info = get_itbl(exception);
+ switch (info->type) {
+ case CONSTR:
+ case CONSTR_1_0:
+ case CONSTR_0_1:
+ case CONSTR_2_0:
+ case CONSTR_1_1:
+ case CONSTR_0_2:
+ case CONSTR_STATIC:
+ case CONSTR_NOCAF_STATIC:
+ desc = GET_CON_DESC(itbl_to_con_itbl(info));
+ default:
+ desc = closure_type_names[info->type];
+ }
+ fprintf(stderr, "*** Exception (reporting due to +RTS -xc): (%s), stack trace: \n ", desc);
+ }
+
is_caf = fprintCallStack(ccs);
// traverse the stack down to the enclosing update frame to
diff --git a/rts/Profiling.h b/rts/Profiling.h
index 2ee3311c81..8c365220fb 100644
--- a/rts/Profiling.h
+++ b/rts/Profiling.h
@@ -35,7 +35,7 @@ void reportCCSProfiling ( void );
void PrintNewStackDecls ( void );
void fprintCCS( FILE *f, CostCentreStack *ccs );
-void fprintCCS_stderr (CostCentreStack *ccs, StgTSO *tso);
+void fprintCCS_stderr (CostCentreStack *ccs, StgClosure *exception, StgTSO *tso);
#ifdef DEBUG
void debugCCS( CostCentreStack *ccs );
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c
index acc87b1938..c7b10b856e 100644
--- a/rts/RaiseAsync.c
+++ b/rts/RaiseAsync.c
@@ -739,7 +739,7 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
*/
if (RtsFlags.ProfFlags.showCCSOnException)
{
- fprintCCS_stderr(tso->prof.CCCS,tso);
+ fprintCCS_stderr(tso->prof.CCCS,exception,tso);
}
#endif
// ASSUMES: the thread is not already complete or dead
diff --git a/rts/package.conf.in b/rts/package.conf.in
index e38a38186d..a1161eaa6f 100644
--- a/rts/package.conf.in
+++ b/rts/package.conf.in
@@ -92,6 +92,7 @@ ld-options:
, "-u", "_base_GHCziIOziException_blockedIndefinitelyOnSTM_closure"
, "-u", "_base_ControlziExceptionziBase_nestedAtomically_closure"
, "-u", "_base_GHCziWeak_runFinalizzerBatch_closure"
+ , "-u", "_base_GHCziTopHandler_flushStdHandles_closure"
, "-u", "_base_GHCziTopHandler_runIO_closure"
, "-u", "_base_GHCziTopHandler_runNonIO_closure"
, "-u", "_base_GHCziConcziIO_ensureIOManagerIsRunning_closure"
@@ -130,6 +131,7 @@ ld-options:
, "-u", "base_GHCziIOziException_blockedIndefinitelyOnSTM_closure"
, "-u", "base_ControlziExceptionziBase_nestedAtomically_closure"
, "-u", "base_GHCziWeak_runFinalizzerBatch_closure"
+ , "-u", "base_GHCziTopHandler_flushStdHandles_closure"
, "-u", "base_GHCziTopHandler_runIO_closure"
, "-u", "base_GHCziTopHandler_runNonIO_closure"
, "-u", "base_GHCziConcziIO_ensureIOManagerIsRunning_closure"
diff --git a/rts/win32/Ticker.c b/rts/win32/Ticker.c
index 929e6f4086..1c45482651 100644
--- a/rts/win32/Ticker.c
+++ b/rts/win32/Ticker.c
@@ -153,7 +153,8 @@ exitTicker (rtsBool wait)
if (!GetExitCodeThread(tickThread, &exitCode)) {
return;
}
- if (exitCode != STILL_ACTIVE) {
+ CloseHandle(tickThread);
+ if (exitCode != STILL_ACTIVE) {
tickThread = INVALID_HANDLE_VALUE;
if ( hStopEvent != INVALID_HANDLE_VALUE ) {
CloseHandle(hStopEvent);