Skip to content

Commit ae33fcf

Browse files
committed
Add Distribution.Utils.Structured
It defines `Structured` type class, which we use to prepend a hash to cached `Binary` blobs. Thus we can catch early, if format is changed, avoiding corrupt cache making cabal behave weirdly. Plenty types got Typeable instances, as it's a superclass of Structured This commit also introduces new compat modules: - Distribution.Compat.Typeable with typeRep - Distribution.Client.Compat.Orphans, to collect at least some orphans into central place.
1 parent 228260d commit ae33fcf

File tree

128 files changed

+1041
-272
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+1041
-272
lines changed

Cabal/Cabal.cabal

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ library
322322
Distribution.Utils.IOData
323323
Distribution.Utils.LogProgress
324324
Distribution.Utils.MapAccum
325+
Distribution.Utils.Structured
325326
Distribution.Compat.CreatePipe
326327
Distribution.Compat.Directory
327328
Distribution.Compat.Environment
@@ -335,6 +336,7 @@ library
335336
Distribution.Compat.Semigroup
336337
Distribution.Compat.Stack
337338
Distribution.Compat.Time
339+
Distribution.Compat.Typeable
338340
Distribution.Compat.DList
339341
Distribution.Compiler
340342
Distribution.InstalledPackageInfo
@@ -619,8 +621,10 @@ test-suite unit-tests
619621
UnitTests.Distribution.Utils.Generic
620622
UnitTests.Distribution.Utils.NubList
621623
UnitTests.Distribution.Utils.ShortText
624+
UnitTests.Distribution.Utils.Structured
622625
UnitTests.Distribution.Version
623626
UnitTests.Distribution.PkgconfigVersion
627+
UnitTests.Orphans
624628
main-is: UnitTests.hs
625629
build-depends:
626630
array,

Cabal/Distribution/Backpack.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ data OpenUnitId
9898
-- TODO: cache holes?
9999

100100
instance Binary OpenUnitId
101-
101+
instance Structured OpenUnitId
102102
instance NFData OpenUnitId where
103103
rnf (IndefFullUnitId cid subst) = rnf cid `seq` rnf subst
104104
rnf (DefiniteUnitId uid) = rnf uid
@@ -165,6 +165,7 @@ data OpenModule
165165
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
166166

167167
instance Binary OpenModule
168+
instance Structured OpenModule
168169

169170
instance NFData OpenModule where
170171
rnf (OpenModule uid mod_name) = rnf uid `seq` rnf mod_name

