diff options
author | Iavor S. Diatchki <iavor.diatchki@gmail.com> | 2012-03-13 22:15:11 -0700 |
---|---|---|
committer | Iavor S. Diatchki <iavor.diatchki@gmail.com> | 2012-03-13 22:15:11 -0700 |
commit | 1dd9b1ae1a5994a78ec1c4ca18c8df6e5b2ca9e0 (patch) | |
tree | 78e4df29214ffbb8076bd00183ab6fbf68e17ffb /compiler/iface | |
parent | cfd89e12334e7dbcc8d9aaee898bcc38b77f549b (diff) | |
parent | 93299cce9a4f7bc65b8164f779a37ef7f9f7c4a0 (diff) | |
download | haskell-1dd9b1ae1a5994a78ec1c4ca18c8df6e5b2ca9e0.tar.gz |
Merge remote-tracking branch 'origin/master' into type-nats
Conflicts:
compiler/coreSyn/CoreLint.lhs
compiler/deSugar/DsBinds.lhs
compiler/hsSyn/HsTypes.lhs
compiler/iface/IfaceType.lhs
compiler/rename/RnHsSyn.lhs
compiler/rename/RnTypes.lhs
compiler/stgSyn/StgLint.lhs
compiler/typecheck/TcHsType.lhs
compiler/utils/ListSetOps.lhs
Diffstat (limited to 'compiler/iface')
-rw-r--r-- | compiler/iface/BinIface.hs | 99 | ||||
-rw-r--r-- | compiler/iface/BuildTyCl.lhs | 6 | ||||
-rw-r--r-- | compiler/iface/FlagChecker.hs | 46 | ||||
-rw-r--r-- | compiler/iface/IfaceSyn.lhs | 14 | ||||
-rw-r--r-- | compiler/iface/IfaceType.lhs | 119 | ||||
-rw-r--r-- | compiler/iface/MkIface.lhs | 163 | ||||
-rw-r--r-- | compiler/iface/TcIface.lhs | 48 |
7 files changed, 198 insertions, 297 deletions
diff --git a/compiler/iface/BinIface.hs b/compiler/iface/BinIface.hs index 8bf6594df5..eff699fd6b 100644 --- a/compiler/iface/BinIface.hs +++ b/compiler/iface/BinIface.hs @@ -998,33 +998,10 @@ instance Binary IfaceType where putByte bh 3 put_ bh ag put_ bh ah - - -- 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 } + = do { putByte bh 4; put_ bh cc; put_ bh tys } put_ bh (IfaceTyConApp tc tys) - = do { putByte bh 21; put_ bh tc; put_ bh tys } + = do { putByte bh 5; put_ bh tc; put_ bh tys } put_ bh (IfaceLitTy n) = do { putByte bh 30; put_ bh n } @@ -1044,30 +1021,10 @@ instance Binary IfaceType where 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) } + 4 -> do { cc <- get bh; tys <- get bh + ; return (IfaceCoConApp cc tys) } + 5 -> do { tc <- get bh; tys <- get bh + ; return (IfaceTyConApp tc tys) } 30 -> do n <- get bh return (IfaceLitTy n) @@ -1088,42 +1045,8 @@ instance Binary IfaceTyLit where _ -> panic ("get IfaceTyLit " ++ show tag) instance Binary IfaceTyCon where - -- 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 -> 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) + put_ bh (IfaceTc ext) = put_ bh ext + get bh = liftM IfaceTc (get bh) instance Binary IfaceCoCon where put_ bh (IfaceCoAx n) = do { putByte bh 0; put_ bh n } @@ -1390,7 +1313,7 @@ instance Binary IfaceDecl where put_ _ (IfaceForeign _ _) = error "Binary.put_(IfaceDecl): IfaceForeign" - put_ bh (IfaceData a1 a2 a3 a4 a5 a6 a7) = do + put_ bh (IfaceData a1 a2 a3 a4 a5 a6 a7 a8) = do putByte bh 2 put_ bh (occNameFS a1) put_ bh a2 @@ -1399,6 +1322,7 @@ instance Binary IfaceDecl where put_ bh a5 put_ bh a6 put_ bh a7 + put_ bh a8 put_ bh (IfaceSyn a1 a2 a3 a4) = do putByte bh 3 @@ -1441,8 +1365,9 @@ instance Binary IfaceDecl where a5 <- get bh a6 <- get bh a7 <- get bh + a8 <- get bh occ <- return $! mkOccNameFS tcName a1 - return (IfaceData occ a2 a3 a4 a5 a6 a7) + return (IfaceData occ a2 a3 a4 a5 a6 a7 a8) 3 -> do a1 <- get bh a2 <- get bh a3 <- get bh diff --git a/compiler/iface/BuildTyCl.lhs b/compiler/iface/BuildTyCl.lhs index 75b8d91881..4a93a2bbe4 100644 --- a/compiler/iface/BuildTyCl.lhs +++ b/compiler/iface/BuildTyCl.lhs @@ -29,6 +29,7 @@ import DataCon import Var import VarSet import BasicTypes +import ForeignCall import Name import MkId import Class @@ -56,6 +57,7 @@ buildSynTyCon tc_name tvs rhs rhs_kind parent ------------------------------------------------------ buildAlgTyCon :: Name -> [TyVar] -- ^ Kind variables and type variables + -> Maybe CType -> ThetaType -- ^ Stupid theta -> AlgTyConRhs -> RecFlag @@ -63,8 +65,8 @@ buildAlgTyCon :: Name -> TyConParent -> TyCon -buildAlgTyCon tc_name ktvs stupid_theta rhs is_rec gadt_syn parent - = mkAlgTyCon tc_name kind ktvs stupid_theta rhs parent is_rec gadt_syn +buildAlgTyCon tc_name ktvs cType stupid_theta rhs is_rec gadt_syn parent + = mkAlgTyCon tc_name kind ktvs cType stupid_theta rhs parent is_rec gadt_syn where kind = mkPiKinds ktvs liftedTypeKind diff --git a/compiler/iface/FlagChecker.hs b/compiler/iface/FlagChecker.hs index 5e4a7092bf..0365be7338 100644 --- a/compiler/iface/FlagChecker.hs +++ b/compiler/iface/FlagChecker.hs @@ -10,6 +10,7 @@ import Binary import BinIface () import DynFlags import HscTypes +import Module import Name import Fingerprint -- import Outputable @@ -21,11 +22,12 @@ 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 ()) +fingerprintDynFlags :: DynFlags -> Module -> (BinHandle -> Name -> IO ()) -> IO Fingerprint -fingerprintDynFlags DynFlags{..} nameio = - let mainis = (mainModIs, mainFunIs) +fingerprintDynFlags DynFlags{..} this_mod nameio = + let mainis = if mainModIs == this_mod then Just mainFunIs else Nothing + -- see #5878 -- pkgopts = (thisPackage dflags, sort $ packageFlags dflags) safeHs = setSafeMode safeHaskell -- oflags = sort $ filter filterOFlags $ flags dflags @@ -38,12 +40,8 @@ fingerprintDynFlags DynFlags{..} nameio = 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, outputHi ]) - -- NB. not outputFile, we don't want "ghc --make M -o <file>" - -- to force recompilation when <file> changes. + -- Note [path flags and recompilation] + paths = [ hcSuf ] -- -fprof-auto etc. prof = if opt_SccProfilingOn then fromEnum profAuto else 0 @@ -51,3 +49,33 @@ fingerprintDynFlags DynFlags{..} nameio = in -- pprTrace "flags" (ppr (mainis, safeHs, lang, cpp, paths)) $ computeFingerprint nameio (mainis, safeHs, lang, cpp, paths, prof) + +{- Note [path flags and recompilation] + +There are several flags that we deliberately omit from the +recompilation check; here we explain why. + +-osuf, -odir, -hisuf, -hidir + If GHC decides that it does not need to recompile, then + it must have found an up-to-date .hi file and .o file. + There is no point recording these flags - the user must + have passed the correct ones. Indeed, the user may + have compiled the source file in one-shot mode using + -o to specify the .o file, and then loaded it in GHCi + using -odir. + +-stubdir + We omit this one because it is automatically set by -outputdir, and + we don't want changes in -outputdir to automatically trigger + recompilation. This could be wrong, but only in very rare cases. + +-i (importPaths) + For the same reason as -osuf etc. above: if GHC decides not to + recompile, then it must have already checked all the .hi files on + which the current module depends, so it must have found them + successfully. It is occasionally useful to be able to cd to a + different directory and use -i flags to enable GHC to find the .hi + files; we don't want this to force recompilation. + +The only path-related flag left is -hcsuf. +-} diff --git a/compiler/iface/IfaceSyn.lhs b/compiler/iface/IfaceSyn.lhs index ef74b13489..d3e44fe54f 100644 --- a/compiler/iface/IfaceSyn.lhs +++ b/compiler/iface/IfaceSyn.lhs @@ -68,6 +68,7 @@ data IfaceDecl ifIdInfo :: IfaceIdInfo } | IfaceData { ifName :: OccName, -- Type constructor + ifCType :: Maybe CType, -- C type for CAPI FFI ifTyVars :: [IfaceTvBndr], -- Type variables ifCtxt :: IfaceContext, -- The "stupid theta" ifCons :: IfaceConDecls, -- Includes new/data/data family info @@ -453,7 +454,8 @@ pprIfaceDecl (IfaceId {ifName = var, ifType = ty, pprIfaceDecl (IfaceForeign {ifName = tycon}) = hsep [ptext (sLit "foreign import type dotnet"), ppr tycon] -pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, +pprIfaceDecl (IfaceSyn {ifName = tycon, + ifTyVars = tyvars, ifSynRhs = Just mono_ty}) = hang (ptext (sLit "type") <+> pprIfaceDeclHead [] tycon tyvars) 4 (vcat [equals <+> ppr mono_ty]) @@ -463,11 +465,12 @@ pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, = hang (ptext (sLit "type family") <+> pprIfaceDeclHead [] tycon tyvars) 4 (dcolon <+> ppr kind) -pprIfaceDecl (IfaceData {ifName = tycon, ifCtxt = context, +pprIfaceDecl (IfaceData {ifName = tycon, ifCType = cType, + ifCtxt = context, ifTyVars = tyvars, ifCons = condecls, ifRec = isrec, ifAxiom = mbAxiom}) = hang (pp_nd <+> pprIfaceDeclHead context tycon tyvars) - 4 (vcat [pprRec isrec, pp_condecls tycon condecls, + 4 (vcat [pprCType cType, pprRec isrec, pp_condecls tycon condecls, pprAxiom mbAxiom]) where pp_nd = case condecls of @@ -489,6 +492,10 @@ pprIfaceDecl (IfaceAxiom {ifName = name, ifTyVars = tyvars, = hang (ptext (sLit "axiom") <+> ppr name <+> ppr tyvars) 2 (dcolon <+> ppr lhs <+> text "~#" <+> ppr rhs) +pprCType :: Maybe CType -> SDoc +pprCType Nothing = ptext (sLit "No C type associated") +pprCType (Just cType) = ptext (sLit "C type:") <+> ppr cType + pprRec :: RecFlag -> SDoc pprRec isrec = ptext (sLit "RecFlag") <+> ppr isrec @@ -876,7 +883,6 @@ freeNamesIfExpr _ = emptyNameSet freeNamesIfTc :: IfaceTyCon -> NameSet freeNamesIfTc (IfaceTc tc) = unitNameSet tc -- ToDo: shouldn't we include IfaceIntTc & co.? -freeNamesIfTc _ = emptyNameSet freeNamesIfCo :: IfaceCoCon -> NameSet freeNamesIfCo (IfaceCoAx tc) = unitNameSet tc diff --git a/compiler/iface/IfaceType.lhs b/compiler/iface/IfaceType.lhs index 77f4b700d2..a833d2c218 100644 --- a/compiler/iface/IfaceType.lhs +++ b/compiler/iface/IfaceType.lhs @@ -19,7 +19,6 @@ module IfaceType ( IfaceType(..), IfacePredType, IfaceKind, IfaceTyCon(..), IfaceCoCon(..), IfaceTyLit(..), IfaceContext, IfaceBndr(..), IfaceTvBndr, IfaceIdBndr, IfaceCoercion, - ifaceTyConName, -- Conversion from Type -> IfaceType toIfaceType, toIfaceKind, toIfaceContext, @@ -93,20 +92,9 @@ data IfaceTyLit = IfaceNumTyLit Integer | IfaceStrTyLit FastString -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. +-- Encodes type constructors, kind constructors +-- coercion constructors, the lot +newtype IfaceTyCon = IfaceTc { ifaceTyConName :: IfExtName } -- Coercion constructors data IfaceCoCon @@ -115,40 +103,8 @@ data IfaceCoCon | IfaceReflCo | IfaceUnsafeCo | IfaceSymCo | IfaceTransCo | IfaceInstCo | 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 (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 -need a Kind. - -In fact, ifaceTyConName is only used for instances and rules, and we don't -expect to instantiate those at these (internal-ish) Any types, so rather -than solve this potential problem now, I'm going to defer it until it happens! - %************************************************************************ %* * Functions over IFaceTypes @@ -220,9 +176,10 @@ pprIfaceIdBndr :: (IfLclName, IfaceType) -> SDoc pprIfaceIdBndr (name, ty) = hsep [ppr name, dcolon, ppr ty] pprIfaceTvBndr :: IfaceTvBndr -> SDoc -pprIfaceTvBndr (tv, IfaceTyConApp IfaceLiftedTypeKindTc []) - = ppr tv +pprIfaceTvBndr (tv, IfaceTyConApp tc []) + | ifaceTyConName tc == liftedTypeKindTyConName = ppr tv pprIfaceTvBndr (tv, kind) = parens (ppr tv <> dcolon <> ppr kind) + pprIfaceTvBndrs :: [IfaceTvBndr] -> SDoc pprIfaceTvBndrs tyvars = hsep (map pprIfaceTvBndr tyvars) \end{code} @@ -288,27 +245,25 @@ pprIfaceForAllPart tvs ctxt doc ppr_tc_app :: Int -> IfaceTyCon -> [IfaceType] -> SDoc 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 _ (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 ctxt_prec tc tys - = maybeParen ctxt_prec tYCON_PREC + = maybeParen ctxt_prec tYCON_PREC (sep [ppr_tc tc, nest 4 (sep (map pprParendIfaceType tys))]) ppr_tc :: IfaceTyCon -> SDoc -- Wrap infix type constructors in parens -ppr_tc tc@(IfaceTc ext_nm) = parenSymOcc (getOccName ext_nm) (ppr tc) -ppr_tc tc = ppr tc +ppr_tc tc = parenSymOcc (getOccName (ifaceTyConName tc)) (ppr tc) ppr_tylit :: IfaceTyLit -> SDoc ppr_tylit (IfaceNumTyLit n) = integer n @@ -316,8 +271,7 @@ ppr_tylit (IfaceStrTyLit n) = text (show n) ------------------- instance Outputable IfaceTyCon where - ppr (IfaceIPTc n) = ppr (IPName n) - ppr other_tc = ppr (ifaceTyConName other_tc) + ppr = ppr . ifaceTyConName instance Outputable IfaceCoCon where ppr (IfaceCoAx n) = ppr n @@ -341,10 +295,6 @@ pprIfaceContext theta = ppr_preds theta <+> darrow ppr_preds :: [IfacePredType] -> SDoc ppr_preds [pred] = ppr pred -- No parens ppr_preds preds = parens (sep (punctuate comma (map ppr preds))) - -------------------- -pabrackets :: SDoc -> SDoc -pabrackets p = ptext (sLit "[:") <> p <> ptext (sLit ":]") \end{code} %************************************************************************ @@ -388,35 +338,10 @@ toIfaceCoVar = occNameFS . getOccName ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon -toIfaceTyCon tc - | isTupleTyCon tc = IfaceTupTc (tupleTyConSort tc) (tyConArity tc) - | Just n <- tyConIP_maybe tc = IfaceIPTc (ipFastString n) - | otherwise = toIfaceTyCon_name (tyConName tc) +toIfaceTyCon = toIfaceTyCon_name . tyConName toIfaceTyCon_name :: Name -> IfaceTyCon -toIfaceTyCon_name nm - | Just (ATyCon tc) <- wiredInNameTyThing_maybe nm - = toIfaceWiredInTyCon tc nm - | otherwise - = IfaceTc nm - -toIfaceWiredInTyCon :: TyCon -> Name -> IfaceTyCon -toIfaceWiredInTyCon tc nm - | 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 +toIfaceTyCon_name = IfaceTc toIfaceTyLit :: TyLit -> IfaceTyLit toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs index 9904042fe0..877de44330 100644 --- a/compiler/iface/MkIface.lhs +++ b/compiler/iface/MkIface.lhs @@ -19,6 +19,7 @@ module MkIface ( checkOldIface, -- See if recompilation is required, by -- comparing version information + RecompileRequired(..), recompileRequired, tyThingToIfaceDecl -- Converting things to their Iface equivalents ) where @@ -110,6 +111,7 @@ import Data.List import Data.Map (Map) import qualified Data.Map as Map import Data.IORef +import System.Directory import System.FilePath \end{code} @@ -287,7 +289,7 @@ mkIface_ hsc_env maybe_old_fingerprint mi_fixities = fixities, mi_warns = warns, mi_anns = mkIfaceAnnotations anns, - mi_globals = Just rdr_env, + mi_globals = maybeGlobalRdrEnv rdr_env, -- Left out deliberately: filled in by addFingerprints mi_iface_hash = fingerprint0, @@ -344,7 +346,7 @@ mkIface_ hsc_env maybe_old_fingerprint -- correctly. This stems from the fact that the interface had -- not changed, so addFingerprints returns the old ModIface -- with the old GlobalRdrEnv (mi_globals). - ; let final_iface = new_iface{ mi_globals = Just rdr_env } + ; let final_iface = new_iface{ mi_globals = maybeGlobalRdrEnv rdr_env } ; return (errs_and_warns, Just (final_iface, no_change_at_all)) }} where @@ -359,6 +361,17 @@ mkIface_ hsc_env maybe_old_fingerprint dflags = hsc_dflags hsc_env + -- We only fill in mi_globals if the module was compiled to byte + -- code. Otherwise, the compiler may not have retained all the + -- top-level bindings and they won't be in the TypeEnv (see + -- Desugar.addExportFlagsAndRules). The mi_globals field is used + -- by GHCi to decide whether the module has its full top-level + -- scope available. (#5534) + maybeGlobalRdrEnv :: GlobalRdrEnv -> Maybe GlobalRdrEnv + maybeGlobalRdrEnv rdr_env + | targetRetainsAllBindings (hscTarget dflags) = Just rdr_env + | otherwise = Nothing + deliberatelyOmitted :: String -> a deliberatelyOmitted x = panic ("Deliberately omitted: " ++ x) @@ -380,7 +393,7 @@ mkIface_ hsc_env maybe_old_fingerprint ----------------------------- writeIfaceFile :: DynFlags -> ModLocation -> ModIface -> IO () writeIfaceFile dflags location new_iface - = do createDirectoryHierarchy (takeDirectory hi_file_path) + = do createDirectoryIfMissing True (takeDirectory hi_file_path) writeBinIface dflags hi_file_path new_iface where hi_file_path = ml_hi_file location @@ -583,7 +596,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls -- - (some of) dflags -- it returns two hashes, one that shouldn't change -- the abi hash and one that should - flag_hash <- fingerprintDynFlags dflags putNameLiterally + flag_hash <- fingerprintDynFlags dflags this_mod putNameLiterally -- the ABI hash depends on: -- - decls @@ -1073,11 +1086,28 @@ Trac #5362 for an example. Such Names are always %* * Load the old interface file for this module (unless we have it already), and check whether it is up to date - %* * %************************************************************************ \begin{code} +data RecompileRequired + = UpToDate + -- ^ everything is up to date, recompilation is not required + | MustCompile + -- ^ The .hs file has been touched, or the .o/.hi file does not exist + | RecompBecause String + -- ^ The .o/.hi files are up to date, but something else has changed + -- to force recompilation; the String says what (one-line summary) + | RecompForcedByTH + -- ^ recompile is forced due to use of TH by the module + deriving Eq + +recompileRequired :: RecompileRequired -> Bool +recompileRequired UpToDate = False +recompileRequired _ = True + + + -- | 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 @@ -1097,7 +1127,7 @@ checkOldIface hsc_env mod_summary source_modified maybe_iface check_old_iface hsc_env mod_summary source_modified maybe_iface check_old_iface :: HscEnv -> ModSummary -> SourceModified -> Maybe ModIface - -> IfG (Bool, Maybe ModIface) + -> IfG (RecompileRequired, Maybe ModIface) check_old_iface hsc_env mod_summary src_modified maybe_iface = let dflags = hsc_dflags hsc_env getIface = @@ -1131,19 +1161,19 @@ check_old_iface hsc_env mod_summary src_modified maybe_iface -- avoid reading an interface; just return the one we might -- have been supplied with. True | not (isObjectTarget $ hscTarget dflags) -> - return (outOfDate, maybe_iface) + return (MustCompile, 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 - return (outOfDate, maybe_iface') + return (MustCompile, maybe_iface') False -> do maybe_iface' <- getIface case maybe_iface' of -- We can't retrieve the iface - Nothing -> return (outOfDate, Nothing) + Nothing -> return (MustCompile, Nothing) -- We have got the old iface; check its versions -- even in the SourceUnmodifiedAndStable case we @@ -1151,15 +1181,6 @@ check_old_iface hsc_env mod_summary src_modified maybe_iface -- 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 if a module is still the same 'version'. -- -- This function is called in the recompilation checker after we have @@ -1180,9 +1201,9 @@ checkVersions hsc_env mod_summary iface ppr (mi_module iface) <> colon) ; recomp <- checkFlagHash hsc_env iface - ; if recomp then return (outOfDate, Nothing) else do { + ; if recompileRequired recomp then return (recomp, Nothing) else do { ; recomp <- checkDependencies hsc_env mod_summary iface - ; if recomp then return (outOfDate, Just iface) else do { + ; if recompileRequired recomp then return (recomp, Just iface) else do { -- Source code unchanged and no errors yet... carry on -- @@ -1211,10 +1232,13 @@ checkVersions hsc_env mod_summary iface 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 + new_hash <- liftIO $ fingerprintDynFlags (hsc_dflags hsc_env) + (mi_module iface) + 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") + False -> out_of_date_hash "flags changed" + (ptext $ sLit " Module flags have changed") old_hash new_hash -- If the direct imports of this module are resolved to targets that @@ -1229,18 +1253,16 @@ checkFlagHash hsc_env iface = do -- Returns True if recompilation is required. checkDependencies :: HscEnv -> ModSummary -> ModIface -> IfG RecompileRequired checkDependencies hsc_env summary iface - = orM (map dep_missing (ms_imps summary ++ ms_srcimps summary)) + = checkList (map dep_missing (ms_imps summary ++ ms_srcimps summary)) where prev_dep_mods = dep_mods (mi_deps iface) prev_dep_pkgs = dep_pkgs (mi_deps iface) this_pkg = thisPackage (hsc_dflags hsc_env) - orM = foldr f (return False) - where f m rest = do b <- m; if b then return True else rest - dep_missing (L _ (ImportDecl { ideclName = L _ mod, ideclPkgQual = pkg })) = do find_res <- liftIO $ findImportedModule hsc_env mod pkg + let reason = moduleNameString mod ++ " changed" case find_res of Found _ mod | pkg == this_pkg @@ -1248,20 +1270,20 @@ checkDependencies hsc_env summary iface then do traceHiDiffs $ text "imported module " <> quotes (ppr mod) <> text " not among previous dependencies" - return outOfDate + return (RecompBecause reason) else - return upToDate + return UpToDate | otherwise -> if pkg `notElem` (map fst prev_dep_pkgs) then do traceHiDiffs $ text "imported module " <> quotes (ppr mod) <> text " is from package " <> quotes (ppr pkg) <> text ", which is not among previous dependencies" - return outOfDate + return (RecompBecause reason) else - return upToDate + return UpToDate where pkg = modulePackageId mod - _otherwise -> return outOfDate + _otherwise -> return (RecompBecause reason) needInterface :: Module -> (ModIface -> IfG RecompileRequired) -> IfG RecompileRequired @@ -1275,8 +1297,10 @@ needInterface mod continue -- 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"), - ppr mod])) + Failed _ -> do + traceHiDiffs (sep [ptext (sLit "Couldn't load interface for module"), + ppr mod]) + return MustCompile -- Couldn't find or parse a module mentioned in the -- old interface file. Don't complain: it might -- just be that the current module doesn't need that @@ -1292,7 +1316,8 @@ checkModUsage _this_pkg UsagePackageModule{ usg_mod = mod, usg_mod_hash = old_mod_hash } = needInterface mod $ \iface -> do - checkModuleFingerprint old_mod_hash (mi_mod_hash iface) + let reason = moduleNameString (moduleName mod) ++ " changed" + checkModuleFingerprint reason old_mod_hash (mi_mod_hash iface) -- We only track the ABI hash of package modules, rather than -- individual entity usages, so if the ABI hash changes we must -- recompile. This is safe but may entail more recompilation when @@ -1312,19 +1337,21 @@ checkModUsage this_pkg UsageHomeModule{ new_decl_hash = mi_hash_fn iface new_export_hash = mi_exp_hash iface + reason = moduleNameString mod_name ++ " changed" + -- CHECK MODULE - recompile <- checkModuleFingerprint old_mod_hash new_mod_hash - if not recompile then return upToDate else do - + recompile <- checkModuleFingerprint reason old_mod_hash new_mod_hash + if not (recompileRequired recompile) then return UpToDate else do + -- CHECK EXPORT LIST - checkMaybeHash maybe_old_export_hash new_export_hash + checkMaybeHash reason maybe_old_export_hash new_export_hash (ptext (sLit " Export list changed")) $ do -- CHECK ITEMS ONE BY ONE - recompile <- checkList [ checkEntityUsage new_decl_hash u + recompile <- checkList [ checkEntityUsage reason new_decl_hash u | u <- old_decl_hash] - if recompile - then return outOfDate -- This one failed, so just bail out now + if recompileRequired recompile + then return recompile -- This one failed, so just bail out now else up_to_date (ptext (sLit " Great! The bits I use are up to date")) @@ -1333,65 +1360,72 @@ checkModUsage _this_pkg UsageFile{ usg_file_path = file, liftIO $ handleIO handle $ do new_mtime <- getModificationUTCTime file - return $ old_mtime /= new_mtime + if (old_mtime /= new_mtime) + then return recomp + else return UpToDate where + recomp = RecompBecause (file ++ " changed") handle = #ifdef DEBUG - \e -> pprTrace "UsageFile" (text (show e)) $ return True + \e -> pprTrace "UsageFile" (text (show e)) $ return recomp #else - \_ -> return True -- if we can't find the file, just recompile, don't fail + \_ -> return recomp -- if we can't find the file, just recompile, don't fail #endif ------------------------ -checkModuleFingerprint :: Fingerprint -> Fingerprint -> IfG RecompileRequired -checkModuleFingerprint old_mod_hash new_mod_hash +checkModuleFingerprint :: String -> Fingerprint -> Fingerprint + -> IfG RecompileRequired +checkModuleFingerprint reason 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")) + = out_of_date_hash reason (ptext (sLit " Module fingerprint has changed")) old_mod_hash new_mod_hash ------------------------ -checkMaybeHash :: Maybe Fingerprint -> Fingerprint -> SDoc +checkMaybeHash :: String -> Maybe Fingerprint -> Fingerprint -> SDoc -> IfG RecompileRequired -> IfG RecompileRequired -checkMaybeHash maybe_old_hash new_hash doc continue +checkMaybeHash reason maybe_old_hash new_hash doc continue | Just hash <- maybe_old_hash, hash /= new_hash - = out_of_date_hash doc hash new_hash + = out_of_date_hash reason doc hash new_hash | otherwise = continue ------------------------ -checkEntityUsage :: (OccName -> Maybe (OccName, Fingerprint)) +checkEntityUsage :: String + -> (OccName -> Maybe (OccName, Fingerprint)) -> (OccName, Fingerprint) -> IfG RecompileRequired -checkEntityUsage new_hash (name,old_hash) +checkEntityUsage reason 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]) + out_of_date reason (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) + return UpToDate + | otherwise -> out_of_date_hash reason (ptext (sLit " Out of date:") <+> ppr name) old_hash new_hash -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 +up_to_date :: SDoc -> IfG RecompileRequired +up_to_date msg = traceHiDiffs msg >> return UpToDate + +out_of_date :: String -> SDoc -> IfG RecompileRequired +out_of_date reason msg = traceHiDiffs msg >> return (RecompBecause reason) -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]) +out_of_date_hash :: String -> SDoc -> Fingerprint -> Fingerprint -> IfG RecompileRequired +out_of_date_hash reason msg old_hash new_hash + = out_of_date reason (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 + if recompileRequired recompile + then return recompile else checkList checks \end{code} @@ -1425,6 +1459,7 @@ tyThingToIfaceDecl (ATyCon tycon) | isAlgTyCon tycon = IfaceData { ifName = getOccName tycon, + ifCType = tyConCType tycon, ifTyVars = toIfaceTvBndrs tyvars, ifCtxt = toIfaceContext (tyConStupidTheta tycon), ifCons = ifaceConDecls (algTyConRhs tycon), diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs index a081fbe36e..e0b0f1d2a8 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 ( tySuperKindTyCon ) +import TysPrim ( superKindTyConName ) import BasicTypes ( Arity, strongLoopBreaker ) import Literal import qualified Var @@ -432,6 +432,7 @@ tc_iface_decl _ ignore_prags (IfaceId {ifName = occ_name, ifType = iface_type, ; return (AnId (mkGlobalId details name ty info)) } tc_iface_decl parent _ (IfaceData {ifName = occ_name, + ifCType = cType, ifTyVars = tv_bndrs, ifCtxt = ctxt, ifGadtSyntax = gadt_syn, ifCons = rdr_cons, @@ -443,7 +444,7 @@ tc_iface_decl parent _ (IfaceData {ifName = occ_name, { stupid_theta <- tcIfaceCtxt ctxt ; parent' <- tc_parent tyvars mb_axiom_name ; cons <- tcIfaceDataCons tc_name tycon tyvars rdr_cons - ; return (buildAlgTyCon tc_name tyvars stupid_theta + ; return (buildAlgTyCon tc_name tyvars cType stupid_theta cons is_rec gadt_syn parent') } ; traceIf (text "tcIfaceDecl4" <+> ppr tycon) ; return (ATyCon tycon) } @@ -1242,6 +1243,9 @@ tcIfaceGlobal :: Name -> IfL TyThing tcIfaceGlobal name | Just thing <- wiredInNameTyThing_maybe name -- Wired-in things include TyCons, DataCons, and Ids + -- Even though we are in an interface file, we want to make + -- sure the instances and RULES of this thing (particularly TyCon) are loaded + -- Imagine: f :: Double -> Double = do { ifCheckWiredInThing thing; return thing } | otherwise = do { env <- getGblEnv @@ -1286,37 +1290,13 @@ tcIfaceGlobal name -- emasculated form (e.g. lacking data constructors). tcIfaceTyCon :: IfaceTyCon -> IfL TyCon -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 - | debugIsOn = case toIfaceTyCon tc of - 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 --- Imagine: f :: Double -> Double -tcWiredInTyCon :: TyCon -> IfL TyCon -tcWiredInTyCon tc = do { ifCheckWiredInThing (ATyCon tc) - ; return tc } +tcIfaceTyCon (IfaceTc name) + = do { thing <- tcIfaceGlobal name + ; case thing of -- A "type constructor" can be a promoted data constructor + -- c.f. Trac #5881 + ATyCon tc -> return tc + ADataCon dc -> return (buildPromotedDataCon dc) + _ -> pprPanic "tcIfaceTyCon" (ppr name $$ ppr thing) } tcIfaceCoAxiom :: Name -> IfL CoAxiom tcIfaceCoAxiom name = do { thing <- tcIfaceGlobal name @@ -1388,7 +1368,7 @@ bindIfaceTyVars bndrs thing_inside (occs,kinds) = unzip bndrs isSuperIfaceKind :: IfaceKind -> Bool -isSuperIfaceKind (IfaceTyConApp IfaceSuperKindTc []) = True +isSuperIfaceKind (IfaceTyConApp (IfaceTc n) []) = n == superKindTyConName isSuperIfaceKind _ = False mk_iface_tyvar :: Name -> IfaceKind -> IfL TyVar |