diff --git a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs
index 115fa76889907c827404311584a475680c9cdc9e..cbfb8c079fe3761e44f4f98810f2049a94ff09d3 100644
--- a/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs
+++ b/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs
@@ -19,7 +19,6 @@ import Distribution.Compiler
 import Distribution.FieldGrammar.Newtypes
 import Distribution.ModuleName
 import Distribution.Simple.Compiler
-import Distribution.Simple.Flag                    (Flag (..))
 import Distribution.Simple.InstallDirs
 import Distribution.Simple.Setup                   (HaddockTarget (..), TestShowDetails (..), DumpBuildInfo)
 import Distribution.SPDX
@@ -242,23 +241,6 @@ instance Arbitrary LibraryName where
     shrink (LSubLibName _) = [LMainLibName]
     shrink _               = []
 
--------------------------------------------------------------------------------
--- option flags
--------------------------------------------------------------------------------
-
-instance Arbitrary a => Arbitrary (Flag a) where
-    arbitrary = arbitrary1
-
-    shrink NoFlag   = []
-    shrink (Flag x) = NoFlag : [ Flag x' | x' <- shrink x ]
-
-instance Arbitrary1 Flag where
-    liftArbitrary genA = sized $ \sz ->
-        if sz <= 0
-        then pure NoFlag
-        else frequency [ (1, pure NoFlag)
-                       , (3, Flag <$> genA) ]
-
 -------------------------------------------------------------------------------
 -- GPD flags
 -------------------------------------------------------------------------------
diff --git a/Cabal-syntax/src/Distribution/Utils/Structured.hs b/Cabal-syntax/src/Distribution/Utils/Structured.hs
index 630566ef648c56314a7a9b6ab87299aeb7756089..b88165a89bb15fa5ff7c28f0ff4ac3005a0aa379 100644
--- a/Cabal-syntax/src/Distribution/Utils/Structured.hs
+++ b/Cabal-syntax/src/Distribution/Utils/Structured.hs
@@ -110,7 +110,7 @@ import Data.Typeable (TypeRep, Typeable, typeRep)
 
 import Distribution.Utils.MD5
 
-import Data.Monoid (mconcat)
+import Data.Monoid (Last, mconcat)
 
 import qualified Data.Foldable
 import qualified Data.Semigroup
@@ -413,6 +413,7 @@ instance Structured Float where structure = nominalStructure
 instance Structured Double where structure = nominalStructure
 
 instance Structured a => Structured (Maybe a)
+instance Structured a => Structured (Last a)
 instance (Structured a, Structured b) => Structured (Either a b)
 instance Structured a => Structured (Ratio a) where structure = containerStructure
 instance Structured a => Structured [a] where structure = containerStructure
diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs
index f311fee9569fb4b96cdc51c9426010bd9d801ee0..e572eb1d4fc04e30f64bf0fe38c4e7692714addd 100644
--- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs
+++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs
@@ -33,4 +33,4 @@ md5CheckGenericPackageDescription proxy = md5Check proxy
 
 md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion
 md5CheckLocalBuildInfo proxy = md5Check proxy
