diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2021-05-05 14:02:37 +0100 |
---|---|---|
committer | Matthew Pickering <matthewtpickering@gmail.com> | 2021-06-03 08:46:47 +0100 |
commit | 25977ab542a30df4ae71d9699d015bcdd1ab7cfb (patch) | |
tree | fc2195f9ceb5651603aa5fed03580eb47e0412d7 /compiler/GHC/Utils | |
parent | 79d12d34ad7177d33b191305f2c0157349f97355 (diff) | |
download | haskell-25977ab542a30df4ae71d9699d015bcdd1ab7cfb.tar.gz |
Driver Rework Patch
This patch comprises of four different but closely related ideas. The
net result is fixing a large number of open issues with the driver
whilst making it simpler to understand.
1. Use the hash of the source file to determine whether the source file
has changed or not. This makes the recompilation checking more robust to
modern build systems which are liable to copy files around changing
their modification times.
2. Remove the concept of a "stable module", a stable module was one
where the object file was older than the source file, and all transitive
dependencies were also stable. Now we don't rely on the modification
time of the source file, the notion of stability is moot.
3. Fix TH/plugin recompilation after the removal of stable modules. The
TH recompilation check used to rely on stable modules. Now there is a
uniform and simple way, we directly track the linkables which were
loaded into the interpreter whilst compiling a module. This is an
over-approximation but more robust wrt package dependencies changing.
4. Fix recompilation checking for dynamic object files. Now we actually
check if the dynamic object file exists when compiling with -dynamic-too
Fixes #19774 #19771 #19758 #17434 #11556 #9121 #8211 #16495 #7277 #16093
Diffstat (limited to 'compiler/GHC/Utils')
-rw-r--r-- | compiler/GHC/Utils/Misc.hs | 25 | ||||
-rw-r--r-- | compiler/GHC/Utils/Outputable.hs | 5 |
2 files changed, 26 insertions, 4 deletions
diff --git a/compiler/GHC/Utils/Misc.hs b/compiler/GHC/Utils/Misc.hs index 8dde1c7296..d19d78c876 100644 --- a/compiler/GHC/Utils/Misc.hs +++ b/compiler/GHC/Utils/Misc.hs @@ -66,7 +66,7 @@ module GHC.Utils.Misc ( dropTail, capitalise, -- * Sorting - sortWith, minWith, nubSort, ordNub, + sortWith, minWith, nubSort, ordNub, ordNubOn, -- * Comparisons isEqual, eqListBy, eqMaybeBy, @@ -100,6 +100,7 @@ module GHC.Utils.Misc ( doesDirNameExist, getModificationUTCTime, modificationTimeIfExists, + fileHashIfExists, withAtomicRename, -- * Filenames and paths @@ -132,6 +133,7 @@ import GHC.Prelude import GHC.Utils.Exception import GHC.Utils.Panic.Plain import GHC.Utils.Constants +import GHC.Utils.Fingerprint import Data.Data import qualified Data.List as List @@ -639,13 +641,18 @@ nubSort = Set.toAscList . Set.fromList -- | Remove duplicates but keep elements in order. -- O(n * log n) ordNub :: Ord a => [a] -> [a] -ordNub xs +ordNub xs = ordNubOn id xs + +-- | Remove duplicates but keep elements in order. +-- O(n * log n) +ordNubOn :: Ord b => (a -> b) -> [a] -> [a] +ordNubOn f xs = go Set.empty xs where go _ [] = [] go s (x:xs) - | Set.member x s = go s xs - | otherwise = x : go (Set.insert x s) xs + | Set.member (f x) s = go s xs + | otherwise = x : go (Set.insert (f x) s) xs {- @@ -1292,6 +1299,16 @@ modificationTimeIfExists f = else ioError e -- -------------------------------------------------------------- +-- check existence & hash at the same time + +fileHashIfExists :: FilePath -> IO (Maybe Fingerprint) +fileHashIfExists f = + (do t <- getFileHash f; return (Just t)) + `catchIO` \e -> if isDoesNotExistError e + then return Nothing + else ioError e + +-- -------------------------------------------------------------- -- atomic file writing by writing to a temporary file first (see #14533) -- -- This should be used in all cases where GHC writes files to disk diff --git a/compiler/GHC/Utils/Outputable.hs b/compiler/GHC/Utils/Outputable.hs index d6c79895d5..7d33007ead 100644 --- a/compiler/GHC/Utils/Outputable.hs +++ b/compiler/GHC/Utils/Outputable.hs @@ -134,6 +134,8 @@ import Data.Graph (SCC(..)) import Data.List (intersperse) import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NEL +import Data.Time +import Data.Time.Format.ISO8601 import GHC.Fingerprint import GHC.Show ( showMultiLineString ) @@ -918,6 +920,9 @@ instance Outputable Double where instance Outputable () where ppr _ = text "()" +instance Outputable UTCTime where + ppr = text . formatShow iso8601Format + instance (Outputable a) => Outputable [a] where ppr xs = brackets (fsep (punctuate comma (map ppr xs))) |