summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
authorAlec Theriault <alec.theriault@gmail.com>2018-12-11 13:47:35 -0500
committerBen Gamari <ben@smart-cactus.org>2018-12-11 14:23:22 -0500
commitf582379de2c4ff7577235c926ad953debdae3cac (patch)
treedf39b7a00d1730be04da120ca452517043478809 /compiler/main
parent21339c9f6bfb952a3a0b8de5ee649d46dfbf0d9b (diff)
downloadhaskell-f582379de2c4ff7577235c926ad953debdae3cac.tar.gz
Support generating HIE files
Adds a `-fenable-ide-info` flag which instructs GHC to generate `.hie` files (see the wiki page: https://ghc.haskell.org/trac/ghc/wiki/HIEFiles). This is a rebased version of Zubin Duggal's (@wz1000) GHC changes for his GSOC project, as posted here: https://gist.github.com/wz1000/5ed4ddd0d3e96d6bc75e095cef95363d. Test Plan: ./validate Reviewers: bgamari, gershomb, nomeata, alanz, sjakobi Reviewed By: alanz, sjakobi Subscribers: alanz, hvr, sjakobi, rwbarton, wz1000, carter Differential Revision: https://phabricator.haskell.org/D5239
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/DriverPipeline.hs38
-rw-r--r--compiler/main/DynFlags.hs22
-rw-r--r--compiler/main/Finder.hs23
-rw-r--r--compiler/main/GhcMake.hs13
-rw-r--r--compiler/main/HscMain.hs68
-rw-r--r--compiler/main/HscTypes.hs4
6 files changed, 134 insertions, 34 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 295d36284f..f1a5cb46e0 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -75,6 +75,8 @@ import Data.Maybe
import Data.Version
import Data.Either ( partitionEithers )
+import Data.Time ( UTCTime )
+
-- ---------------------------------------------------------------------------
-- Pre-process
@@ -1016,6 +1018,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
let o_file = ml_obj_file location -- The real object file
hi_file = ml_hi_file location
+ hie_file = ml_hie_file location
dest_file | writeInterfaceOnlyMode dflags
= hi_file
| otherwise
@@ -1023,7 +1026,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
-- Figure out if the source has changed, for recompilation avoidance.
--
- -- Setting source_unchanged to True means that M.o seems
+ -- Setting source_unchanged to True means that M.o (or M.hie) seems
-- to be up to date wrt M.hs; so no need to recompile unless imports have
-- changed (which the compiler itself figures out).
-- Setting source_unchanged to False tells the compiler that M.o is out of
@@ -1037,13 +1040,14 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
-- (b) we aren't going all the way to .o file (e.g. ghc -S)
then return SourceModified
-- Otherwise look at file modification dates
- else do dest_file_exists <- doesFileExist dest_file
- if not dest_file_exists
- then return SourceModified -- Need to recompile
- else do t2 <- getModificationUTCTime dest_file
- if t2 > src_timestamp
- then return SourceUnmodified
- else return SourceModified
+ else do dest_file_mod <- sourceModified dest_file src_timestamp
+ hie_file_mod <- if gopt Opt_WriteHie dflags
+ then sourceModified hie_file
+ src_timestamp
+ else pure False
+ if dest_file_mod || hie_file_mod
+ then return SourceModified
+ else return SourceUnmodified
PipeState{hsc_env=hsc_env'} <- getPipeState
@@ -1062,6 +1066,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
ms_obj_date = Nothing,
ms_parsed_mod = Nothing,
ms_iface_date = Nothing,
+ ms_hie_date = Nothing,
ms_textual_imps = imps,
ms_srcimps = src_imps }
@@ -1634,8 +1639,9 @@ getLocation src_flavour mod_name = do
location1 <- liftIO $ mkHomeModLocation2 dflags mod_name basename suff
-- Boot-ify it if necessary
- let location2 | HsBootFile <- src_flavour = addBootSuffixLocn location1
- | otherwise = location1
+ let location2
+ | HsBootFile <- src_flavour = addBootSuffixLocnOut location1
+ | otherwise = location1
-- Take -ohi into account if present
@@ -2251,6 +2257,18 @@ writeInterfaceOnlyMode dflags =
gopt Opt_WriteInterface dflags &&
HscNothing == hscTarget dflags
+-- | Figure out if a source file was modified after an output file (or if we
+-- anyways need to consider the source file modified since the output is gone).
+sourceModified :: FilePath -- ^ destination file we are looking for
+ -> UTCTime -- ^ last time of modification of source file
+ -> IO Bool -- ^ do we need to regenerate the output?
+sourceModified dest_file src_timestamp = do
+ dest_file_exists <- doesFileExist dest_file
+ if not dest_file_exists
+ then return True -- Need to recompile
+ else do t2 <- getModificationUTCTime dest_file
+ return (t2 <= src_timestamp)
+
-- | What phase to run after one of the backend code generators has run
hscPostBackendPhase :: DynFlags -> HscSource -> HscTarget -> Phase
hscPostBackendPhase _ HsBootFile _ = StopLn
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 9e93e47eeb..6c4ee86084 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -511,6 +511,7 @@ data GeneralFlag
| Opt_OmitInterfacePragmas
| Opt_ExposeAllUnfoldings
| Opt_WriteInterface -- forces .hi files to be written even with -fno-code
+ | Opt_WriteHie -- generate .hie files
-- profiling opts
| Opt_AutoSccsOnIndividualCafs
@@ -544,6 +545,7 @@ data GeneralFlag
| Opt_GhciSandbox
| Opt_GhciHistory
| Opt_GhciLeakCheck
+ | Opt_ValidateHie
| Opt_LocalGhciHistory
| Opt_NoIt
| Opt_HelpfulErrors
@@ -942,12 +944,14 @@ data DynFlags = DynFlags {
objectDir :: Maybe String,
dylibInstallName :: Maybe String,
hiDir :: Maybe String,
+ hieDir :: Maybe String,
stubDir :: Maybe String,
dumpDir :: Maybe String,
objectSuf :: String,
hcSuf :: String,
hiSuf :: String,
+ hieSuf :: String,
canGenerateDynamicToo :: IORef Bool,
dynObjectSuf :: String,
@@ -1910,12 +1914,14 @@ defaultDynFlags mySettings (myLlvmTargets, myLlvmPasses) =
objectDir = Nothing,
dylibInstallName = Nothing,
hiDir = Nothing,
+ hieDir = Nothing,
stubDir = Nothing,
dumpDir = Nothing,
objectSuf = phaseInputExt StopLn,
hcSuf = phaseInputExt HCc,
hiSuf = "hi",
+ hieSuf = "hie",
canGenerateDynamicToo = panic "defaultDynFlags: No canGenerateDynamicToo",
dynObjectSuf = "dyn_" ++ phaseInputExt StopLn,
@@ -2493,10 +2499,10 @@ getVerbFlags dflags
| verbosity dflags >= 4 = ["-v"]
| otherwise = []
-setObjectDir, setHiDir, setStubDir, setDumpDir, setOutputDir,
+setObjectDir, setHiDir, setHieDir, setStubDir, setDumpDir, setOutputDir,
setDynObjectSuf, setDynHiSuf,
setDylibInstallName,
- setObjectSuf, setHiSuf, setHcSuf, parseDynLibLoaderMode,
+ setObjectSuf, setHiSuf, setHieSuf, setHcSuf, parseDynLibLoaderMode,
setPgmP, addOptl, addOptc, addOptP,
addCmdlineFramework, addHaddockOpts, addGhciScript,
setInteractivePrint
@@ -2506,18 +2512,24 @@ setOutputFile, setDynOutputFile, setOutputHi, setDumpPrefixForce
setObjectDir f d = d { objectDir = Just f}
setHiDir f d = d { hiDir = Just f}
+setHieDir f d = d { hieDir = Just f}
setStubDir f d = d { stubDir = Just f
, includePaths = addGlobalInclude (includePaths d) [f] }
-- -stubdir D adds an implicit -I D, so that gcc can find the _stub.h file
-- \#included from the .hc file when compiling via C (i.e. unregisterised
-- builds).
setDumpDir f d = d { dumpDir = Just f}
-setOutputDir f = setObjectDir f . setHiDir f . setStubDir f . setDumpDir f
+setOutputDir f = setObjectDir f
+ . setHieDir f
+ . setHiDir f
+ . setStubDir f
+ . setDumpDir f
setDylibInstallName f d = d { dylibInstallName = Just f}
setObjectSuf f d = d { objectSuf = f}
setDynObjectSuf f d = d { dynObjectSuf = f}
setHiSuf f d = d { hiSuf = f}
+setHieSuf f d = d { hieSuf = f}
setDynHiSuf f d = d { dynHiSuf = f}
setHcSuf f d = d { hcSuf = f}
@@ -3062,8 +3074,10 @@ dynamic_flags_deps = [
, make_ord_flag defGhcFlag "dynosuf" (hasArg setDynObjectSuf)
, make_ord_flag defGhcFlag "hcsuf" (hasArg setHcSuf)
, make_ord_flag defGhcFlag "hisuf" (hasArg setHiSuf)
+ , make_ord_flag defGhcFlag "hiesuf" (hasArg setHieSuf)
, make_ord_flag defGhcFlag "dynhisuf" (hasArg setDynHiSuf)
, make_ord_flag defGhcFlag "hidir" (hasArg setHiDir)
+ , make_ord_flag defGhcFlag "hiedir" (hasArg setHieDir)
, make_ord_flag defGhcFlag "tmpdir" (hasArg setTmpDir)
, make_ord_flag defGhcFlag "stubdir" (hasArg setStubDir)
, make_ord_flag defGhcFlag "dumpdir" (hasArg setDumpDir)
@@ -4088,6 +4102,7 @@ fFlagsDeps = [
flagSpec "gen-manifest" Opt_GenManifest,
flagSpec "ghci-history" Opt_GhciHistory,
flagSpec "ghci-leak-check" Opt_GhciLeakCheck,
+ flagSpec "validate-ide-info" Opt_ValidateHie,
flagGhciSpec "local-ghci-history" Opt_LocalGhciHistory,
flagGhciSpec "no-it" Opt_NoIt,
flagSpec "ghci-sandbox" Opt_GhciSandbox,
@@ -4143,6 +4158,7 @@ fFlagsDeps = [
flagSpec "strictness" Opt_Strictness,
flagSpec "use-rpaths" Opt_RPath,
flagSpec "write-interface" Opt_WriteInterface,
+ flagSpec "write-ide-info" Opt_WriteHie,
flagSpec "unbox-small-strict-fields" Opt_UnboxSmallStrictFields,
flagSpec "unbox-strict-fields" Opt_UnboxStrictFields,
flagSpec "version-macros" Opt_VersionMacros,
diff --git a/compiler/main/Finder.hs b/compiler/main/Finder.hs
index 57d608bbf7..2db0a5e0b4 100644
--- a/compiler/main/Finder.hs
+++ b/compiler/main/Finder.hs
@@ -482,23 +482,27 @@ mkHomeModLocation2 dflags mod src_basename ext = do
obj_fn = mkObjPath dflags src_basename mod_basename
hi_fn = mkHiPath dflags src_basename mod_basename
+ hie_fn = mkHiePath dflags src_basename mod_basename
return (ModLocation{ ml_hs_file = Just (src_basename <.> ext),
ml_hi_file = hi_fn,
- ml_obj_file = obj_fn })
+ ml_obj_file = obj_fn,
+ ml_hie_file = hie_fn })
mkHiOnlyModLocation :: DynFlags -> Suffix -> FilePath -> String
-> IO ModLocation
mkHiOnlyModLocation dflags hisuf path basename
= do let full_basename = path </> basename
obj_fn = mkObjPath dflags full_basename basename
+ hie_fn = mkHiePath dflags full_basename basename
return ModLocation{ ml_hs_file = Nothing,
ml_hi_file = full_basename <.> hisuf,
-- Remove the .hi-boot suffix from
-- hi_file, if it had one. We always
-- want the name of the real .hi file
-- in the ml_hi_file field.
- ml_obj_file = obj_fn
+ ml_obj_file = obj_fn,
+ ml_hie_file = hie_fn
}
-- | Constructs the filename of a .o file for a given source file.
@@ -532,6 +536,21 @@ mkHiPath dflags basename mod_basename = hi_basename <.> hisuf
hi_basename | Just dir <- hidir = dir </> mod_basename
| otherwise = basename
+-- | Constructs the filename of a .hie file for a given source file.
+-- Does /not/ check whether the .hie file exists
+mkHiePath
+ :: DynFlags
+ -> FilePath -- the filename of the source file, minus the extension
+ -> String -- the module name with dots replaced by slashes
+ -> FilePath
+mkHiePath dflags basename mod_basename = hie_basename <.> hiesuf
+ where
+ hiedir = hieDir dflags
+ hiesuf = hieSuf dflags
+
+ hie_basename | Just dir <- hiedir = dir </> mod_basename
+ | otherwise = basename
+
-- -----------------------------------------------------------------------------
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index 39b6427173..8b2bc01ffe 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -2186,6 +2186,8 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
then liftIO $ getObjTimestamp location NotBoot
else return Nothing
hi_timestamp <- maybeGetIfaceDate dflags location
+ let hie_location = ml_hie_file location
+ hie_timestamp <- modificationTimeIfExists hie_location
-- We have to repopulate the Finder's cache because it
-- was flushed before the downsweep.
@@ -2193,7 +2195,8 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
(moduleName (ms_mod old_summary)) (ms_location old_summary)
return old_summary{ ms_obj_date = obj_timestamp
- , ms_iface_date = hi_timestamp }
+ , ms_iface_date = hi_timestamp
+ , ms_hie_date = hie_timestamp }
else
new_summary src_timestamp
@@ -2232,6 +2235,7 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
else return Nothing
hi_timestamp <- maybeGetIfaceDate dflags location
+ hie_timestamp <- modificationTimeIfExists (ml_hie_file location)
extra_sig_imports <- findExtraSigImports hsc_env hsc_src mod_name
required_by_imports <- implicitRequirements hsc_env the_imps
@@ -2247,6 +2251,7 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
ms_textual_imps = the_imps ++ extra_sig_imports ++ required_by_imports,
ms_hs_date = src_timestamp,
ms_iface_date = hi_timestamp,
+ ms_hie_date = hie_timestamp,
ms_obj_date = obj_timestamp })
findSummaryBySourceFile :: [ModSummary] -> FilePath -> Maybe ModSummary
@@ -2304,8 +2309,10 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
then getObjTimestamp location is_boot
else return Nothing
hi_timestamp <- maybeGetIfaceDate dflags location
+ hie_timestamp <- modificationTimeIfExists (ml_hie_file location)
return (Just (Right old_summary{ ms_obj_date = obj_timestamp
- , ms_iface_date = hi_timestamp}))
+ , ms_iface_date = hi_timestamp
+ , ms_hie_date = hie_timestamp }))
| otherwise =
-- source changed: re-summarise.
new_summary location (ms_mod old_summary) src_fn src_timestamp
@@ -2389,6 +2396,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
else return Nothing
hi_timestamp <- maybeGetIfaceDate dflags location
+ hie_timestamp <- modificationTimeIfExists (ml_hie_file location)
extra_sig_imports <- findExtraSigImports hsc_env hsc_src mod_name
required_by_imports <- implicitRequirements hsc_env the_imps
@@ -2404,6 +2412,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
ms_textual_imps = the_imps ++ extra_sig_imports ++ required_by_imports,
ms_hs_date = src_timestamp,
ms_iface_date = hi_timestamp,
+ ms_hie_date = hie_timestamp,
ms_obj_date = obj_timestamp })))
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index 9b9edf7d21..c2c912451b 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -85,6 +85,7 @@ module HscMain
import GhcPrelude
import Data.Data hiding (Fixity, TyCon)
+import Data.Maybe ( fromJust )
import Id
import GHCi ( addSptEntry )
import GHCi.RemoteTypes ( ForeignHValue )
@@ -167,10 +168,15 @@ import Data.IORef
import System.FilePath as FilePath
import System.Directory
import System.IO (fixIO)
-import qualified Data.Map as Map
+import qualified Data.Map as M
import qualified Data.Set as S
import Data.Set (Set)
+import HieAst ( mkHieFile )
+import HieTypes ( getAsts, hie_asts )
+import HieBin ( readHieFile, writeHieFile )
+import HieDebug ( diffFile, validateScopes )
+
#include "HsVersions.h"
@@ -379,8 +385,8 @@ hscParse' mod_summary
hpm_module = rdr_module,
hpm_src_files = srcs2,
hpm_annotations
- = (Map.fromListWith (++) $ annotations pst,
- Map.fromList $ ((noSrcSpan,comment_q pst)
+ = (M.fromListWith (++) $ annotations pst,
+ M.fromList $ ((noSrcSpan,comment_q pst)
:(annotations_comments pst)))
}
@@ -392,15 +398,41 @@ hscParse' mod_summary
-- -----------------------------------------------------------------------------
-- | If the renamed source has been kept, extract it. Dump it if requested.
-extract_renamed_stuff :: TcGblEnv -> Hsc (TcGblEnv, RenamedStuff)
-extract_renamed_stuff tc_result = do
+extract_renamed_stuff :: ModSummary -> TcGblEnv -> Hsc RenamedStuff
+extract_renamed_stuff mod_summary tc_result = do
let rn_info = getRenamedStuff tc_result
dflags <- getDynFlags
liftIO $ dumpIfSet_dyn dflags Opt_D_dump_rn_ast "Renamer" $
showAstData NoBlankSrcSpan rn_info
- return (tc_result, rn_info)
+ -- Create HIE files
+ when (gopt Opt_WriteHie dflags) $ do
+ hieFile <- mkHieFile mod_summary (tcg_binds tc_result)
+ (fromJust rn_info)
+ let out_file = ml_hie_file $ ms_location mod_summary
+ liftIO $ writeHieFile out_file hieFile
+
+ -- Validate HIE files
+ when (gopt Opt_ValidateHie dflags) $ do
+ hs_env <- Hsc $ \e w -> return (e, w)
+ liftIO $ do
+ -- Validate Scopes
+ case validateScopes $ getAsts $ hie_asts hieFile of
+ [] -> putMsg dflags $ text "Got valid scopes"
+ xs -> do
+ putMsg dflags $ text "Got invalid scopes"
+ mapM_ (putMsg dflags) xs
+ -- Roundtrip testing
+ nc <- readIORef $ hsc_NC hs_env
+ (file', _) <- readHieFile nc out_file
+ case diffFile hieFile file' of
+ [] ->
+ putMsg dflags $ text "Got no roundtrip errors"
+ xs -> do
+ putMsg dflags $ text "Got roundtrip errors"
+ mapM_ (putMsg dflags) xs
+ return rn_info
-- -----------------------------------------------------------------------------
@@ -408,22 +440,23 @@ extract_renamed_stuff tc_result = do
hscTypecheckRename :: HscEnv -> ModSummary -> HsParsedModule
-> IO (TcGblEnv, RenamedStuff)
hscTypecheckRename hsc_env mod_summary rdr_module = runHsc hsc_env $ do
- tc_result <- hscTypecheck True mod_summary (Just rdr_module)
- extract_renamed_stuff tc_result
+ tc_result <- hsc_typecheck True mod_summary (Just rdr_module)
+ rn_info <- extract_renamed_stuff mod_summary tc_result
+ return (tc_result, rn_info)
+-- | Rename and typecheck a module, but don't return the renamed syntax
hscTypecheck :: Bool -- ^ Keep renamed source?
-> ModSummary -> Maybe HsParsedModule
-> Hsc TcGblEnv
hscTypecheck keep_rn mod_summary mb_rdr_module = do
- tc_result <- hscTypecheck' keep_rn mod_summary mb_rdr_module
- _ <- extract_renamed_stuff tc_result
+ tc_result <- hsc_typecheck keep_rn mod_summary mb_rdr_module
+ _ <- extract_renamed_stuff mod_summary tc_result
return tc_result
-
-hscTypecheck' :: Bool -- ^ Keep renamed source?
+hsc_typecheck :: Bool -- ^ Keep renamed source?
-> ModSummary -> Maybe HsParsedModule
-> Hsc TcGblEnv
-hscTypecheck' keep_rn mod_summary mb_rdr_module = do
+hsc_typecheck keep_rn mod_summary mb_rdr_module = do
hsc_env <- getHscEnv
let hsc_src = ms_hsc_src mod_summary
dflags = hsc_dflags hsc_env
@@ -433,6 +466,7 @@ hscTypecheck' keep_rn mod_summary mb_rdr_module = do
inner_mod = canonicalizeHomeModule dflags mod_name
src_filename = ms_hspp_file mod_summary
real_loc = realSrcLocSpan $ mkRealSrcLoc (mkFastString src_filename) 1 1
+ keep_rn' = gopt Opt_WriteHie dflags || keep_rn
MASSERT( moduleUnitId outer_mod == thisPackage dflags )
if hsc_src == HsigFile && not (isHoleModule inner_mod)
then ioMsgMaybe $ tcRnInstantiateSignature hsc_env outer_mod' real_loc
@@ -440,7 +474,7 @@ hscTypecheck' keep_rn mod_summary mb_rdr_module = do
do hpm <- case mb_rdr_module of
Just hpm -> return hpm
Nothing -> hscParse' mod_summary
- tc_result0 <- tcRnModule' mod_summary keep_rn hpm
+ tc_result0 <- tcRnModule' mod_summary keep_rn' hpm
if hsc_src == HsigFile
then do (iface, _, _) <- liftIO $ hscSimpleIface hsc_env tc_result0 Nothing
ioMsgMaybe $
@@ -1411,7 +1445,8 @@ hscCompileCmmFile hsc_env filename output_filename = runHsc hsc_env $ do
where
no_loc = ModLocation{ ml_hs_file = Just filename,
ml_hi_file = panic "hscCompileCmmFile: no hi file",
- ml_obj_file = panic "hscCompileCmmFile: no obj file" }
+ ml_obj_file = panic "hscCompileCmmFile: no obj file",
+ ml_hie_file = panic "hscCompileCmmFile: no hie file"}
-------------------- Stuff for new code gen ---------------------
@@ -1591,7 +1626,8 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
-- We use a basically null location for iNTERACTIVE
let iNTERACTIVELoc = ModLocation{ ml_hs_file = Nothing,
ml_hi_file = panic "hsDeclsWithLocation:ml_hi_file",
- ml_obj_file = panic "hsDeclsWithLocation:ml_hi_file"}
+ ml_obj_file = panic "hsDeclsWithLocation:ml_obj_file",
+ ml_hie_file = panic "hsDeclsWithLocation:ml_hie_file" }
ds_result <- hscDesugar' iNTERACTIVELoc tc_gblenv
{- Simplify -}
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index d0cf7e0dd8..456332daeb 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -2752,6 +2752,8 @@ data ModSummary
-- ^ Timestamp of hi file, if we *only* are typechecking (it is
-- 'Nothing' otherwise.
-- See Note [Recompilation checking in -fno-code mode] and #9243
+ ms_hie_date :: Maybe UTCTime,
+ -- ^ Timestamp of hie file, if we have one
ms_srcimps :: [(Maybe FastString, Located ModuleName)],
-- ^ Source imports of the module
ms_textual_imps :: [(Maybe FastString, Located ModuleName)],
@@ -2833,7 +2835,7 @@ showModMsg dflags target recomp mod_summary = showSDoc dflags $
{-
************************************************************************
* *
-\subsection{Recmpilation}
+\subsection{Recompilation}
* *
************************************************************************
-}