-    0x906e7b142a02710d412d471a5656769b
+    0x364f8e404df9ada84ea3b4e3b3084a10
diff --git a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
index cb36fe680dbeb73e9a89ef0e94c354e0f843dcda..f7e7ca5b7b6a27df48d4b0f2aacac42fbd6f045b 100644
--- a/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
+++ b/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
@@ -17,7 +17,6 @@ import Distribution.InstalledPackageInfo           (AbiDependency, ExposedModule
 import Distribution.ModuleName                     (ModuleName)
 import Distribution.PackageDescription
 import Distribution.Simple.Compiler                (DebugInfoLevel, OptimisationLevel, ProfDetailLevel)
-import Distribution.Simple.Flag                    (Flag)
 import Distribution.Simple.InstallDirs
 import Distribution.Simple.InstallDirs.Internal
 import Distribution.Simple.Setup                   (HaddockTarget, TestShowDetails)
@@ -43,7 +42,6 @@ instance (Eq a, Show a) => ToExpr (Condition a) where toExpr = defaultExprViaSho
 instance (Show a, ToExpr b, ToExpr c, Show b, Show c, Eq a, Eq c, Eq b) => ToExpr (CondTree a b c)
 instance (Show a, ToExpr b, ToExpr c, Show b, Show c, Eq a, Eq c, Eq b) => ToExpr (CondBranch a b c)
 instance (ToExpr a) => ToExpr (NubList a)
-instance (ToExpr a) => ToExpr (Flag a)
 instance ToExpr a => ToExpr (NES.NonEmptySet a) where
     toExpr xs = App "NonEmptySet.fromNonEmpty" [toExpr $ NES.toNonEmpty xs]
 
diff --git a/Cabal/src/Distribution/Backpack/Id.hs b/Cabal/src/Distribution/Backpack/Id.hs
index 38e831acf1795a17c1938d452475123a193e35a3..b4333d73b9d3d85c1ec067d68848172a0c4e594e 100644
--- a/Cabal/src/Distribution/Backpack/Id.hs
+++ b/Cabal/src/Distribution/Backpack/Id.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 
 -- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
@@ -13,7 +14,7 @@ import Prelude ()
 
 import Distribution.PackageDescription
 import Distribution.Simple.Compiler
-import Distribution.Simple.Flag (Flag (..))
+import Distribution.Simple.Flag (Flag, pattern Flag, pattern NoFlag)
 import qualified Distribution.Simple.InstallDirs as InstallDirs
 import Distribution.Simple.LocalBuildInfo
 import Distribution.Types.ComponentId
diff --git a/Cabal/src/Distribution/Simple/Flag.hs b/Cabal/src/Distribution/Simple/Flag.hs
index 744a7da1331521c1d6d399a93fab2cc50fdda30f..341fd907e09f1b49efabbfd03aa957cda39b5972 100644
--- a/Cabal/src/Distribution/Simple/Flag.hs
+++ b/Cabal/src/Distribution/Simple/Flag.hs
@@ -1,6 +1,5 @@
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE DeriveTraversable #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 -----------------------------------------------------------------------------
 
@@ -19,7 +18,9 @@
 --
 -- Split off from "Distribution.Simple.Setup" to break import cycles.
 module Distribution.Simple.Flag
-  ( Flag (..)
+  ( Flag
+  , pattern Flag
+  , pattern NoFlag
   , allFlags
   , toFlag
   , fromFlag
@@ -32,6 +33,7 @@ module Distribution.Simple.Flag
   , BooleanFlag (..)
   ) where
 
+import Data.Monoid (Last (..))
 import Distribution.Compat.Prelude hiding (get)
 import Distribution.Compat.Stack
 import Prelude ()
@@ -61,43 +63,15 @@ import Prelude ()
 -- 'NoFlag' and later flags override earlier ones.
 --
 -- Isomorphic to 'Maybe' a.
-data Flag a = Flag a | NoFlag deriving (Eq, Generic, Show, Read, Foldable, Traversable)
-
-instance Binary a => Binary (Flag a)
-instance Structured a => Structured (Flag a)
-
-instance Functor Flag where
-  fmap f (Flag x) = Flag (f x)
-  fmap _ NoFlag = NoFlag
-
-instance Applicative Flag where
-  (Flag x) <*> y = x <$> y
-  NoFlag <*> _ = NoFlag
-  pure = Flag
-
-instance Monoid (Flag a) where
-  mempty = NoFlag
-  mappend = (<>)
-
-instance Semigroup (Flag a) where
-  _ <> f@(Flag _) = f
-  f <> NoFlag = f
-
-instance Bounded a => Bounded (Flag a) where
-  minBound = toFlag minBound
-  maxBound = toFlag maxBound
-
-instance Enum a => Enum (Flag a) where
-  fromEnum = fromEnum . fromFlag
-  toEnum = toFlag . toEnum
-  enumFrom (Flag a) = map toFlag . enumFrom $ a
-  enumFrom _ = []
-  enumFromThen (Flag a) (Flag b) = toFlag `map` enumFromThen a b
-  enumFromThen _ _ = []
-  enumFromTo (Flag a) (Flag b) = toFlag `map` enumFromTo a b
-  enumFromTo _ _ = []
-  enumFromThenTo (Flag a) (Flag b) (Flag c) = toFlag `map` enumFromThenTo a b c
-  enumFromThenTo _ _ _ = []
+type Flag = Last
+
+pattern Flag :: a -> Last a
+pattern Flag a = Last (Just a)
+
+pattern NoFlag :: Last a
+pattern NoFlag = Last Nothing
+
+{-# COMPLETE Flag, NoFlag #-}
 
 -- | Wraps a value in 'Flag'.
 toFlag :: a -> Flag a
@@ -110,26 +84,22 @@ fromFlag NoFlag = error "fromFlag NoFlag. Use fromFlagOrDefault"
 
 -- | Extracts a value from a 'Flag', and returns the default value on 'NoFlag'.
 fromFlagOrDefault :: a -> Flag a -> a
-fromFlagOrDefault _ (Flag x) = x
-fromFlagOrDefault def NoFlag = def
+fromFlagOrDefault def = fromMaybe def . getLast
 
 -- | Converts a 'Flag' value to a 'Maybe' value.
 flagToMaybe :: Flag a -> Maybe a
-flagToMaybe (Flag x) = Just x
-flagToMaybe NoFlag = Nothing
+flagToMaybe = getLast
 
 -- | Pushes a function through a 'Flag' value, and returns a default
 -- if the 'Flag' value is 'NoFlag'.
 --
 -- @since 3.4.0.0
 flagElim :: b -> (a -> b) -> Flag a -> b
-flagElim n _ NoFlag = n
-flagElim _ f (Flag x) = f x
+flagElim n f = maybe n f . getLast
 
 -- | Converts a 'Flag' value to a list.
 flagToList :: Flag a -> [a]
-flagToList (Flag x) = [x]
-flagToList NoFlag = []
+flagToList = maybeToList . getLast
 
 -- | Returns 'True' only if every 'Flag' 'Bool' value is Flag True, else 'False'.
 allFlags :: [Flag Bool] -> Flag Bool
@@ -140,8 +110,7 @@ allFlags flags =
 
 -- | Converts a 'Maybe' value to a 'Flag' value.
 maybeToFlag :: Maybe a -> Flag a
-maybeToFlag Nothing = NoFlag
-maybeToFlag (Just x) = Flag x
+maybeToFlag = Last
 
 -- | Merge the elements of a list 'Flag' with another list 'Flag'.
 mergeListFlag :: Flag [a] -> Flag [a] -> Flag [a]
diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs
index 18ab1a76ff92bd599efaa646f3fba50d0445e574..59ca82ba483697b3f45005fd50e594766fc01124 100644
--- a/Cabal/src/Distribution/Simple/GHC/Internal.hs
+++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 
 -----------------------------------------------------------------------------
@@ -67,7 +68,7 @@ import Distribution.Pretty (prettyShow)
 import Distribution.Simple.BuildPaths
 import Distribution.Simple.Compiler
 import Distribution.Simple.Errors
-import Distribution.Simple.Flag (Flag (NoFlag), maybeToFlag, toFlag)
+import Distribution.Simple.Flag (Flag, maybeToFlag, toFlag, pattern NoFlag)
 import Distribution.Simple.GHC.ImplInfo
 import Distribution.Simple.LocalBuildInfo
 import Distribution.Simple.Program
diff --git a/Cabal/src/Distribution/Simple/Setup.hs b/Cabal/src/Distribution/Simple/Setup.hs
index 65978d2ce33f4a2015988e71f9640a3dd56779a7..313aa35e1d0e6d1d80adf88f76b741f44ef48bf9 100644
--- a/Cabal/src/Distribution/Simple/Setup.hs
+++ b/Cabal/src/Distribution/Simple/Setup.hs
@@ -2,6 +2,7 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 
 -- |
@@ -118,7 +119,9 @@ module Distribution.Simple.Setup
   , splitArgs
   , defaultDistPref
   , optionDistPref
-  , Flag (..)
+  , Flag
+  , pattern Flag
+  , pattern NoFlag
   , toFlag
   , fromFlag
   , fromFlagOrDefault
diff --git a/Cabal/src/Distribution/Simple/Setup/Common.hs b/Cabal/src/Distribution/Simple/Setup/Common.hs
index 1a7e6691bab01554c1ea00a5698c41210eb0a30d..63c239131e8019227b606bddbde4402c2738dd37 100644
--- a/Cabal/src/Distribution/Simple/Setup/Common.hs
+++ b/Cabal/src/Distribution/Simple/Setup/Common.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 
 -- |
@@ -32,7 +33,9 @@ module Distribution.Simple.Setup.Common
   , defaultDistPref
   , extraCompilationArtifacts
   , optionDistPref
-  , Flag (..)
+  , Flag
+  , pattern Flag
+  , pattern NoFlag
   , toFlag
   , fromFlag
   , fromFlagOrDefault
diff --git a/cabal-install/src/Distribution/Client/CmdBuild.hs b/cabal-install/src/Distribution/Client/CmdBuild.hs
index 44f1c4e0f27cab984e1eed6b2d2fe2da4d1d5815..e668b16532035be2fd90fb79444ca544d4f9ca4d 100644
--- a/cabal-install/src/Distribution/Client/CmdBuild.hs
+++ b/cabal-install/src/Distribution/Client/CmdBuild.hs
@@ -50,7 +50,7 @@ import Distribution.Simple.Command
   , option
   , usageAlternatives
   )
-import Distribution.Simple.Flag (Flag (..), fromFlag, fromFlagOrDefault, toFlag)
+import Distribution.Simple.Flag (Flag, fromFlag, fromFlagOrDefault, toFlag)
 import Distribution.Simple.Utils
   ( dieWithException
   , wrapText
diff --git a/cabal-install/src/Distribution/Client/CmdClean.hs b/cabal-install/src/Distribution/Client/CmdClean.hs
index a738f38336a74732244e082a2e129da8090d1d24..322eeb61f7e57b2d41c23eb478d0d62aef01fc27 100644
--- a/cabal-install/src/Distribution/Client/CmdClean.hs
+++ b/cabal-install/src/Distribution/Client/CmdClean.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Distribution.Client.CmdClean (cleanCommand, cleanAction) where
@@ -38,13 +39,14 @@ import Distribution.Simple.Command
   , option
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , falseArg
   , flagToMaybe
   , fromFlagOrDefault
   , optionDistPref
   , optionVerbosity
   , toFlag
+  , pattern NoFlag
   )
 import Distribution.Simple.Utils
   ( dieWithException
diff --git a/cabal-install/src/Distribution/Client/CmdFreeze.hs b/cabal-install/src/Distribution/Client/CmdFreeze.hs
index 29718b5d441537c2b94b9cc7c8cae55a90b1bc84..b8d95f9c0ce63583de423c867812290f34084b90 100644
--- a/cabal-install/src/Distribution/Client/CmdFreeze.hs
+++ b/cabal-install/src/Distribution/Client/CmdFreeze.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 -- | cabal-install CLI command: freeze
@@ -53,7 +54,7 @@ import Distribution.PackageDescription
   ( FlagAssignment
   , nullFlagAssignment
   )
-import Distribution.Simple.Flag (Flag (..), fromFlagOrDefault)
+import Distribution.Simple.Flag (fromFlagOrDefault, pattern Flag)
 import Distribution.Simple.Utils
   ( dieWithException
   , notice
diff --git a/cabal-install/src/Distribution/Client/CmdHaddock.hs b/cabal-install/src/Distribution/Client/CmdHaddock.hs
index 677589e3e3556fbc1ab6ce7fefdf19ce9ff33047..70e9870a0792d7dada080dd535f63a27ac89d9fa 100644
--- a/cabal-install/src/Distribution/Client/CmdHaddock.hs
+++ b/cabal-install/src/Distribution/Client/CmdHaddock.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 -- | cabal-install CLI command: haddock
@@ -47,7 +48,7 @@ import Distribution.Simple.Command
   , option
   , usageAlternatives
   )
-import Distribution.Simple.Flag (Flag (..))
+import Distribution.Simple.Flag (Flag, pattern Flag)
 import Distribution.Simple.Program.Builtin
   ( haddockProgram
   )
diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs
index 0635a77d68ec452a4eb4e2efb7816b70f96d89ff..b2e59c33408d37e5b3979b0e508cd17ab541c7c3 100644
--- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs
+++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE PatternSynonyms #-}
+
 module Distribution.Client.CmdHaddockProject
   ( haddockProjectCommand
   , haddockProjectAction
@@ -64,9 +66,10 @@ import Distribution.Simple.Command
   ( CommandUI (..)
   )
 import Distribution.Simple.Flag
-  ( Flag (..)
-  , fromFlag
+  ( fromFlag
   , fromFlagOrDefault
+  , pattern Flag
+  , pattern NoFlag
   )
 import Distribution.Simple.Haddock (createHaddockIndex)
 import Distribution.Simple.InstallDirs
diff --git a/cabal-install/src/Distribution/Client/CmdInstall.hs b/cabal-install/src/Distribution/Client/CmdInstall.hs
index 63cf59169a36cb4f490731513a01d74db52fdf97..e08293dff7c717ec44a99636fd53e2592de740ef 100644
--- a/cabal-install/src/Distribution/Client/CmdInstall.hs
+++ b/cabal-install/src/Distribution/Client/CmdInstall.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections #-}
@@ -162,8 +163,10 @@ import Distribution.Simple.Program.Db
   , userSpecifyPaths
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , installDirsOptions
+  , pattern Flag
+  , pattern NoFlag
   )
 import Distribution.Simple.Utils
   ( createDirectoryIfMissingVerbose
diff --git a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs
index b35cd06fe7a41375c2efaa5d750645ab8258ff35..1be09c514a9095c4942c64600862423b9c161981 100644
--- a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs
+++ b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 module Distribution.Client.CmdInstall.ClientInstallFlags
   ( InstallMethod (..)
@@ -21,10 +22,11 @@ import Distribution.Simple.Command
   , reqArg
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , flagToList
   , toFlag
   , trueArg
+  , pattern Flag
   )
 
 import Distribution.Client.Types.InstallMethod
diff --git a/cabal-install/src/Distribution/Client/CmdOutdated.hs b/cabal-install/src/Distribution/Client/CmdOutdated.hs
index 028b5e922e5c58cc0b76763f52277db3c921ba21..f053c862c02338fba2a288feb432e3da41d7b87f 100644
--- a/cabal-install/src/Distribution/Client/CmdOutdated.hs
+++ b/cabal-install/src/Distribution/Client/CmdOutdated.hs
@@ -97,7 +97,7 @@ import Distribution.Simple.Compiler
   , compilerInfo
   )
 import Distribution.Simple.Flag
-  ( Flag (..)
+  ( Flag
   , flagToMaybe
   , fromFlagOrDefault
   , toFlag
diff --git a/cabal-install/src/Distribution/Client/CmdPath.hs b/cabal-install/src/Distribution/Client/CmdPath.hs
index d7587219665d62af64293bf91a2eab44abac141a..87058e03b6786e568477ce3c3d649bcdfafda140 100644
--- a/cabal-install/src/Distribution/Client/CmdPath.hs
+++ b/cabal-install/src/Distribution/Client/CmdPath.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 -- |
@@ -66,9 +67,11 @@ import Distribution.Simple.Command
   )
 import Distribution.Simple.Compiler
 import Distribution.Simple.Flag
-  ( Flag (..)
+  ( Flag
   , flagToList
   , fromFlagOrDefault
+  , pattern Flag
+  , pattern NoFlag
   )
 import Distribution.Simple.Program
 import Distribution.Simple.Utils
diff --git a/cabal-install/src/Distribution/Client/CmdRepl.hs b/cabal-install/src/Distribution/Client/CmdRepl.hs
index a75524bbca66b016c617687ad02f8a8ab0768958..ad02342e2a22e4fdf0e2187482dfdf1d5df0b4f8 100644
--- a/cabal-install/src/Distribution/Client/CmdRepl.hs
+++ b/cabal-install/src/Distribution/Client/CmdRepl.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE TypeApplications #-}
 
@@ -177,7 +178,7 @@ import Distribution.Client.ReplFlags
   , topReplOptions
   )
 import Distribution.Compat.Binary (decode)
-import Distribution.Simple.Flag (Flag (Flag), fromFlagOrDefault)
+import Distribution.Simple.Flag (fromFlagOrDefault, pattern Flag)
 import Distribution.Simple.Program.Builtin (ghcProgram)
 import Distribution.Simple.Program.Db (requireProgram)
 import Distribution.Simple.Program.Run
diff --git a/cabal-install/src/Distribution/Client/CmdSdist.hs b/cabal-install/src/Distribution/Client/CmdSdist.hs
index ab9e7712bc354fc44e1db97d35d2e71d9a605554..5dcc90a8bfb950aaa1bd38144d792374abfa5e0a 100644
--- a/cabal-install/src/Distribution/Client/CmdSdist.hs
+++ b/cabal-install/src/Distribution/Client/CmdSdist.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE MultiWayIf #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Distribution.Client.CmdSdist
@@ -97,7 +98,7 @@ import Distribution.Simple.PreProcess
   ( knownSuffixHandlers
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , flagToList
   , flagToMaybe
   , fromFlagOrDefault
@@ -105,6 +106,7 @@ import Distribution.Simple.Setup
   , optionVerbosity
   , toFlag
   , trueArg
+  , pattern Flag
   )
 import Distribution.Simple.SrcDist
   ( listPackageSourcesWithDie
diff --git a/cabal-install/src/Distribution/Client/CmdTest.hs b/cabal-install/src/Distribution/Client/CmdTest.hs
index 3812bd6af87c8a596338b9073931d9c046bb3001..c839a00c44deb15351926068c3d437d9176c3e77 100644
--- a/cabal-install/src/Distribution/Client/CmdTest.hs
+++ b/cabal-install/src/Distribution/Client/CmdTest.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 -- | cabal-install CLI command: test
@@ -48,7 +49,8 @@ import Distribution.Simple.Command
   , usageAlternatives
   )
 import Distribution.Simple.Flag
-  ( Flag (..)
+  ( Flag
+  , pattern Flag
   )
 import Distribution.Simple.Setup
   ( TestFlags (..)
diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs
index 419d7d603ea6338a1968188eaf1033af74cc97ec..9254b2fae9b1bf38ab120a27bd4fe836effe881c 100644
--- a/cabal-install/src/Distribution/Client/Config.hs
+++ b/cabal-install/src/Distribution/Client/Config.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 -----------------------------------------------------------------------------
 
@@ -181,7 +182,7 @@ import Distribution.Simple.Setup
   ( BenchmarkFlags (..)
   , CommonSetupFlags (..)
   , ConfigFlags (..)
-  , Flag (..)
+  , Flag
   , HaddockFlags (..)
   , TestFlags (..)
   , configureOptions
@@ -197,6 +198,8 @@ import Distribution.Simple.Setup
   , programDbOptions
   , programDbPaths'
   , toFlag
+  , pattern Flag
+  , pattern NoFlag
   )
 import Distribution.Simple.Utils
   ( cabalVersion
diff --git a/cabal-install/src/Distribution/Client/Get.hs b/cabal-install/src/Distribution/Client/Get.hs
index 39ace2f26520271c6f0b9afa3525d97f633bc6be..328e93e9c9ed81e640efd1010b6c5001b900ed0a 100644
--- a/cabal-install/src/Distribution/Client/Get.hs
+++ b/cabal-install/src/Distribution/Client/Get.hs
@@ -1,6 +1,4 @@
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
+{-# LANGUAGE PatternSynonyms #-}
 
 -- |
 -- Module      :  Distribution.Client.Get
@@ -39,10 +37,10 @@ import Distribution.Simple.Program
   ( programName
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
-  , flagToMaybe
+  ( flagToMaybe
   , fromFlag
   , fromFlagOrDefault
+  , pattern NoFlag
   )
 import Distribution.Simple.Utils
   ( dieWithException
diff --git a/cabal-install/src/Distribution/Client/GlobalFlags.hs b/cabal-install/src/Distribution/Client/GlobalFlags.hs
index 2fd19e71b50aafb7432278d5d7f6c97d3ee09e52..a1aef03a8ee673e64d1fd65e42c6c7e673bef945 100644
--- a/cabal-install/src/Distribution/Client/GlobalFlags.hs
+++ b/cabal-install/src/Distribution/Client/GlobalFlags.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
@@ -28,9 +29,10 @@ import Distribution.Client.Types
   , unRepoName
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , flagToMaybe
   , fromFlag
+  , pattern Flag
   )
 import Distribution.Simple.Utils
   ( info
diff --git a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs
index 9e1ed191f94b93cf3ad82ee9f3042b5682659b3b..e7fb8a3e3c9f5323608967fad2f1c1be8baa09ee 100644
--- a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs
+++ b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 module Distribution.Client.Init.FlagExtractors
   ( -- * Flag extractors
@@ -51,7 +52,7 @@ import Distribution.Client.Init.Types
 import Distribution.FieldGrammar.Newtypes (SpecLicense)
 import Distribution.ModuleName (ModuleName)
 import Distribution.Simple.Flag (flagElim)
-import Distribution.Simple.Setup (Flag (..), flagToMaybe, fromFlagOrDefault)
+import Distribution.Simple.Setup (Flag, flagToMaybe, fromFlagOrDefault, pattern Flag, pattern NoFlag)
 import Distribution.Types.Dependency (Dependency (..))
 import Distribution.Types.PackageName (PackageName)
 import Distribution.Version (Version)
diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs
index 82064d8fbc1529803ed286bec2980a5b3d0008d7..e01590df1fc019c7fad1f62cf4388f1c296814d5 100644
--- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs
+++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 -----------------------------------------------------------------------------
 
@@ -58,7 +59,7 @@ import Distribution.Client.Types (SourcePackageDb (..))
 import Distribution.FieldGrammar.Newtypes (SpecLicense (..))
 import qualified Distribution.SPDX as SPDX
 import Distribution.Simple.PackageIndex (InstalledPackageIndex)
-import Distribution.Simple.Setup (Flag (..), fromFlagOrDefault)
+import Distribution.Simple.Setup (fromFlagOrDefault, pattern Flag, pattern NoFlag)
 import Distribution.Solver.Types.PackageIndex (elemByPackageName)
 import Distribution.Types.PackageName (PackageName, unPackageName)
 import Distribution.Version (Version)
diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs
index f4b953814546187f7c36ab269e68786692b0a014..80ceefac6f80c58da696d5f3489b87ad227e4598 100644
--- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs
+++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE PatternSynonyms #-}
+
 module Distribution.Client.Init.NonInteractive.Command
   ( genPkgDescription
   , genLibTarget
@@ -49,7 +51,7 @@ import Distribution.Client.Init.Utils
 import Distribution.Client.Types (SourcePackageDb (..))
 import Distribution.ModuleName (ModuleName, components)
 import Distribution.Simple.PackageIndex (InstalledPackageIndex)
-import Distribution.Simple.Setup (Flag (..), fromFlagOrDefault)
+import Distribution.Simple.Setup (fromFlagOrDefault, pattern Flag, pattern NoFlag)
 import Distribution.Solver.Types.PackageIndex (elemByPackageName)
 import Distribution.Types.Dependency (Dependency (..))
 import Distribution.Types.PackageName (PackageName, unPackageName)
diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs
index 4d413085547f6d4eda29b9e0b0425374d88541df..c7762a1bd648196d1dc879b91be75df6770fe377 100644
--- a/cabal-install/src/Distribution/Client/Init/Simple.hs
+++ b/cabal-install/src/Distribution/Client/Init/Simple.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE PatternSynonyms #-}
+
 module Distribution.Client.Init.Simple
   ( -- * Project creation
     createProject
@@ -16,7 +18,7 @@ import Distribution.Client.Init.FlagExtractors
 import Distribution.Client.Init.Types
 import Distribution.Client.Init.Utils (currentDirPkgName, fixupDocFiles, mkPackageNameDep)
 import Distribution.Client.Types.SourcePackageDb (SourcePackageDb (..))
-import Distribution.Simple.Flag (Flag (..), flagElim, fromFlagOrDefault)
+import Distribution.Simple.Flag (flagElim, fromFlagOrDefault, pattern Flag, pattern NoFlag)
 import Distribution.Simple.PackageIndex
 import Distribution.Types.Dependency
 import Distribution.Types.PackageName (unPackageName)
diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs
index 8da7ba2b52bfcbacea76adacba53f6d4e12d8729..f72634248a06d451e5f74c08c8a6ae83783a8710 100644
--- a/cabal-install/src/Distribution/Client/Init/Types.hs
+++ b/cabal-install/src/Distribution/Client/Init/Types.hs
@@ -80,7 +80,7 @@ import Distribution.Client.Utils as P
 import Distribution.Fields.Pretty
 import Distribution.ModuleName
 import qualified Distribution.Package as P
-import Distribution.Simple.Setup (Flag (..))
+import Distribution.Simple.Setup (Flag)
 import Distribution.Verbosity (silent)
 import Distribution.Version
 import Language.Haskell.Extension (Extension, Language (..))
diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs
index 527dd7a109cbe35ba609f0dc20e10e4ec5588dbf..d55ac85a947b0b5e834ed0b80b60662fa5e3621b 100644
--- a/cabal-install/src/Distribution/Client/Init/Utils.hs
+++ b/cabal-install/src/Distribution/Client/Init/Utils.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Distribution.Client.Init.Utils
@@ -42,7 +43,7 @@ import Distribution.InstalledPackageInfo (InstalledPackageInfo, exposed)
 import Distribution.ModuleName (ModuleName)
 import qualified Distribution.Package as P
 import Distribution.Simple.PackageIndex (InstalledPackageIndex, moduleNameIndex)
-import Distribution.Simple.Setup (Flag (..))
+import Distribution.Simple.Setup (pattern Flag, pattern NoFlag)
 import Distribution.Types.Dependency (Dependency, mkDependency)
 import Distribution.Types.LibraryName
 import Distribution.Types.PackageName
diff --git a/cabal-install/src/Distribution/Client/Main.hs b/cabal-install/src/Distribution/Client/Main.hs
index 39caec854cdb71b1c33f66adce9a090ffc07061c..1a8d945611aab1e4da80785afd651b0eeb9f098f 100644
--- a/cabal-install/src/Distribution/Client/Main.hs
+++ b/cabal-install/src/Distribution/Client/Main.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 -- |
@@ -74,7 +75,7 @@ import Distribution.Simple.Setup
   ( BenchmarkFlags (..)
   , CleanFlags (..)
   , CopyFlags (..)
-  , Flag (..)
+  , Flag
   , HaddockFlags (..)
   , HaddockTarget (..)
   , HscolourFlags (..)
@@ -87,6 +88,8 @@ import Distribution.Simple.Setup
   , fromFlagOrDefault
   , hscolourCommand
   , toFlag
+  , pattern Flag
+  , pattern NoFlag
   )
 
 import Distribution.Client.Compat.Prelude hiding (get)
diff --git a/cabal-install/src/Distribution/Client/ManpageFlags.hs b/cabal-install/src/Distribution/Client/ManpageFlags.hs
index 59221252a17bcea858b92f595d37e50cfcd76661..c45a6d59f074e2f79e889b000c14f567c4aa4022 100644
--- a/cabal-install/src/Distribution/Client/ManpageFlags.hs
+++ b/cabal-install/src/Distribution/Client/ManpageFlags.hs
@@ -9,7 +9,7 @@ module Distribution.Client.ManpageFlags
 import Distribution.Client.Compat.Prelude
 
 import Distribution.Simple.Command (OptionField (..), ShowOrParseArgs (..), option)
-import Distribution.Simple.Setup (Flag (..), optionVerbosity, toFlag, trueArg)
+import Distribution.Simple.Setup (Flag, optionVerbosity, toFlag, trueArg)
 import Distribution.Verbosity (normal)
 
 data ManpageFlags = ManpageFlags
diff --git a/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal-install/src/Distribution/Client/ProjectConfig.hs
index b9f2cfed6c6956c60e9549b75f476c108c7ac5be..5d2c3981c0e07d05be1c3b7f42e921430fedbd4b 100644
--- a/cabal-install/src/Distribution/Client/ProjectConfig.hs
+++ b/cabal-install/src/Distribution/Client/ProjectConfig.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE TypeApplications #-}
 
@@ -177,12 +178,13 @@ import Distribution.Simple.Program
   ( ConfiguredProgram (..)
   )
 import Distribution.Simple.Setup
-  ( Flag (Flag)
+  ( Flag
   , flagToList
   , flagToMaybe
   , fromFlag
   , fromFlagOrDefault
   , toFlag
+  , pattern Flag
   )
 import Distribution.System
   ( Platform
diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
index 10858d5601d656773580223ab6e11956057ec5c9..2e24a493d0e51524e4d428707c6bb40abcbd7d4a 100644
--- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
+++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections #-}
@@ -109,7 +110,7 @@ import Distribution.Simple.Setup
   , CommonSetupFlags (..)
   , ConfigFlags (..)
   , DumpBuildInfo (DumpBuildInfo, NoDumpBuildInfo)
-  , Flag (..)
+  , Flag
   , HaddockFlags (..)
   , TestFlags (..)
   , benchmarkOptions'
@@ -126,6 +127,8 @@ import Distribution.Simple.Setup
   , splitArgs
   , testOptions'
   , toFlag
+  , pattern Flag
+  , pattern NoFlag
   )
 import Distribution.Simple.Utils
   ( debug
diff --git a/cabal-install/src/Distribution/Client/ProjectFlags.hs b/cabal-install/src/Distribution/Client/ProjectFlags.hs
index a18814a034b1d1bd5392da5e5bb62b280218b1ee..29b964bb99bc2cfc7d8840ee8ffc5f2b089bc8de 100644
--- a/cabal-install/src/Distribution/Client/ProjectFlags.hs
+++ b/cabal-install/src/Distribution/Client/ProjectFlags.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 module Distribution.Client.ProjectFlags
   ( ProjectFlags (..)
@@ -20,7 +21,15 @@ import Distribution.Simple.Command
   , option
   , reqArg
   )
-import Distribution.Simple.Setup (Flag (..), flagToList, flagToMaybe, toFlag, trueArg)
+import Distribution.Simple.Setup
+  ( Flag
+  , flagToList
+  , flagToMaybe
+  , toFlag
+  , trueArg
+  , pattern Flag
+  , pattern NoFlag
+  )
 
 data ProjectFlags = ProjectFlags
   { flagProjectDir :: Flag FilePath
diff --git a/cabal-install/src/Distribution/Client/ReplFlags.hs b/cabal-install/src/Distribution/Client/ReplFlags.hs
index 0d587b1d5014a1da33c306ebfdda606156f5b598..c2e741663e34705940035f5f014eb3b1cd20e022 100644
--- a/cabal-install/src/Distribution/Client/ReplFlags.hs
+++ b/cabal-install/src/Distribution/Client/ReplFlags.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE PatternSynonyms #-}
+
 module Distribution.Client.ReplFlags (EnvFlags (..), ReplFlags (..), topReplOptions, multiReplOption, defaultReplFlags) where
 
 import Distribution.Client.Compat.Prelude
@@ -21,12 +23,13 @@ import Distribution.Simple.Command
   , reqArg
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , ReplOptions (..)
   , boolOpt
   , falseArg
   , replOptions
   , toFlag
+  , pattern NoFlag
   )
 import Distribution.Types.Dependency
   ( Dependency (..)
diff --git a/cabal-install/src/Distribution/Client/Sandbox.hs b/cabal-install/src/Distribution/Client/Sandbox.hs
index 732856a3d8faa8052a4adb792af582cedc32ee79..68d72a6def151fae547f75982757593edb36bbd5 100644
--- a/cabal-install/src/Distribution/Client/Sandbox.hs
+++ b/cabal-install/src/Distribution/Client/Sandbox.hs
@@ -48,7 +48,7 @@ import Distribution.Simple.Configure
 import qualified Distribution.Simple.LocalBuildInfo as LocalBuildInfo
 import Distribution.Simple.Program (ProgramDb)
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( Flag
   , flagToMaybe
   , fromFlagOrDefault
   )
diff --git a/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs b/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs
index 57e45ddb2ba5b78985dd8b62443d39168ddf5edd..3ccb0862ea2b7a4224c7499d046d91d090f2d39e 100644
--- a/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs
+++ b/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs
@@ -55,7 +55,7 @@ import Distribution.Deprecated.ParseUtils
 import Distribution.Simple.InstallDirs (InstallDirs (..), PathTemplate)
 import Distribution.Simple.Setup
   ( ConfigFlags (..)
-  , Flag (..)
+  , Flag
   , HaddockFlags (..)
   )
 import Distribution.Simple.Utils (debug, warn)
diff --git a/cabal-install/src/Distribution/Client/ScriptUtils.hs b/cabal-install/src/Distribution/Client/ScriptUtils.hs
index 440de3c84ad5e8713a1efa27d7ae5315f905a5d5..5068323e87fa16492ff252234471a92c5644fecc 100644
--- a/cabal-install/src/Distribution/Client/ScriptUtils.hs
+++ b/cabal-install/src/Distribution/Client/ScriptUtils.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RecordWildCards #-}
 
 -- | Utilities to help commands with scripts
@@ -126,7 +127,7 @@ import Distribution.Simple.PackageDescription
   ( parseString
   )
 import Distribution.Simple.Setup
-  ( Flag (..)
+  ( pattern Flag
   )
 import Distribution.Simple.Utils
   ( createDirectoryIfMissingVerbose
diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs
index 78fcf7c2e1f0096cdccaa7dec01c99e3472c791c..81f2d69ff0aa0a00a2e4d7d5e9538adb1896ee21 100644
--- a/cabal-install/src/Distribution/Client/Setup.hs
+++ b/cabal-install/src/Distribution/Client/Setup.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
@@ -169,7 +170,7 @@ import Distribution.Simple.Configure
   , interpretPackageDbFlags
   )
 import Distribution.Simple.Flag
-  ( Flag (..)
+  ( Flag
   , flagElim
   , flagToList
   , flagToMaybe
@@ -177,6 +178,8 @@ import Distribution.Simple.Flag
   , maybeToFlag
   , mergeListFlag
   , toFlag
+  , pattern Flag
+  , pattern NoFlag
   )
 import Distribution.Simple.InstallDirs
   ( InstallDirs (..)
diff --git a/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal-install/src/Distribution/Client/SetupWrapper.hs
index 78833af6d1510a6bf791e29d76251d828e8fcebc..e68be61cea79921093ec6488200a1afe491c1da9 100644
--- a/cabal-install/src/Distribution/Client/SetupWrapper.hs
+++ b/cabal-install/src/Distribution/Client/SetupWrapper.hs
@@ -2,6 +2,7 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
 {- FOURMOLU_DISABLE -}
 
 -----------------------------------------------------------------------------
@@ -144,7 +145,7 @@ import Distribution.Simple.Program.GHC
   )
 import Distribution.Simple.Setup
   ( CommonSetupFlags (..)
-  , Flag (..)
+  , pattern Flag
   , GlobalFlags (..)
   , globalCommand
   )
diff --git a/cabal-install/src/Distribution/Client/Utils.hs b/cabal-install/src/Distribution/Client/Utils.hs
index b1ad7bd9a37f7ecb5214c83f5357b9fa499b311a..f4a1fb67a51698fa1eccc0893fbc4e1683ef3361 100644
--- a/cabal-install/src/Distribution/Client/Utils.hs
+++ b/cabal-install/src/Distribution/Client/Utils.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module Distribution.Client.Utils
@@ -69,7 +70,7 @@ import Data.List
 import Distribution.Client.Errors
 import Distribution.Compat.Environment
 import Distribution.Compat.Time (getModTime)
-import Distribution.Simple.Setup (Flag (..))
+import Distribution.Simple.Setup (Flag, pattern Flag, pattern NoFlag)
 import Distribution.Simple.Utils (dieWithException, findPackageDesc, noticeNoWrap)
 import Distribution.Utils.Path
   ( CWD
diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs
index ac0c9c57739a512685543aef7fd5e2da76ba4e70..3cbb9d15b670973b67a55686d438e9c0e41d02d7 100644
--- a/cabal-install/tests/IntegrationTests2.hs
+++ b/cabal-install/tests/IntegrationTests2.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 -- For the handy instance IsString PackageIdentifier
@@ -99,7 +100,7 @@ import System.IO.Silently
 
 import qualified Data.ByteString as BS
 import Data.Maybe (fromJust)
-import Distribution.Simple.Flag (Flag (Flag, NoFlag))
+import Distribution.Simple.Flag (Flag, pattern Flag, pattern NoFlag)
 import Distribution.Types.ParStrat
 
 main :: IO ()
diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs b/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
index 17d098b23b805680af6dafbd5ef79503a3f40e8c..c8843761e69cc2c5a3971c4dc3ce09a048573b2a 100644
--- a/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
+++ b/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
@@ -25,6 +25,7 @@ import Prelude ()
 
 import Data.Char (isLetter)
 import Data.List ((\\))
+import Data.Monoid (Last (..))
 
 import Distribution.Simple.Setup
 import Distribution.Types.Flag (mkFlagAssignment)
@@ -199,7 +200,7 @@ instance Arbitrary WriteGhcEnvironmentFilesPolicy where
   arbitrary = arbitraryBoundedEnum
 
 arbitraryFlag :: Gen a -> Gen (Flag a)
-arbitraryFlag = liftArbitrary
+arbitraryFlag = fmap (fmap Last) liftArbitrary
 
 instance Arbitrary RepoName where
   -- TODO: rename refinement?
diff --git a/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs
index a9cb90c64f1b6ea393b68637b03238dd0256fcb3..1eda271f98e6b1fb0eb6b4540837789a56850edd 100644
--- a/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs
+++ b/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE PatternSynonyms #-}
+
 module UnitTests.Distribution.Client.UserConfig
   ( tests
   ) where
@@ -18,7 +20,7 @@ import Test.Tasty.HUnit
 import Distribution.Client.Config
 import Distribution.Client.Setup (GlobalFlags (..), InstallFlags (..))
 import Distribution.Client.Utils (removeExistingFile)
-import Distribution.Simple.Setup (ConfigFlags (..), Flag (..), fromFlag)
+import Distribution.Simple.Setup (ConfigFlags (..), fromFlag, pattern Flag)
 import Distribution.Simple.Utils (withTempDirectory)
 import Distribution.Utils.NubList (fromNubList)
 import Distribution.Verbosity (silent)
diff --git a/cabal-testsuite/src/Test/Cabal/Script.hs b/cabal-testsuite/src/Test/Cabal/Script.hs
index a478d5008afa0b44c41eeae2acb41a7893377246..3aa3d5acc949204d0d66a3d6af8a1aceef3dfe2f 100644
--- a/cabal-testsuite/src/Test/Cabal/Script.hs
+++ b/cabal-testsuite/src/Test/Cabal/Script.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 
 -- | Functionality for invoking Haskell scripts with the correct
@@ -25,7 +26,7 @@ import Distribution.Simple.Program
 import Distribution.Simple.Compiler
 import Distribution.Verbosity
 import Distribution.System
-import Distribution.Simple.Setup (Flag(..))
+import Distribution.Simple.Setup (pattern Flag)
 
 import qualified Data.Monoid as M
 
diff --git a/changelog.d/pr-10948.md b/changelog.d/pr-10948.md
new file mode 100644
index 0000000000000000000000000000000000000000..83757e5f47ef9bd0669d0a8e9004d04035f8b145
--- /dev/null
+++ b/changelog.d/pr-10948.md
@@ -0,0 +1,18 @@
+synopsis: Make `Flag a` a type synonym for `Last (Maybe a)`
+packages: Cabal cabal-install
+prs: #10948
+
+description: {
+
+- Replace `data Flag a = Flag a | NoFlag` with `type Flag = Data.Monoid.Last`
+  and provide `pattern Flag a = Last (Just a)` and `pattern NoFlag = Last Nothing`
+  for backward compatibility.
+- The change aims to be non-breaking for the majority of clients, although
+  imports of form `import Distribution.Simple.Flag (Flag (..))` should be replaced
+  with `import Distribution.Simple.Flag (Flag, pattern Flag, pattern NoFlag)`
+  (the latter form is backwards compatible with older versions of Cabal).
+  Enable language extension `PatternSynonyms` if required. In the unlikely case
+  of defining instances for `Flag`, `TypeSynonymInstances` extension
+  is needed.
+
+}
diff --git a/release-notes/WIP-Cabal-3.16.x.0.md b/release-notes/WIP-Cabal-3.16.x.0.md
new file mode 100644
index 0000000000000000000000000000000000000000..1c208dbcf4d9f334532ea8af71566638a8378c97
--- /dev/null
+++ b/release-notes/WIP-Cabal-3.16.x.0.md
@@ -0,0 +1,18 @@
+Cabal 3.16.x.0 changelog and release notes.
+
+This file will be edited and the changes incorporated into the official
+3.16.x.0 Cabal and Cabal-syntax release notes.
+
+---
+
+### Migration guide
+
+- `data Flag a = Flag a | NoFlag` has been replaced with `type Flag = Data.Monoid.Last`,
+  while `pattern Flag a = Last (Just a)` and `pattern NoFlag = Last Nothing` are provided
+  for backward compatibility.
+  Imports of form `import Distribution.Simple.Flag (Flag (..))` should be replaced
+  with `import Distribution.Simple.Flag (Flag, pattern Flag, pattern NoFlag)`
+  (the latter form is backwards compatible with older versions of Cabal).
+  Enable `{-# LANGUAGE PatternSynonyms #-}` if required. In the unlikely case
+  of defining instances for `Flag`, `{-# LANGUAGE TypeSynonymInstances #-}`
+  is needed.