Cabal/Distribution/Backpack/ModuleShape.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE DeriveDataTypeable #-}
12
{-# LANGUAGE DeriveGeneric #-}
23
-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
34
module Distribution.Backpack.ModuleShape (
@@ -29,9 +30,10 @@ data ModuleShape = ModuleShape {
2930
modShapeProvides :: OpenModuleSubst,
3031
modShapeRequires :: Set ModuleName
3132
}
32-
deriving (Eq, Show, Generic)
33+
deriving (Eq, Show, Generic, Typeable)
3334

3435
instance Binary ModuleShape
36+
instance Structured ModuleShape
3537

3638
instance ModSubst ModuleShape where
3739
modSubst subst (ModuleShape provs reqs)

Cabal/Distribution/Compat/Graph.hs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
{-# LANGUAGE TypeFamilies #-}
2-
{-# LANGUAGE CPP #-}
3-
{-# LANGUAGE FlexibleContexts #-}
4-
{-# LANGUAGE DeriveDataTypeable #-}
1+
{-# LANGUAGE BangPatterns #-}
2+
{-# LANGUAGE CPP #-}
3+
{-# LANGUAGE DeriveDataTypeable #-}
4+
{-# LANGUAGE FlexibleContexts #-}
5+
{-# LANGUAGE ScopedTypeVariables #-}
6+
{-# LANGUAGE TypeFamilies #-}
57
{-# LANGUAGE UndecidableInstances #-}
6-
{-# LANGUAGE BangPatterns #-}
78
-----------------------------------------------------------------------------
89
-- |
910
-- Module : Distribution.Compat.Graph
@@ -83,20 +84,21 @@ module Distribution.Compat.Graph (
8384
nodeValue,
8485
) where
8586

87+
import Distribution.Compat.Prelude hiding (empty, lookup, null, toList)
8688
import Prelude ()
87-
import qualified Distribution.Compat.Prelude as Prelude
88-
import Distribution.Compat.Prelude hiding (lookup, null, empty, toList)
89-
90-
import Data.Graph (SCC(..))
91-
import qualified Data.Graph as G
9289

93-
import qualified Data.Map.Strict as Map
94-
import qualified Data.Set as Set
95-
import qualified Data.Array as Array
96-
import Data.Array ((!))
97-
import qualified Data.Tree as Tree
98-
import Data.Either (partitionEithers)
99-
import qualified Data.Foldable as Foldable
90+
import Data.Array ((!))
91+
import Data.Either (partitionEithers)
92+
import Data.Graph (SCC (..))
93+
import Distribution.Utils.Structured (Structure (..), Structured (..))
94+
95+
import qualified Data.Array as Array
96+
import qualified Data.Foldable as Foldable
97+
import qualified Data.Graph as G
98+
import qualified Data.Map.Strict as Map
99+
import qualified Data.Set as Set
100+
import qualified Data.Tree as Tree
101+
import qualified Distribution.Compat.Prelude as Prelude
100102

101103
-- | A graph of nodes @a@. The nodes are expected to have instance
102104
-- of class 'IsNode'.
@@ -129,6 +131,9 @@ instance (IsNode a, Binary a, Show (Key a)) => Binary (Graph a) where
129131
put x = put (toList x)
130132
get = fmap fromDistinctList get
131133

134+
instance Structured a => Structured (Graph a) where
135+
structure p = Nominal (typeRep p) 0 "Graph" [structure (Proxy :: Proxy a)]
136+
132137
instance (Eq (Key a), Eq a) => Eq (Graph a) where
133138
g1 == g2 = graphMap g1 == graphMap g2
134139

Cabal/Distribution/Compat/Prelude.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ module Distribution.Compat.Prelude (
3333
-- * Common type-classes
3434
Semigroup (..),
3535
gmappend, gmempty,
36-
Typeable,
36+
Typeable, TypeRep, typeRep,
3737
Data,
3838
Generic,
3939
NFData (..), genericRnf,
4040
Binary (..),
41+
Structured,
4142
Alternative (..),
4243
MonadPlus (..),
4344
IsString (..),
@@ -137,7 +138,7 @@ import qualified Data.Foldable
137138
import Control.Applicative (Alternative (..))
138139
import Control.DeepSeq (NFData (..))
139140
import Data.Data (Data)
140-
import Data.Typeable (Typeable)
141+
import Distribution.Compat.Typeable (Typeable, TypeRep, typeRep)
141142
import Distribution.Compat.Binary (Binary (..))
142143
import Distribution.Compat.Semigroup (Semigroup (..), gmappend, gmempty)
143144
import GHC.Generics (Generic, Rep(..),
@@ -167,6 +168,8 @@ import qualified Text.PrettyPrint as Disp
167168
import qualified Prelude as OrigPrelude
168169
import Distribution.Compat.Stack
169170

171+
import Distribution.Utils.Structured (Structured)
172+
170173
type IO a = WithCallStack (OrigPrelude.IO a)
171174
type NoCallStackIO a = OrigPrelude.IO a
172175

Cabal/Distribution/Compat/Semigroup.hs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE DeriveDataTypeable #-}
23
{-# LANGUAGE DeriveGeneric #-}
34
{-# LANGUAGE FlexibleContexts #-}
45
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -21,6 +22,8 @@ module Distribution.Compat.Semigroup
2122
) where
2223

2324
import Distribution.Compat.Binary (Binary)
25+
import Distribution.Utils.Structured (Structured)
26+
import Data.Typeable (Typeable)
2427

2528
import GHC.Generics
2629
-- Data.Semigroup is available since GHC 8.0/base-4.9 in `base`
@@ -38,7 +41,9 @@ instance Semigroup (First' a) where
3841

3942
-- | A copy of 'Data.Semigroup.Last'.
4043
newtype Last' a = Last' { getLast' :: a }
41-
deriving (Eq, Ord, Read, Show, Binary)
44+
deriving (Eq, Ord, Read, Show, Generic, Binary, Typeable)
45+
46+
instance Structured a => Structured (Last' a)
4247

4348
instance Semigroup (Last' a) where
4449
_ <> b = b
@@ -49,7 +54,9 @@ instance Functor Last' where
4954
-- | A wrapper around 'Maybe', providing the 'Semigroup' and 'Monoid' instances
5055
-- implemented for 'Maybe' since @base-4.11@.
5156
newtype Option' a = Option' { getOption' :: Maybe a }
52-
deriving (Eq, Ord, Read, Show, Binary, Functor)
57+
deriving (Eq, Ord, Read, Show, Binary, Generic, Functor, Typeable)
58+
59+
instance Structured a => Structured (Option' a)
5360

5461
instance Semigroup a => Semigroup (Option' a) where
5562
Option' (Just a) <> Option' (Just b) = Option' (Just (a <> b))

Cabal/Distribution/Compat/Time.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE DeriveDataTypeable #-}
3+
{-# LANGUAGE DeriveGeneric #-}
24
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
35
{-# LANGUAGE RankNTypes #-}
46
{-# LANGUAGE FlexibleContexts #-}
@@ -55,7 +57,9 @@ import System.Posix.Files ( modificationTime )
5557
-- | An opaque type representing a file's modification time, represented
5658
-- internally as a 64-bit unsigned integer in the Windows UTC format.
5759
newtype ModTime = ModTime Word64
58-
deriving (Binary, Bounded, Eq, Ord)
60+
deriving (Binary, Generic, Bounded, Eq, Ord, Typeable)
61+
62+
instance Structured ModTime
5963

6064
instance Show ModTime where
6165
show (ModTime x) = show x

Cabal/Distribution/Compat/Typeable.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE ScopedTypeVariables #-}
3+
module Distribution.Compat.Typeable (
4+
Typeable,
5+
TypeRep,
6+
typeRep,
7+
) where
8+
9+
#if MIN_VERSION_base(4,7,0)
10+
import Data.Typeable (Typeable, TypeRep, typeRep)
11+
#else
12+
import Data.Typeable (Typeable, TypeRep, typeOf)
13+
#endif
14+
15+
#if !MIN_VERSION_base(4,7,0)
16+
typeRep :: forall a proxy. Typeable a => proxy a -> TypeRep
17+
typeRep _ = typeOf (undefined :: a)
18+
#endif

Cabal/Distribution/Compiler.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ data CompilerFlavor =
6666
deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
6767

6868
instance Binary CompilerFlavor
69-
69+
instance Structured CompilerFlavor
7070
instance NFData CompilerFlavor where rnf = genericRnf
7171

7272
knownCompilerFlavors :: [CompilerFlavor]
@@ -125,6 +125,7 @@ data PerCompilerFlavor v = PerCompilerFlavor v v
125125
deriving (Generic, Show, Read, Eq, Typeable, Data)
126126

127127
instance Binary a => Binary (PerCompilerFlavor a)
128+
instance Structured a => Structured (PerCompilerFlavor a)
128129
instance NFData a => NFData (PerCompilerFlavor a)
129130

130131
perCompilerFlavorToList :: PerCompilerFlavor v -> [(CompilerFlavor, v)]
@@ -143,10 +144,10 @@ instance (Semigroup a, Monoid a) => Monoid (PerCompilerFlavor a) where
143144
-- ------------------------------------------------------------
144145

145146
data CompilerId = CompilerId CompilerFlavor Version
146-
deriving (Eq, Generic, Ord, Read, Show)
147+
deriving (Eq, Generic, Ord, Read, Show, Typeable)
147148

148149
instance Binary CompilerId
149-
150+
instance Structured CompilerId
150151
instance NFData CompilerId where rnf = genericRnf
151152

152153
instance Pretty CompilerId where
@@ -192,9 +193,10 @@ instance Binary CompilerInfo
192193
data AbiTag
193194
= NoAbiTag
194195
| AbiTag String
195-
deriving (Eq, Generic, Show, Read)
196+
deriving (Eq, Generic, Show, Read, Typeable)
196197

197198
instance Binary AbiTag
199+
instance Structured AbiTag
198200

199201
instance Pretty AbiTag where
200202
pretty NoAbiTag = Disp.empty

Cabal/Distribution/License.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ data License =
128128
deriving (Generic, Read, Show, Eq, Typeable, Data)
129129

130130
instance Binary License
131-
131+
instance Structured License
132132
instance NFData License where rnf = genericRnf
133133

134134
-- | The list of all currently recognised licenses.

Cabal/Distribution/ModuleName.hs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{-# LANGUAGE DeriveDataTypeable #-}
2-
{-# LANGUAGE DeriveGeneric #-}
2+
{-# LANGUAGE DeriveGeneric #-}
33

44
-----------------------------------------------------------------------------
55
-- |
@@ -23,24 +23,24 @@ module Distribution.ModuleName (
2323
validModuleComponent,
2424
) where
2525

26-
import Prelude ()
2726
import Distribution.Compat.Prelude
27+
import Prelude ()
2828

29-
import Distribution.Utils.ShortText
30-
import System.FilePath ( pathSeparator )
31-
32-
import Distribution.Pretty
3329
import Distribution.Parsec
30+
import Distribution.Pretty
31+
import Distribution.Utils.ShortText
32+
import System.FilePath (pathSeparator)
3433

3534
import qualified Distribution.Compat.CharParsing as P
36-
import qualified Text.PrettyPrint as Disp
35+
import qualified Text.PrettyPrint as Disp
3736

3837
-- | A valid Haskell module name.
3938
--
4039
newtype ModuleName = ModuleName ShortTextLst
4140
deriving (Eq, Generic, Ord, Read, Show, Typeable, Data)
4241

4342
instance Binary ModuleName
43+
instance Structured ModuleName
4444

4545
instance NFData ModuleName where
4646
rnf (ModuleName ms) = rnf ms
@@ -131,6 +131,8 @@ instance Binary ShortTextLst where
131131
put = put . stlToList
132132
get = stlFromList <$> get
133133

134+
instance Structured ShortTextLst
135+
134136
stlToList :: ShortTextLst -> [ShortText]
135137
stlToList STLNil = []
136138
stlToList (STLCons st next) = st : stlToList next

Cabal/Distribution/SPDX/License.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ data License
4444
deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)
4545

4646
instance Binary License
47+
instance Structured License
4748

4849
instance NFData License where
4950
rnf NONE = ()

Cabal/Distribution/SPDX/LicenseExceptionId.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ module Distribution.SPDX.LicenseExceptionId (
1212
import Distribution.Compat.Prelude
1313
import Prelude ()
1414

15+
import Distribution.Compat.Lens (set)
1516
import Distribution.Pretty
1617
import Distribution.Parsec
1718
import Distribution.Utils.Generic (isAsciiAlphaNum)
19+
import Distribution.Utils.Structured (Structured (..), nominalStructure, typeVersion)
1820
import Distribution.SPDX.LicenseListVersion
1921

2022
import qualified Data.Binary.Get as Binary
@@ -75,6 +77,10 @@ instance Binary LicenseExceptionId where
7577
then fail "Too large LicenseExceptionId tag"
7678
else return (toEnum (fromIntegral i))
7779

80+
-- note: remember to bump version each time the definition changes
81+
instance Structured LicenseExceptionId where
82+
structure p = set typeVersion 306 $ nominalStructure p
83+
7884
instance Pretty LicenseExceptionId where
7985
pretty = Disp.text . licenseExceptionId
8086

Cabal/Distribution/SPDX/LicenseExpression.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ simpleLicenseExpression i = ELicense (ELicenseId i) Nothing
6060

6161
instance Binary LicenseExpression
6262
instance Binary SimpleLicenseExpression
63+
instance Structured SimpleLicenseExpression
64+
instance Structured LicenseExpression
6365

6466
instance Pretty LicenseExpression where
6567
pretty = go 0

Cabal/Distribution/SPDX/LicenseId.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ module Distribution.SPDX.LicenseId (
1515
import Distribution.Compat.Prelude
1616
import Prelude ()
1717

18+
import Distribution.Compat.Lens (set)
1819
import Distribution.Pretty
1920
import Distribution.Parsec
2021
import Distribution.Utils.Generic (isAsciiAlphaNum)
22+
import Distribution.Utils.Structured (Structured (..), nominalStructure, typeVersion)
2123
import Distribution.SPDX.LicenseListVersion
2224

2325
import qualified Data.Binary.Get as Binary
@@ -413,6 +415,10 @@ instance Binary LicenseId where
413415
then fail "Too large LicenseId tag"
414416
else return (toEnum (fromIntegral i))
415417

418+
-- note: remember to bump version each time the definition changes
419+
instance Structured LicenseId where
420+
structure p = set typeVersion 306 $ nominalStructure p
421+
416422
instance Pretty LicenseId where
417423
pretty = Disp.text . licenseId
418424

Cabal/Distribution/SPDX/LicenseReference.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ licenseDocumentRef :: LicenseRef -> Maybe String
3434
licenseDocumentRef = _lrDocument
3535

3636
instance Binary LicenseRef
37+
instance Structured LicenseRef
3738

3839
instance NFData LicenseRef where
3940
rnf (LicenseRef d l) = rnf d `seq` rnf l

0 commit comments

Comments
 (0)