Use top-level instances to solve superclasses where possible
[ghc.git] / compiler / main / DynFlags.hs
index f078c51..682480b 100644 (file)
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 -------------------------------------------------------------------------------
 --
@@ -20,16 +21,17 @@ module DynFlags (
         -- * Dynamic flags and associated configuration types
         DumpFlag(..),
         GeneralFlag(..),
-        WarningFlag(..),
-        ExtensionFlag(..),
+        WarningFlag(..), WarnReason(..),
         Language(..),
         PlatformConstants(..),
         FatalMessager, LogAction, FlushOut(..), FlushErr(..),
         ProfAuto(..),
         glasgowExtsFlags,
+        warningGroups, warningHierarchies,
         dopt, dopt_set, dopt_unset,
-        gopt, gopt_set, gopt_unset,
+        gopt, gopt_set, gopt_unset, setGeneralFlag', unSetGeneralFlag',
         wopt, wopt_set, wopt_unset,
+        wopt_fatal,
         xopt, xopt_set, xopt_unset,
         lang_set,
         useUnicodeSyntax,
@@ -39,23 +41,28 @@ module DynFlags (
         DynFlags(..),
         FlagSpec(..),
         HasDynFlags(..), ContainsDynFlags(..),
+        OverridingBool(..), overrideWith,
         RtsOptsEnabled(..),
         HscTarget(..), isObjectTarget, defaultObjectTarget,
         targetRetainsAllBindings,
         GhcMode(..), isOneShot,
         GhcLink(..), isNoLink,
         PackageFlag(..), PackageArg(..), ModRenaming(..),
+        IgnorePackageFlag(..), TrustFlag(..),
         PkgConfRef(..),
         Option(..), showOpt,
         DynLibLoader(..),
-        fFlags, fWarningFlags, fLangFlags, xFlags,
+        fFlags, fLangFlags, xFlags,
+        wWarningFlags,
         dynFlagDependencies,
         tablesNextToCode, mkTablesNextToCode,
-        SigOf, getSigOf,
+        makeDynFlagsConsistent,
 
         Way(..), mkBuildTag, wayRTSOnly, addWay', updateWays,
         wayGeneralFlags, wayUnsetGeneralFlags,
 
+        thisPackage, thisComponentId, thisUnitIdInsts,
+
         -- ** Safe Haskell
         SafeHaskellMode(..),
         safeHaskellOn, safeImportsOn, safeLanguageOn, safeInferOn,
@@ -70,8 +77,8 @@ module DynFlags (
         versionedAppDir,
         extraGccViaCFlags, systemPackageConfig,
         pgm_L, pgm_P, pgm_F, pgm_c, pgm_s, pgm_a, pgm_l, pgm_dll, pgm_T,
-        pgm_sysman, pgm_windres, pgm_libtool, pgm_lo, pgm_lc,
-        opt_L, opt_P, opt_F, opt_c, opt_a, opt_l,
+        pgm_windres, pgm_libtool, pgm_lo, pgm_lc, pgm_i,
+        opt_L, opt_P, opt_F, opt_c, opt_a, opt_l, opt_i,
         opt_windres, opt_lo, opt_lc,
 
 
@@ -79,6 +86,7 @@ module DynFlags (
         defaultDynFlags,                -- Settings -> DynFlags
         defaultWays,
         interpWays,
+        interpreterProfiled, interpreterDynamic,
         initDynFlags,                   -- DynFlags -> IO DynFlags
         defaultFatalMessager,
         defaultLogAction,
@@ -91,8 +99,9 @@ module DynFlags (
         getVerbFlags,
         updOptLevel,
         setTmpDir,
-        setPackageKey,
+        setUnitId,
         interpretPackageEnv,
+        canonicalizeHomeModule,
 
         -- ** Parsing DynFlags
         parseDynamicFlagsCmdLine,
@@ -100,7 +109,7 @@ module DynFlags (
         parseDynamicFlagsFull,
 
         -- ** Available DynFlags
-        allFlags,
+        allNonDeprecatedFlags,
         flagsAll,
         flagsDynamic,
         flagsPackage,
@@ -112,19 +121,13 @@ module DynFlags (
         -- ** DynFlags C compiler options
         picCCOpts, picPOpts,
 
-        -- * Configuration of the stg-to-stg passes
-        StgToDo(..),
-        getStgToDo,
-
         -- * Compiler configuration suitable for display to the user
         compilerInfo,
 
-#ifdef GHCI
         rtsIsProfiled,
-#endif
         dynamicGhc,
 
-#include "../includes/dist-derivedconstants/header/GHCConstantsHaskellExports.hs"
+#include "GHCConstantsHaskellExports.hs"
         bLOCK_SIZE_W,
         wORD_SIZE_IN_BITS,
         tAG_MASK,
@@ -171,18 +174,24 @@ import SrcLoc
 import BasicTypes       ( IntWithInf, treatZeroAsInf )
 import FastString
 import Outputable
-#ifdef GHCI
 import Foreign.C        ( CInt(..) )
 import System.IO.Unsafe ( unsafeDupablePerformIO )
-#endif
-import {-# SOURCE #-} ErrUtils ( Severity(..), MsgDoc, mkLocMessage )
+import {-# SOURCE #-} ErrUtils ( Severity(..), MsgDoc, mkLocMessageAnn
+                               , getCaretDiagnostic, dumpSDoc )
+import Json
+import SysTools.Terminal ( stderrSupportsAnsiColors )
 
 import System.IO.Unsafe ( unsafePerformIO )
 import Data.IORef
 import Control.Arrow ((&&&))
 import Control.Monad
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.Writer
+import Control.Monad.Trans.Reader
+import Control.Monad.Trans.Except
 import Control.Exception (throwIO)
 
+import Data.Ord
 import Data.Bits
 import Data.Char
 import Data.Int
@@ -204,6 +213,9 @@ import Data.IntSet (IntSet)
 import qualified Data.IntSet as IntSet
 
 import GHC.Foreign (withCString, peekCString)
+import qualified GHC.LanguageExtensions as LangExt
+
+import Foreign (Ptr) -- needed for 2nd stage
 
 -- Note [Updating flag description in the User's Guide]
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,10 +224,10 @@ import GHC.Foreign (withCString, peekCString)
 -- described in the User's Guide. Usually at least two sections need to be
 -- updated:
 --
---  * Flag Reference section in docs/users-guide/flags.xml lists all available
---    flags together with a short description
+--  * Flag Reference section generated from the modules in
+--    utils/mkUserGuidePart/Options
 --
---  * Flag description in docs/users_guide/using.xml provides a detailed
+--  * Flag description in docs/users_guide/using.rst provides a detailed
 --    explanation of flags' usage.
 
 -- Note [Supporting CLI completion]
@@ -230,6 +242,59 @@ import GHC.Foreign (withCString, peekCString)
 -- have effect, and annotate it accordingly. For Flags use defFlag, defGhcFlag,
 -- defGhciFlag, and for FlagSpec use flagSpec or flagGhciSpec.
 
+-- Note [Adding a language extension]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- There are a few steps to adding (or removing) a language extension,
+--
+--  * Adding the extension to GHC.LanguageExtensions
+--
+--    The Extension type in libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs
+--    is the canonical list of language extensions known by GHC.
+--
+--  * Adding a flag to DynFlags.xFlags
+--
+--    This is fairly self-explanatory. The name should be concise, memorable,
+--    and consistent with any previous implementations of the similar idea in
+--    other Haskell compilers.
+--
+--  * Adding the flag to the documentation
+--
+--    This is the same as any other flag. See
+--    Note [Updating flag description in the User's Guide]
+--
+--  * Adding the flag to Cabal
+--
+--    The Cabal library has its own list of all language extensions supported
+--    by all major compilers. This is the list that user code being uploaded
+--    to Hackage is checked against to ensure language extension validity.
+--    Consequently, it is very important that this list remains up-to-date.
+--
+--    To this end, there is a testsuite test (testsuite/tests/driver/T4437.hs)
+--    whose job it is to ensure these GHC's extensions are consistent with
+--    Cabal.
+--
+--    The recommended workflow is,
+--
+--     1. Temporarily add your new language extension to the
+--        expectedGhcOnlyExtensions list in T4437 to ensure the test doesn't
+--        break while Cabal is updated.
+--
+--     2. After your GHC change is accepted, submit a Cabal pull request adding
+--        your new extension to Cabal's list (found in
+--        Cabal/Language/Haskell/Extension.hs).
+--
+--     3. After your Cabal change is accepted, let the GHC developers know so
+--        they can update the Cabal submodule and remove the extensions from
+--        expectedGhcOnlyExtensions.
+--
+--  * Adding the flag to the GHC Wiki
+--
+--    There is a change log tracking language extension additions and removals
+--    on the GHC wiki:  https://ghc.haskell.org/trac/ghc/wiki/LanguagePragmaHistory
+--
+--  See Trac #4437 and #8176.
+
 -- -----------------------------------------------------------------------------
 -- DynFlags
 
@@ -238,15 +303,19 @@ data DumpFlag
 
    -- debugging flags
    = Opt_D_dump_cmm
+   | Opt_D_dump_cmm_from_stg
    | Opt_D_dump_cmm_raw
-   -- All of the cmm subflags (there are a lot!)  Automatically
-   -- enabled if you run -ddump-cmm
+   | Opt_D_dump_cmm_verbose
+   -- All of the cmm subflags (there are a lot!) automatically
+   -- enabled if you run -ddump-cmm-verbose
+   -- Each flag corresponds to exact stage of Cmm pipeline.
    | Opt_D_dump_cmm_cfg
    | Opt_D_dump_cmm_cbe
    | Opt_D_dump_cmm_switch
    | Opt_D_dump_cmm_proc
-   | Opt_D_dump_cmm_sink
    | Opt_D_dump_cmm_sp
+   | Opt_D_dump_cmm_sink
+   | Opt_D_dump_cmm_caf
    | Opt_D_dump_cmm_procmap
    | Opt_D_dump_cmm_split
    | Opt_D_dump_cmm_info
@@ -271,7 +340,9 @@ data DumpFlag
    | Opt_D_dump_simpl_trace
    | Opt_D_dump_occur_anal
    | Opt_D_dump_parsed
+   | Opt_D_dump_parsed_ast
    | Opt_D_dump_rn
+   | Opt_D_dump_shape
    | Opt_D_dump_simpl
    | Opt_D_dump_simpl_iterations
    | Opt_D_dump_spec
@@ -279,7 +350,7 @@ data DumpFlag
    | Opt_D_dump_stg
    | Opt_D_dump_call_arity
    | Opt_D_dump_stranal
-   | Opt_D_dump_strsigs
+   | Opt_D_dump_str_signatures
    | Opt_D_dump_tc
    | Opt_D_dump_types
    | Opt_D_dump_rules
@@ -291,6 +362,7 @@ data DumpFlag
    | Opt_D_dump_simpl_stats
    | Opt_D_dump_cs_trace -- Constraint solver in type checker
    | Opt_D_dump_tc_trace
+   | Opt_D_dump_ec_trace -- Pattern match exhaustiveness checker
    | Opt_D_dump_if_trace
    | Opt_D_dump_vt_trace
    | Opt_D_dump_splices
@@ -308,6 +380,7 @@ data DumpFlag
    | Opt_D_dump_view_pattern_commoning
    | Opt_D_verbose_core2core
    | Opt_D_dump_debug
+   | Opt_D_dump_json
 
    deriving (Eq, Show, Enum)
 
@@ -326,10 +399,18 @@ data GeneralFlag
    | Opt_NoLlvmMangler                 -- hidden flag
 
    | Opt_WarnIsError                    -- -Werror; makes warnings fatal
+   | Opt_ShowWarnGroups                 -- Show the group a warning belongs to
+   | Opt_HideSourcePaths                -- Hide module source/object paths
 
    | Opt_PrintExplicitForalls
    | Opt_PrintExplicitKinds
+   | Opt_PrintExplicitCoercions
+   | Opt_PrintExplicitRuntimeReps
+   | Opt_PrintEqualityRelations
    | Opt_PrintUnicodeSyntax
+   | Opt_PrintExpandedSynonyms
+   | Opt_PrintPotentialInstances
+   | Opt_PrintTypecheckerElaboration
 
    -- optimisation opts
    | Opt_CallArity
@@ -341,14 +422,17 @@ data GeneralFlag
    | Opt_FloatIn
    | Opt_Specialise
    | Opt_SpecialiseAggressively
+   | Opt_CrossModuleSpecialise
    | Opt_StaticArgumentTransformation
    | Opt_CSE
+   | Opt_StgCSE
    | Opt_LiberateCase
    | Opt_SpecConstr
    | Opt_DoLambdaEtaExpansion
    | Opt_IgnoreAsserts
    | Opt_DoEtaReduction
    | Opt_CaseMerge
+   | Opt_CaseFolding                    -- Constant folding through case-expressions
    | Opt_UnboxStrictFields
    | Opt_UnboxSmallStrictFields
    | Opt_DictsCheap
@@ -360,15 +444,18 @@ data GeneralFlag
    | Opt_PedanticBottoms                -- Be picky about how we treat bottom
    | Opt_LlvmTBAA                       -- Use LLVM TBAA infastructure for improving AA (hidden flag)
    | Opt_LlvmPassVectorsInRegisters     -- Pass SIMD vectors in registers (requires a patched LLVM) (hidden flag)
+   | Opt_LlvmFillUndefWithGarbage       -- Testing for undef bugs (hidden flag)
    | Opt_IrrefutableTuples
    | Opt_CmmSink
    | Opt_CmmElimCommonBlocks
    | Opt_OmitYields
-   | Opt_SimpleListLiterals
    | Opt_FunToThunk               -- allow WwLib.mkWorkerArgs to remove all value lambdas
    | Opt_DictsStrict                     -- be strict in argument dictionaries
    | Opt_DmdTxDictSel              -- use a special demand transformer for dictionary selectors
    | Opt_Loopification                  -- See Note [Self-recursive tail calls]
+   | Opt_CprAnal
+   | Opt_WorkerWrapper
+   | Opt_SolveConstantDicts
 
    -- Interface files
    | Opt_IgnoreInterfacePragmas
@@ -387,8 +474,10 @@ data GeneralFlag
    | Opt_EagerBlackHoling
    | Opt_NoHsMain
    | Opt_SplitObjs
+   | Opt_SplitSections
    | Opt_StgStats
    | Opt_HideAllPackages
+   | Opt_HideAllPluginPackages
    | Opt_PrintBindResult
    | Opt_Haddock
    | Opt_HaddockOptions
@@ -403,21 +492,24 @@ data GeneralFlag
    | Opt_IgnoreDotGhci
    | Opt_GhciSandbox
    | Opt_GhciHistory
+   | Opt_LocalGhciHistory
    | Opt_HelpfulErrors
    | Opt_DeferTypeErrors
    | Opt_DeferTypedHoles
-   | Opt_Parallel
+   | Opt_DeferOutOfScopeVariables
    | Opt_PIC
    | Opt_SccProfilingOn
    | Opt_Ticky
    | Opt_Ticky_Allocd
    | Opt_Ticky_LNE
    | Opt_Ticky_Dyn_Thunk
-   | Opt_Static
    | Opt_RPath
    | Opt_RelativeDynlibPaths
    | Opt_Hpc
    | Opt_FlatCache
+   | Opt_ExternalInterpreter
+   | Opt_OptimalApplicativeDo
+   | Opt_VersionMacros
 
    -- PreInlining is on by default. The option is there just to see how
    -- bad things get if you turn it off!
@@ -426,8 +518,10 @@ data GeneralFlag
    -- output style opts
    | Opt_ErrorSpans -- Include full span info in error messages,
                     -- instead of just the start position.
+   | Opt_DiagnosticsShowCaret -- Show snippets of offending code
    | Opt_PprCaseAsLet
    | Opt_PprShowTicks
+   | Opt_ShowHoleConstraints
 
    -- Suppress all coercions, them replacing with '...'
    | Opt_SuppressCoercions
@@ -440,6 +534,8 @@ data GeneralFlag
    | Opt_SuppressIdInfo
    -- Suppress separate type signatures in core, but leave types on
    -- lambda bound vars
+   | Opt_SuppressUnfoldings
+   -- Suppress the details of even stable unfoldings
    | Opt_SuppressTypeSignatures
    -- Suppress unique ids on variables.
    -- Except for uniques, as some simplifier phases introduce new
@@ -457,17 +553,28 @@ data GeneralFlag
    | Opt_KeepTmpFiles
    | Opt_KeepRawTokenStream
    | Opt_KeepLlvmFiles
+   | Opt_KeepHiFiles
+   | Opt_KeepOFiles
 
    | Opt_BuildDynamicToo
 
    -- safe haskell flags
    | Opt_DistrustAllPackages
    | Opt_PackageTrust
+   deriving (Eq, Show, Enum)
 
-   -- debugging flags
-   | Opt_Debug
+-- | Used when outputting warnings: if a reason is given, it is
+-- displayed. If a warning isn't controlled by a flag, this is made
+-- explicit at the point of use.
+data WarnReason = NoReason | Reason !WarningFlag
+  deriving Show
 
-   deriving (Eq, Show, Enum)
+instance Outputable WarnReason where
+  ppr = text . show
+
+instance ToJson WarnReason where
+  json NoReason = JSNull
+  json (Reason wf) = JSString (show wf)
 
 data WarningFlag =
 -- See Note [Updating flag description in the User's Guide]
@@ -484,8 +591,8 @@ data WarningFlag =
    | Opt_WarnMissingFields
    | Opt_WarnMissingImportList
    | Opt_WarnMissingMethods
-   | Opt_WarnMissingSigs
-   | Opt_WarnMissingLocalSigs
+   | Opt_WarnMissingSignatures
+   | Opt_WarnMissingLocalSignatures
    | Opt_WarnNameShadowing
    | Opt_WarnOverlappingPatterns
    | Opt_WarnTypeDefaults
@@ -495,10 +602,13 @@ data WarningFlag =
    | Opt_WarnUnusedPatternBinds
    | Opt_WarnUnusedImports
    | Opt_WarnUnusedMatches
-   | Opt_WarnContextQuantification
+   | Opt_WarnUnusedTypePatterns
+   | Opt_WarnUnusedForalls
    | Opt_WarnWarningsDeprecations
    | Opt_WarnDeprecatedFlags
-   | Opt_WarnAMP
+   | Opt_WarnAMP -- Introduced in GHC 7.8, obsolete since 7.10
+   | Opt_WarnMissingMonadFailInstances -- since 8.0
+   | Opt_WarnSemigroup -- since 8.0
    | Opt_WarnDodgyExports
    | Opt_WarnDodgyImports
    | Opt_WarnOrphans
@@ -513,19 +623,34 @@ data WarningFlag =
    | Opt_WarnUnsafe
    | Opt_WarnSafe
    | Opt_WarnTrustworthySafe
-   | Opt_WarnPointlessPragmas
+   | Opt_WarnMissedSpecs
+   | Opt_WarnAllMissedSpecs
    | Opt_WarnUnsupportedCallingConventions
    | Opt_WarnUnsupportedLlvmVersion
    | Opt_WarnInlineRuleShadowing
    | Opt_WarnTypedHoles
    | Opt_WarnPartialTypeSignatures
-   | Opt_WarnMissingExportedSigs
+   | Opt_WarnMissingExportedSignatures
    | Opt_WarnUntickedPromotedConstructors
    | Opt_WarnDerivingTypeable
+   | Opt_WarnDeferredTypeErrors
+   | Opt_WarnDeferredOutOfScopeVariables
+   | Opt_WarnNonCanonicalMonadInstances   -- since 8.0
+   | Opt_WarnNonCanonicalMonadFailInstances -- since 8.0
+   | Opt_WarnNonCanonicalMonoidInstances  -- since 8.0
+   | Opt_WarnMissingPatternSynonymSignatures -- since 8.0
+   | Opt_WarnUnrecognisedWarningFlags     -- since 8.0
+   | Opt_WarnSimplifiableClassConstraints -- Since 8.2
+   | Opt_WarnCPPUndef                     -- Since 8.2
+   | Opt_WarnUnbangedStrictPatterns       -- Since 8.2
+   | Opt_WarnMissingHomeModules           -- Since 8.2
    deriving (Eq, Show, Enum)
 
 data Language = Haskell98 | Haskell2010
-   deriving Enum
+   deriving (Eq, Enum, Show)
+
+instance Outputable Language where
+    ppr = text . show
 
 -- | The various Safe Haskell modes
 data SafeHaskellMode
@@ -544,111 +669,6 @@ instance Show SafeHaskellMode where
 instance Outputable SafeHaskellMode where
     ppr = text . show
 
-data ExtensionFlag
--- See Note [Updating flag description in the User's Guide]
-   = Opt_Cpp
-   | Opt_OverlappingInstances
-   | Opt_UndecidableInstances
-   | Opt_IncoherentInstances
-   | Opt_MonomorphismRestriction
-   | Opt_MonoPatBinds
-   | Opt_MonoLocalBinds
-   | Opt_RelaxedPolyRec           -- Deprecated
-   | Opt_ExtendedDefaultRules     -- Use GHC's extended rules for defaulting
-   | Opt_ForeignFunctionInterface
-   | Opt_UnliftedFFITypes
-   | Opt_InterruptibleFFI
-   | Opt_CApiFFI
-   | Opt_GHCForeignImportPrim
-   | Opt_JavaScriptFFI
-   | Opt_ParallelArrays           -- Syntactic support for parallel arrays
-   | Opt_Arrows                   -- Arrow-notation syntax
-   | Opt_TemplateHaskell
-   | Opt_QuasiQuotes
-   | Opt_ImplicitParams
-   | Opt_ImplicitPrelude
-   | Opt_ScopedTypeVariables
-   | Opt_AllowAmbiguousTypes
-   | Opt_UnboxedTuples
-   | Opt_BangPatterns
-   | Opt_TypeFamilies
-   | Opt_OverloadedStrings
-   | Opt_OverloadedLists
-   | Opt_NumDecimals
-   | Opt_DisambiguateRecordFields
-   | Opt_RecordWildCards
-   | Opt_RecordPuns
-   | Opt_ViewPatterns
-   | Opt_GADTs
-   | Opt_GADTSyntax
-   | Opt_NPlusKPatterns
-   | Opt_DoAndIfThenElse
-   | Opt_RebindableSyntax
-   | Opt_ConstraintKinds
-   | Opt_PolyKinds                -- Kind polymorphism
-   | Opt_DataKinds                -- Datatype promotion
-   | Opt_InstanceSigs
-
-   | Opt_StandaloneDeriving
-   | Opt_DeriveDataTypeable
-   | Opt_AutoDeriveTypeable       -- Automatic derivation of Typeable
-   | Opt_DeriveFunctor
-   | Opt_DeriveTraversable
-   | Opt_DeriveFoldable
-   | Opt_DeriveGeneric            -- Allow deriving Generic/1
-   | Opt_DefaultSignatures        -- Allow extra signatures for defmeths
-   | Opt_DeriveAnyClass           -- Allow deriving any class
-
-   | Opt_TypeSynonymInstances
-   | Opt_FlexibleContexts
-   | Opt_FlexibleInstances
-   | Opt_ConstrainedClassMethods
-   | Opt_MultiParamTypeClasses
-   | Opt_NullaryTypeClasses
-   | Opt_FunctionalDependencies
-   | Opt_UnicodeSyntax
-   | Opt_ExistentialQuantification
-   | Opt_MagicHash
-   | Opt_EmptyDataDecls
-   | Opt_KindSignatures
-   | Opt_RoleAnnotations
-   | Opt_ParallelListComp
-   | Opt_TransformListComp
-   | Opt_MonadComprehensions
-   | Opt_GeneralizedNewtypeDeriving
-   | Opt_RecursiveDo
-   | Opt_PostfixOperators
-   | Opt_TupleSections
-   | Opt_PatternGuards
-   | Opt_LiberalTypeSynonyms
-   | Opt_RankNTypes
-   | Opt_ImpredicativeTypes
-   | Opt_TypeOperators
-   | Opt_ExplicitNamespaces
-   | Opt_PackageImports
-   | Opt_ExplicitForAll
-   | Opt_AlternativeLayoutRule
-   | Opt_AlternativeLayoutRuleTransitional
-   | Opt_DatatypeContexts
-   | Opt_NondecreasingIndentation
-   | Opt_RelaxedLayout
-   | Opt_TraditionalRecordSyntax
-   | Opt_LambdaCase
-   | Opt_MultiWayIf
-   | Opt_BinaryLiterals
-   | Opt_NegativeLiterals
-   | Opt_EmptyCase
-   | Opt_PatternSynonyms
-   | Opt_PartialTypeSignatures
-   | Opt_NamedWildCards
-   | Opt_StaticPointers
-   deriving (Eq, Enum, Show)
-
-type SigOf = Map ModuleName Module
-
-getSigOf :: DynFlags -> ModuleName -> Maybe Module
-getSigOf dflags n = Map.lookup n (sigOf dflags)
-
 -- | Contains not only a collection of 'GeneralFlag's but also a plethora of
 -- information relating to the compilation of a single file or GHC session
 data DynFlags = DynFlags {
@@ -656,12 +676,12 @@ data DynFlags = DynFlags {
   ghcLink               :: GhcLink,
   hscTarget             :: HscTarget,
   settings              :: Settings,
-  -- See Note [Signature parameters in TcGblEnv and DynFlags]
-  sigOf                 :: SigOf,       -- ^ Compiling an hs-boot against impl.
   verbosity             :: Int,         -- ^ Verbosity level: see Note [Verbosity levels]
   optLevel              :: Int,         -- ^ Optimisation level
+  debugLevel            :: Int,         -- ^ How much debug information to produce
   simplPhases           :: Int,         -- ^ Number of simplifier phases
   maxSimplIterations    :: Int,         -- ^ Max simplifier iterations
+  maxPmCheckIterations  :: Int,         -- ^ Max no iterations for pm checking
   ruleCheck             :: Maybe String,
   strictnessBefore      :: [Int],       -- ^ Additional demand analysis
 
@@ -674,6 +694,8 @@ data DynFlags = DynFlags {
 
   maxRelevantBinds      :: Maybe Int,   -- ^ Maximum number of bindings from the type envt
                                         --   to show in type error messages
+  maxUncoveredPatterns  :: Int,         -- ^ Maximum number of unmatched patterns to show
+                                        --   in non-exhaustiveness warnings
   simplTickFactor       :: Int,         -- ^ Multiplier for simplifier ticks
   specConstrThreshold   :: Maybe Int,   -- ^ Threshold for SpecConstr
   specConstrCount       :: Maybe Int,   -- ^ Max number of specialisations for any one function
@@ -683,15 +705,18 @@ data DynFlags = DynFlags {
   floatLamArgs          :: Maybe Int,   -- ^ Arg count for lambda floating
                                         --   See CoreMonad.FloatOutSwitches
 
-  historySize           :: Int,
+  historySize           :: Int,         -- ^ Simplification history size
 
-  cmdlineHcIncludes     :: [String],    -- ^ @\-\#includes@
   importPaths           :: [FilePath],
   mainModIs             :: Module,
   mainFunIs             :: Maybe String,
   reductionDepth        :: IntWithInf,   -- ^ Typechecker maximum stack depth
+  solverIterations      :: IntWithInf,   -- ^ Number of iterations in the constraints solver
+                                         --   Typically only 1 is needed
 
-  thisPackage           :: PackageKey,   -- ^ name of package currently being compiled
+  thisInstalledUnitId   :: InstalledUnitId,
+  thisComponentId_      :: Maybe ComponentId,
+  thisUnitIdInsts_      :: Maybe [(ModuleName, Module)],
 
   -- ways
   ways                  :: [Way],       -- ^ Way flags from the command line
@@ -746,12 +771,14 @@ data DynFlags = DynFlags {
 
   rtsOpts               :: Maybe String,
   rtsOptsEnabled        :: RtsOptsEnabled,
+  rtsOptsSuggestions    :: Bool,
 
   hpcDir                :: String,      -- ^ Path to store the .mix files
 
   -- Plugins
   pluginModNames        :: [ModuleName],
   pluginModNameOpts     :: [(ModuleName,String)],
+  frontendPluginOpts    :: [String],
 
   -- GHC API hooks
   hooks                 :: Hooks,
@@ -767,15 +794,21 @@ data DynFlags = DynFlags {
         -- ^ The @-package-db@ flags given on the command line, in the order
         -- they appeared.
 
+  ignorePackageFlags    :: [IgnorePackageFlag],
+        -- ^ The @-ignore-package@ flags from the command line
   packageFlags          :: [PackageFlag],
         -- ^ The @-package@ and @-hide-package@ flags from the command-line
+  pluginPackageFlags    :: [PackageFlag],
+        -- ^ The @-plugin-package-id@ flags from command line
+  trustFlags            :: [TrustFlag],
+        -- ^ The @-trust@ and @-distrust@ flags
   packageEnv            :: Maybe FilePath,
         -- ^ Filepath to the package environment file (if overriding default)
 
   -- Package state
   -- NB. do not modify this field, it is calculated by
   -- Packages.initPackages
-  pkgDatabase           :: Maybe [PackageConfig],
+  pkgDatabase           :: Maybe [(FilePath, [PackageConfig])],
   pkgState              :: PackageState,
 
   -- Temporary files
@@ -796,6 +829,7 @@ data DynFlags = DynFlags {
   dumpFlags             :: IntSet,
   generalFlags          :: IntSet,
   warningFlags          :: IntSet,
+  fatalWarningFlags     :: IntSet,
   -- Don't change this without updating extensionFlags:
   language              :: Maybe Language,
   -- | Safe Haskell mode
@@ -814,9 +848,11 @@ data DynFlags = DynFlags {
   warnUnsafeOnLoc       :: SrcSpan,
   trustworthyOnLoc      :: SrcSpan,
   -- Don't change this without updating extensionFlags:
-  extensions            :: [OnOff ExtensionFlag],
+  extensions            :: [OnOff LangExt.Extension],
   -- extensionFlags should always be equal to
   --     flattenExtensionFlags language extensions
+  -- LangExt.Extension is defined in libraries/ghc-boot so that it can be used
+  -- by template-haskell
   extensionFlags        :: IntSet,
 
   -- Unfolding control
@@ -833,30 +869,33 @@ data DynFlags = DynFlags {
   ghciHistSize          :: Int,
 
   -- | MsgDoc output action: use "ErrUtils" instead of this if you can
+  initLogAction         :: IO (Maybe LogOutput),
   log_action            :: LogAction,
+  log_finaliser         :: LogFinaliser,
   flushOut              :: FlushOut,
   flushErr              :: FlushErr,
 
   haddockOptions        :: Maybe String,
+
+  -- | GHCi scripts specified by -ghci-script, in reverse order
   ghciScripts           :: [String],
 
   -- Output style options
   pprUserLength         :: Int,
   pprCols               :: Int,
-  traceLevel            :: Int, -- Standard level is 1. Less verbose is 0.
 
-  useUnicode      :: Bool,
+  useUnicode            :: Bool,
+  useColor              :: OverridingBool,
+  canUseColor           :: Bool,
 
   -- | what kind of {-# SCC #-} to add automatically
   profAuto              :: ProfAuto,
 
   interactivePrint      :: Maybe String,
 
-  llvmVersion           :: IORef Int,
-
   nextWrapperNum        :: IORef (ModuleEnv Int),
 
-  -- | Machine dependant flags (-m<blah> stuff)
+  -- | Machine dependent flags (-m<blah> stuff)
   sseVersion            :: Maybe SseVersion,
   avx                   :: Bool,
   avx2                  :: Bool,
@@ -882,15 +921,42 @@ data DynFlags = DynFlags {
 
   -- | Only inline memset if it generates no more than this many
   -- pseudo (roughly: Cmm) instructions.
-  maxInlineMemsetInsns  :: Int
+  maxInlineMemsetInsns  :: Int,
+
+  -- | Reverse the order of error messages in GHC/GHCi
+  reverseErrors :: Bool,
+
+  -- | Unique supply configuration for testing build determinism
+  initialUnique         :: Int,
+  uniqueIncrement       :: Int
 }
 
 class HasDynFlags m where
     getDynFlags :: m DynFlags
 
+{- It would be desirable to have the more generalised
+
+  instance (MonadTrans t, Monad m, HasDynFlags m) => HasDynFlags (t m) where
+      getDynFlags = lift getDynFlags
+
+instance definition. However, that definition would overlap with the
+`HasDynFlags (GhcT m)` instance. Instead we define instances for a
+couple of common Monad transformers explicitly. -}
+
+instance (Monoid a, Monad m, HasDynFlags m) => HasDynFlags (WriterT a m) where
+    getDynFlags = lift getDynFlags
+
+instance (Monad m, HasDynFlags m) => HasDynFlags (ReaderT a m) where
+    getDynFlags = lift getDynFlags
+
+instance (Monad m, HasDynFlags m) => HasDynFlags (MaybeT m) where
+    getDynFlags = lift getDynFlags
+
+instance (Monad m, HasDynFlags m) => HasDynFlags (ExceptT e m) where
+    getDynFlags = lift getDynFlags
+
 class ContainsDynFlags t where
     extractDynFlags :: t -> DynFlags
-    replaceDynFlags :: t -> DynFlags -> t
 
 data ProfAuto
   = NoProfAuto         -- ^ no SCC annotations added
@@ -917,6 +983,7 @@ data Settings = Settings {
   sLdSupportsBuildId       :: Bool,
   sLdSupportsFilelist      :: Bool,
   sLdIsGnuLd               :: Bool,
+  sGccSupportsNoPie        :: Bool,
   -- commands for particular phases
   sPgm_L                 :: String,
   sPgm_P                 :: (String,[Option]),
@@ -927,11 +994,11 @@ data Settings = Settings {
   sPgm_l                 :: (String,[Option]),
   sPgm_dll               :: (String,[Option]),
   sPgm_T                 :: String,
-  sPgm_sysman            :: String,
   sPgm_windres           :: String,
   sPgm_libtool           :: String,
   sPgm_lo                :: (String,[Option]), -- LLVM: opt llvm optimiser
   sPgm_lc                :: (String,[Option]), -- LLVM: llc static compiler
+  sPgm_i                 :: String,
   -- options for particular phases
   sOpt_L                 :: [String],
   sOpt_P                 :: [String],
@@ -942,6 +1009,7 @@ data Settings = Settings {
   sOpt_windres           :: [String],
   sOpt_lo                :: [String], -- LLVM: llvm optimiser
   sOpt_lc                :: [String], -- LLVM: llc static compiler
+  sOpt_i                 :: [String], -- iserv options
 
   sPlatformConstants     :: PlatformConstants
  }
@@ -984,8 +1052,6 @@ pgm_dll               :: DynFlags -> (String,[Option])
 pgm_dll dflags = sPgm_dll (settings dflags)
 pgm_T                 :: DynFlags -> String
 pgm_T dflags = sPgm_T (settings dflags)
-pgm_sysman            :: DynFlags -> String
-pgm_sysman dflags = sPgm_sysman (settings dflags)
 pgm_windres           :: DynFlags -> String
 pgm_windres dflags = sPgm_windres (settings dflags)
 pgm_libtool           :: DynFlags -> String
@@ -994,6 +1060,8 @@ pgm_lo                :: DynFlags -> (String,[Option])
 pgm_lo dflags = sPgm_lo (settings dflags)
 pgm_lc                :: DynFlags -> (String,[Option])
 pgm_lc dflags = sPgm_lc (settings dflags)
+pgm_i                 :: DynFlags -> String
+pgm_i dflags = sPgm_i (settings dflags)
 opt_L                 :: DynFlags -> [String]
 opt_L dflags = sOpt_L (settings dflags)
 opt_P                 :: DynFlags -> [String]
@@ -1015,14 +1083,27 @@ opt_lo                :: DynFlags -> [String]
 opt_lo dflags = sOpt_lo (settings dflags)
 opt_lc                :: DynFlags -> [String]
 opt_lc dflags = sOpt_lc (settings dflags)
+opt_i                 :: DynFlags -> [String]
+opt_i dflags = sOpt_i (settings dflags)
 
 -- | The directory for this version of ghc in the user's app directory
 -- (typically something like @~/.ghc/x86_64-linux-7.6.3@)
 --
-versionedAppDir :: DynFlags -> IO FilePath
+versionedAppDir :: DynFlags -> MaybeT IO FilePath
 versionedAppDir dflags = do
-  appdir <- getAppUserDataDirectory (programName dflags)
-  return $ appdir </> (TARGET_ARCH ++ '-':TARGET_OS ++ '-':projectVersion dflags)
+  -- Make sure we handle the case the HOME isn't set (see #11678)
+  appdir <- tryMaybeT $ getAppUserDataDirectory (programName dflags)
+  return $ appdir </> versionedFilePath dflags
+
+-- | A filepath like @x86_64-linux-7.6.3@ with the platform string to use when
+-- constructing platform-version-dependent files that need to co-exist.
+--
+versionedFilePath :: DynFlags -> FilePath
+versionedFilePath dflags =     TARGET_ARCH
+                        ++ '-':TARGET_OS
+                        ++ '-':projectVersion dflags
+  -- NB: This functionality is reimplemented in Cabal, so if you
+  -- change it, be sure to update Cabal.
 
 -- | The target code type of the compilation (if any).
 --
@@ -1078,9 +1159,9 @@ data GhcMode
   deriving Eq
 
 instance Outputable GhcMode where
-  ppr CompManager = ptext (sLit "CompManager")
-  ppr OneShot     = ptext (sLit "OneShot")
-  ppr MkDepend    = ptext (sLit "MkDepend")
+  ppr CompManager = text "CompManager"
+  ppr OneShot     = text "OneShot"
+  ppr MkDepend    = text "MkDepend"
 
 isOneShot :: GhcMode -> Bool
 isOneShot OneShot = True
@@ -1105,9 +1186,11 @@ isNoLink _      = False
 -- is used.
 data PackageArg =
       PackageArg String    -- ^ @-package@, by 'PackageName'
-    | PackageIdArg String  -- ^ @-package-id@, by 'SourcePackageId'
-    | PackageKeyArg String -- ^ @-package-key@, by 'InstalledPackageId'
+    | UnitIdArg UnitId     -- ^ @-package-id@, by 'UnitId'
   deriving (Eq, Show)
+instance Outputable PackageArg where
+    ppr (PackageArg pn) = text "package" <+> text pn
+    ppr (UnitIdArg uid) = text "unit" <+> ppr uid
 
 -- | Represents the renaming that may be associated with an exposed
 -- package, e.g. the @rns@ part of @-package "foo (rns)"@.
@@ -1125,16 +1208,30 @@ data ModRenaming = ModRenaming {
     modRenamings :: [(ModuleName, ModuleName)] -- ^ Bring module @m@ into scope
                                                --   under name @n@.
   } deriving (Eq)
+instance Outputable ModRenaming where
+    ppr (ModRenaming b rns) = ppr b <+> parens (ppr rns)
+
+-- | Flags for manipulating the set of non-broken packages.
+newtype IgnorePackageFlag = IgnorePackage String -- ^ @-ignore-package@
+  deriving (Eq)
+
+-- | Flags for manipulating package trust.
+data TrustFlag
+  = TrustPackage    String -- ^ @-trust@
+  | DistrustPackage String -- ^ @-distrust@
+  deriving (Eq)
 
--- | Flags for manipulating packages.
+-- | Flags for manipulating packages visibility.
 data PackageFlag
-  = ExposePackage   PackageArg ModRenaming -- ^ @-package@, @-package-id@
-                                           -- and @-package-key@
+  = ExposePackage   String PackageArg ModRenaming -- ^ @-package@, @-package-id@
   | HidePackage     String -- ^ @-hide-package@
-  | IgnorePackage   String -- ^ @-ignore-package@
-  | TrustPackage    String -- ^ @-trust-package@
-  | DistrustPackage String -- ^ @-distrust-package@
   deriving (Eq)
+-- NB: equality instance is used by InteractiveUI to test if
+-- package flags have changed.
+
+instance Outputable PackageFlag where
+    ppr (ExposePackage n arg rn) = text n <> braces (ppr arg <+> ppr rn)
+    ppr (HidePackage str) = text "-hide-package" <+> text str
 
 defaultHscTarget :: Platform -> HscTarget
 defaultHscTarget = defaultObjectTarget
@@ -1167,6 +1264,17 @@ data DynLibLoader
 data RtsOptsEnabled = RtsOptsNone | RtsOptsSafeOnly | RtsOptsAll
   deriving (Show)
 
+data OverridingBool
+  = Auto
+  | Always
+  | Never
+  deriving Show
+
+overrideWith :: Bool -> OverridingBool -> Bool
+overrideWith b Auto   = b
+overrideWith _ Always = True
+overrideWith _ Never  = False
+
 -----------------------------------------------------------------------------
 -- Ways
 
@@ -1189,7 +1297,6 @@ data Way
   | WayDebug
   | WayProf
   | WayEventLog
-  | WayPar
   | WayDyn
   deriving (Eq, Ord, Show)
 
@@ -1212,6 +1319,7 @@ allowed_combination way = and [ x `allowedWith` y
         (WayCustom {}) `allowedWith` _          = True
         WayThreaded `allowedWith` WayProf       = True
         WayThreaded `allowedWith` WayEventLog   = True
+        WayProf     `allowedWith` WayEventLog   = True
         _ `allowedWith` _                       = False
 
 mkBuildTag :: [Way] -> String
@@ -1224,7 +1332,6 @@ wayTag WayDebug    = "debug"
 wayTag WayDyn      = "dyn"
 wayTag WayProf     = "p"
 wayTag WayEventLog = "l"
-wayTag WayPar      = "mp"
 
 wayRTSOnly :: Way -> Bool
 wayRTSOnly (WayCustom {}) = False
@@ -1233,7 +1340,6 @@ wayRTSOnly WayDebug    = True
 wayRTSOnly WayDyn      = False
 wayRTSOnly WayProf     = False
 wayRTSOnly WayEventLog = True
-wayRTSOnly WayPar      = False
 
 wayDesc :: Way -> String
 wayDesc (WayCustom xs) = xs
@@ -1242,7 +1348,6 @@ wayDesc WayDebug    = "Debug"
 wayDesc WayDyn      = "Dynamic"
 wayDesc WayProf     = "Profiling"
 wayDesc WayEventLog = "RTS Event Logging"
-wayDesc WayPar      = "Parallel"
 
 -- Turn these flags on when enabling this way
 wayGeneralFlags :: Platform -> Way -> [GeneralFlag]
@@ -1259,7 +1364,6 @@ wayGeneralFlags _ WayDyn      = [Opt_PIC]
     -- modules of the main program with -fPIC when using -dynamic.
 wayGeneralFlags _ WayProf     = [Opt_SccProfilingOn]
 wayGeneralFlags _ WayEventLog = []
-wayGeneralFlags _ WayPar      = [Opt_Parallel]
 
 -- Turn these flags off when enabling this way
 wayUnsetGeneralFlags :: Platform -> Way -> [GeneralFlag]
@@ -1270,19 +1374,12 @@ wayUnsetGeneralFlags _ WayDyn      = [-- There's no point splitting objects
                                       -- when we're going to be dynamically
                                       -- linking. Plus it breaks compilation
                                       -- on OSX x86.
-                                      Opt_SplitObjs]
+                                      Opt_SplitObjs,
+                                      -- If splitobjs wasn't useful for this,
+                                      -- assume sections aren't either.
+                                      Opt_SplitSections]
 wayUnsetGeneralFlags _ WayProf     = []
 wayUnsetGeneralFlags _ WayEventLog = []
-wayUnsetGeneralFlags _ WayPar      = []
-
-wayExtras :: Platform -> Way -> DynFlags -> DynFlags
-wayExtras _ (WayCustom {}) dflags = dflags
-wayExtras _ WayThreaded dflags = dflags
-wayExtras _ WayDebug    dflags = dflags
-wayExtras _ WayDyn      dflags = dflags
-wayExtras _ WayProf     dflags = dflags
-wayExtras _ WayEventLog dflags = dflags
-wayExtras _ WayPar      dflags = exposePackage' "concurrent" dflags
 
 wayOptc :: Platform -> Way -> [String]
 wayOptc _ (WayCustom {}) = []
@@ -1294,7 +1391,6 @@ wayOptc _ WayDebug      = []
 wayOptc _ WayDyn        = []
 wayOptc _ WayProf       = ["-DPROFILING"]
 wayOptc _ WayEventLog   = ["-DTRACING"]
-wayOptc _ WayPar        = ["-DPAR", "-w"]
 
 wayOptl :: Platform -> Way -> [String]
 wayOptl _ (WayCustom {}) = []
@@ -1312,9 +1408,6 @@ wayOptl _ WayDebug      = []
 wayOptl _ WayDyn        = []
 wayOptl _ WayProf       = []
 wayOptl _ WayEventLog   = []
-wayOptl _ WayPar        = ["-L${PVM_ROOT}/lib/${PVM_ARCH}",
-                           "-lpvm3",
-                           "-lgpvm3"]
 
 wayOptP :: Platform -> Way -> [String]
 wayOptP _ (WayCustom {}) = []
@@ -1323,7 +1416,6 @@ wayOptP _ WayDebug    = []
 wayOptP _ WayDyn      = []
 wayOptP _ WayProf     = ["-DPROFILING"]
 wayOptP _ WayEventLog = ["-DTRACING"]
-wayOptP _ WayPar      = ["-D__PARALLEL_HASKELL__"]
 
 whenGeneratingDynamicToo :: MonadIO m => DynFlags -> m () -> m ()
 whenGeneratingDynamicToo dflags f = ifGeneratingDynamicToo dflags f (return ())
@@ -1376,7 +1468,6 @@ initDynFlags dflags = do
  refDirsToClean <- newIORef Map.empty
  refFilesToNotIntermediateClean <- newIORef []
  refGeneratedDumps <- newIORef Set.empty
- refLlvmVersion <- newIORef 28
  refRtldInfo <- newIORef Nothing
  refRtccInfo <- newIORef Nothing
  wrapperNum <- newIORef emptyModuleEnv
@@ -1386,6 +1477,7 @@ initDynFlags dflags = do
                           do str' <- peekCString enc cstr
                              return (str == str'))
                          `catchIOError` \_ -> return False
+ canUseColor <- stderrSupportsAnsiColors
  return dflags{
         canGenerateDynamicToo = refCanGenerateDynamicToo,
         nextTempSuffix = refNextTempSuffix,
@@ -1393,9 +1485,9 @@ initDynFlags dflags = do
         dirsToClean    = refDirsToClean,
         filesToNotIntermediateClean = refFilesToNotIntermediateClean,
         generatedDumps = refGeneratedDumps,
-        llvmVersion    = refLlvmVersion,
         nextWrapperNum = wrapperNum,
         useUnicode    = canUseUnicode,
+        canUseColor   = canUseColor,
         rtldInfo      = refRtldInfo,
         rtccInfo      = refRtccInfo
         }
@@ -1409,13 +1501,15 @@ defaultDynFlags mySettings =
         ghcMode                 = CompManager,
         ghcLink                 = LinkBinary,
         hscTarget               = defaultHscTarget (sTargetPlatform mySettings),
-        sigOf                   = Map.empty,
         verbosity               = 0,
         optLevel                = 0,
+        debugLevel              = 0,
         simplPhases             = 2,
         maxSimplIterations      = 4,
+        maxPmCheckIterations    = 2000000,
         ruleCheck               = Nothing,
         maxRelevantBinds        = Just 6,
+        maxUncoveredPatterns    = 4,
         simplTickFactor         = 100,
         specConstrThreshold     = Just 2000,
         specConstrCount         = Just 3,
@@ -1431,13 +1525,15 @@ defaultDynFlags mySettings =
         enableTimeStats         = False,
         ghcHeapSize             = Nothing,
 
-        cmdlineHcIncludes       = [],
         importPaths             = ["."],
         mainModIs               = mAIN,
         mainFunIs               = Nothing,
         reductionDepth          = treatZeroAsInf mAX_REDUCTION_DEPTH,
+        solverIterations        = treatZeroAsInf mAX_SOLVER_ITERATIONS,
 
-        thisPackage             = mainPackageKey,
+        thisInstalledUnitId     = toInstalledUnitId mainUnitId,
+        thisUnitIdInsts_        = Nothing,
+        thisComponentId_        = Nothing,
 
         objectDir               = Nothing,
         dylibInstallName        = Nothing,
@@ -1458,6 +1554,7 @@ defaultDynFlags mySettings =
 
         pluginModNames          = [],
         pluginModNameOpts       = [],
+        frontendPluginOpts      = [],
         hooks                   = emptyHooks,
 
         outputFile              = Nothing,
@@ -1473,11 +1570,15 @@ defaultDynFlags mySettings =
         cmdlineFrameworks       = [],
         rtsOpts                 = Nothing,
         rtsOptsEnabled          = RtsOptsSafeOnly,
+        rtsOptsSuggestions      = True,
 
         hpcDir                  = ".hpc",
 
         extraPkgConfs           = id,
         packageFlags            = [],
+        pluginPackageFlags      = [],
+        ignorePackageFlags      = [],
+        trustFlags              = [],
         packageEnv              = Nothing,
         pkgDatabase             = Nothing,
         -- This gets filled in with GHC.setSessionDynFlags
@@ -1502,6 +1603,7 @@ defaultDynFlags mySettings =
         dumpFlags = IntSet.empty,
         generalFlags = IntSet.fromList (map fromEnum (defaultFlags mySettings)),
         warningFlags = IntSet.fromList (map fromEnum standardWarnings),
+        fatalWarningFlags = IntSet.empty,
         ghciScripts = [],
         language = Nothing,
         safeHaskell = Sf_None,
@@ -1526,7 +1628,7 @@ defaultDynFlags mySettings =
         ufCreationThreshold = 750,
         ufUseThreshold      = 60,
         ufFunAppDiscount    = 60,
-        -- Be fairly keen to inline a fuction if that means
+        -- Be fairly keen to inline a function if that means
         -- we'll be able to pick the right method from a dictionary
         ufDictDiscount      = 30,
         ufKeenessFactor     = 1.5,
@@ -1536,15 +1638,21 @@ defaultDynFlags mySettings =
 
         ghciHistSize = 50, -- keep a log of length 50 by default
 
+        -- Logging
+
+        initLogAction = defaultLogOutput,
+
         log_action = defaultLogAction,
+        log_finaliser = \ _ -> return (),
+
         flushOut = defaultFlushOut,
         flushErr = defaultFlushErr,
         pprUserLength = 5,
         pprCols = 100,
         useUnicode = False,
-        traceLevel = 1,
+        useColor = Auto,
+        canUseColor = False,
         profAuto = NoProfAuto,
-        llvmVersion = panic "defaultDynFlags: No llvmVersion",
         interactivePrint = Nothing,
         nextWrapperNum = panic "defaultDynFlags: No nextWrapperNum",
         sseVersion = Nothing,
@@ -1559,7 +1667,12 @@ defaultDynFlags mySettings =
 
         maxInlineAllocSize = 128,
         maxInlineMemcpyInsns = 32,
-        maxInlineMemsetInsns = 32
+        maxInlineMemsetInsns = 32,
+
+        initialUnique = 0,
+        uniqueIncrement = 1,
+
+        reverseErrors = False
       }
 
 defaultWays :: Settings -> [Way]
@@ -1568,47 +1681,138 @@ defaultWays settings = if pc_DYNAMIC_BY_DEFAULT (sPlatformConstants settings)
                        else []
 
 interpWays :: [Way]
-interpWays = if dynamicGhc
-             then [WayDyn]
-             else []
+interpWays
+  | dynamicGhc = [WayDyn]
+  | rtsIsProfiled = [WayProf]
+  | otherwise = []
+
+interpreterProfiled :: DynFlags -> Bool
+interpreterProfiled dflags
+  | gopt Opt_ExternalInterpreter dflags = gopt Opt_SccProfilingOn dflags
+  | otherwise = rtsIsProfiled
+
+interpreterDynamic :: DynFlags -> Bool
+interpreterDynamic dflags
+  | gopt Opt_ExternalInterpreter dflags = WayDyn `elem` ways dflags
+  | otherwise = dynamicGhc
 
 --------------------------------------------------------------------------
+--
+-- Note [JSON Error Messages]
+--
+-- When the user requests the compiler output to be dumped as json
+-- we modify the log_action to collect all the messages in an IORef
+-- and then finally in GHC.withCleanupSession the log_finaliser is
+-- called which prints out the messages together.
+--
+-- Before the compiler calls log_action, it has already turned the `ErrMsg`
+-- into a formatted message. This means that we lose some possible
+-- information to provide to the user but refactoring log_action is quite
+-- invasive as it is called in many places. So, for now I left it alone
+-- and we can refine its behaviour as users request different output.
 
 type FatalMessager = String -> IO ()
-type LogAction = DynFlags -> Severity -> SrcSpan -> PprStyle -> MsgDoc -> IO ()
+
+data LogOutput = LogOutput
+               { getLogAction :: LogAction
+               , getLogFinaliser :: LogFinaliser
+               }
+
+defaultLogOutput :: IO (Maybe LogOutput)
+defaultLogOutput = return $ Nothing
+
+type LogAction = DynFlags
+              -> WarnReason
+              -> Severity
+              -> SrcSpan
+              -> PprStyle
+              -> MsgDoc
+              -> IO ()
+
+type LogFinaliser = DynFlags -> IO ()
 
 defaultFatalMessager :: FatalMessager
 defaultFatalMessager = hPutStrLn stderr
 
+
+-- See Note [JSON Error Messages]
+jsonLogOutput :: IO (Maybe LogOutput)
+jsonLogOutput = do
+  ref <- newIORef []
+  return . Just $ LogOutput (jsonLogAction ref) (jsonLogFinaliser ref)
+
+jsonLogAction :: IORef [SDoc] -> LogAction
+jsonLogAction iref dflags reason severity srcSpan style msg
+  = do
+      addMessage . withPprStyle (mkCodeStyle CStyle) . renderJSON $
+        JSObject [ ( "span", json srcSpan )
+                 , ( "doc" , JSString (showSDoc dflags msg) )
+                 , ( "severity", json severity )
+                 , ( "reason" ,   json reason )
+                ]
+      defaultLogAction dflags reason severity srcSpan style msg
+  where
+    addMessage m = modifyIORef iref (m:)
+
+
+jsonLogFinaliser :: IORef [SDoc] -> DynFlags -> IO ()
+jsonLogFinaliser iref dflags = do
+  msgs <- readIORef iref
+  let fmt_msgs = brackets $ pprWithCommas (blankLine $$) msgs
+  output fmt_msgs
+  where
+    -- dumpSDoc uses log_action to output the dump
+    dflags' = dflags { log_action = defaultLogAction }
+    output doc = dumpSDoc dflags' neverQualify Opt_D_dump_json "" doc
+
+
 defaultLogAction :: LogAction
-defaultLogAction dflags severity srcSpan style msg
+defaultLogAction dflags reason severity srcSpan style msg
     = case severity of
-      SevOutput      -> printSDoc msg style
-      SevDump        -> printSDoc (msg $$ blankLine) style
+      SevOutput      -> printOut msg style
+      SevDump        -> printOut (msg $$ blankLine) style
       SevInteractive -> putStrSDoc msg style
       SevInfo        -> printErrs msg style
       SevFatal       -> printErrs msg style
-      _              -> do hPutChar stderr '\n'
-                           printErrs (mkLocMessage severity srcSpan msg) style
+      _              -> do -- otherwise (i.e. SevError or SevWarning)
+                           hPutChar stderr '\n'
+                           caretDiagnostic <-
+                               if gopt Opt_DiagnosticsShowCaret dflags
+                               then getCaretDiagnostic severity srcSpan
+                               else pure empty
+                           printErrs (message $+$ caretDiagnostic)
+                               (setStyleColoured True style)
                            -- careful (#2302): printErrs prints in UTF-8,
                            -- whereas converting to string first and using
                            -- hPutStr would just emit the low 8 bits of
                            -- each unicode char.
-    where printSDoc  = defaultLogActionHPrintDoc  dflags stdout
+    where printOut   = defaultLogActionHPrintDoc  dflags stdout
           printErrs  = defaultLogActionHPrintDoc  dflags stderr
           putStrSDoc = defaultLogActionHPutStrDoc dflags stdout
-
+          -- Pretty print the warning flag, if any (#10752)
+          message = mkLocMessageAnn flagMsg severity srcSpan msg
+          flagMsg = case reason of
+                        NoReason -> Nothing
+                        Reason flag -> (\spec -> "-W" ++ flagSpecName spec ++ flagGrp flag) <$>
+                                          flagSpecOf flag
+
+          flagGrp flag
+              | gopt Opt_ShowWarnGroups dflags =
+                    case smallestGroups flag of
+                        [] -> ""
+                        groups -> " (in " ++ intercalate ", " (map ("-W"++) groups) ++ ")"
+              | otherwise = ""
+
+-- | Like 'defaultLogActionHPutStrDoc' but appends an extra newline.
 defaultLogActionHPrintDoc :: DynFlags -> Handle -> SDoc -> PprStyle -> IO ()
 defaultLogActionHPrintDoc dflags h d sty
  = defaultLogActionHPutStrDoc dflags h (d $$ text "") sty
-      -- Adds a newline
 
 defaultLogActionHPutStrDoc :: DynFlags -> Handle -> SDoc -> PprStyle -> IO ()
 defaultLogActionHPutStrDoc dflags h d sty
-  = Pretty.printDoc_ Pretty.PageMode (pprCols dflags) h doc
-  where   -- Don't add a newline at the end, so that successive
-          -- calls to this log-action can output all on the same line
-    doc = runSDoc d (initSDocContext dflags sty)
+  -- Don't add a newline at the end, so that successive
+  -- calls to this log-action can output all on the same line
+  = printSDoc Pretty.PageMode dflags h sty d
 
 newtype FlushOut = FlushOut (IO ())
 
@@ -1633,35 +1837,40 @@ Note [Verbosity levels]
 
 data OnOff a = On a
              | Off a
+  deriving (Eq, Show)
+
+instance Outputable a => Outputable (OnOff a) where
+  ppr (On x)  = text "On" <+> ppr x
+  ppr (Off x) = text "Off" <+> ppr x
 
 -- OnOffs accumulate in reverse order, so we use foldr in order to
 -- process them in the right order
-flattenExtensionFlags :: Maybe Language -> [OnOff ExtensionFlag] -> IntSet
+flattenExtensionFlags :: Maybe Language -> [OnOff LangExt.Extension] -> IntSet
 flattenExtensionFlags ml = foldr f defaultExtensionFlags
     where f (On f)  flags = IntSet.insert (fromEnum f) flags
           f (Off f) flags = IntSet.delete (fromEnum f) flags
           defaultExtensionFlags = IntSet.fromList (map fromEnum (languageExtensions ml))
 
-languageExtensions :: Maybe Language -> [ExtensionFlag]
+languageExtensions :: Maybe Language -> [LangExt.Extension]
 
 languageExtensions Nothing
     -- Nothing => the default case
-    = Opt_NondecreasingIndentation -- This has been on by default for some time
-    : delete Opt_DatatypeContexts  -- The Haskell' committee decided to
-                                   -- remove datatype contexts from the
-                                   -- language:
+    = LangExt.NondecreasingIndentation -- This has been on by default for some time
+    : delete LangExt.DatatypeContexts  -- The Haskell' committee decided to
+                                       -- remove datatype contexts from the
+                                       -- language:
    -- http://www.haskell.org/pipermail/haskell-prime/2011-January/003335.html
       (languageExtensions (Just Haskell2010))
 
    -- NB: MonoPatBinds is no longer the default
 
 languageExtensions (Just Haskell98)
-    = [Opt_ImplicitPrelude,
-       Opt_MonomorphismRestriction,
-       Opt_NPlusKPatterns,
-       Opt_DatatypeContexts,
-       Opt_TraditionalRecordSyntax,
-       Opt_NondecreasingIndentation
+    = [LangExt.ImplicitPrelude,
+       LangExt.MonomorphismRestriction,
+       LangExt.NPlusKPatterns,
+       LangExt.DatatypeContexts,
+       LangExt.TraditionalRecordSyntax,
+       LangExt.NondecreasingIndentation
            -- strictly speaking non-standard, but we always had this
            -- on implicitly before the option was added in 7.1, and
            -- turning it off breaks code, so we're keeping it on for
@@ -1670,15 +1879,15 @@ languageExtensions (Just Haskell98)
       ]
 
 languageExtensions (Just Haskell2010)
-    = [Opt_ImplicitPrelude,
-       Opt_MonomorphismRestriction,
-       Opt_DatatypeContexts,
-       Opt_TraditionalRecordSyntax,
-       Opt_EmptyDataDecls,
-       Opt_ForeignFunctionInterface,
-       Opt_PatternGuards,
-       Opt_DoAndIfThenElse,
-       Opt_RelaxedPolyRec]
+    = [LangExt.ImplicitPrelude,
+       LangExt.MonomorphismRestriction,
+       LangExt.DatatypeContexts,
+       LangExt.TraditionalRecordSyntax,
+       LangExt.EmptyDataDecls,
+       LangExt.ForeignFunctionInterface,
+       LangExt.PatternGuards,
+       LangExt.DoAndIfThenElse,
+       LangExt.RelaxedPolyRec]
 
 -- | Test whether a 'DumpFlag' is set
 dopt :: DumpFlag -> DynFlags -> Bool
@@ -1691,6 +1900,7 @@ dopt f dflags = (fromEnum f `IntSet.member` dumpFlags dflags)
           enableIfVerbose Opt_D_dump_vt_trace               = False
           enableIfVerbose Opt_D_dump_tc                     = False
           enableIfVerbose Opt_D_dump_rn                     = False
+          enableIfVerbose Opt_D_dump_shape                  = False
           enableIfVerbose Opt_D_dump_rn_stats               = False
           enableIfVerbose Opt_D_dump_hi_diffs               = False
           enableIfVerbose Opt_D_verbose_core2core           = False
@@ -1710,6 +1920,7 @@ dopt f dflags = (fromEnum f `IntSet.member` dumpFlags dflags)
           enableIfVerbose Opt_D_dump_view_pattern_commoning = False
           enableIfVerbose Opt_D_dump_mod_cycles             = False
           enableIfVerbose Opt_D_dump_mod_map                = False
+          enableIfVerbose Opt_D_dump_ec_trace               = False
           enableIfVerbose _                                 = True
 
 -- | Set a 'DumpFlag'
@@ -1744,19 +1955,35 @@ wopt_set dfs f = dfs{ warningFlags = IntSet.insert (fromEnum f) (warningFlags df
 wopt_unset :: DynFlags -> WarningFlag -> DynFlags
 wopt_unset dfs f = dfs{ warningFlags = IntSet.delete (fromEnum f) (warningFlags dfs) }
 
--- | Test whether a 'ExtensionFlag' is set
-xopt :: ExtensionFlag -> DynFlags -> Bool
+-- | Test whether a 'WarningFlag' is set as fatal
+wopt_fatal :: WarningFlag -> DynFlags -> Bool
+wopt_fatal f dflags = fromEnum f `IntSet.member` fatalWarningFlags dflags
+
+-- | Mark a 'WarningFlag' as fatal (do not set the flag)
+wopt_set_fatal :: DynFlags -> WarningFlag -> DynFlags
+wopt_set_fatal dfs f
+    = dfs { fatalWarningFlags =
+              IntSet.insert (fromEnum f) (fatalWarningFlags dfs) }
+
+-- | Mark a 'WarningFlag' as not fatal
+wopt_unset_fatal :: DynFlags -> WarningFlag -> DynFlags
+wopt_unset_fatal dfs f
+    = dfs { fatalWarningFlags =
+              IntSet.delete (fromEnum f) (fatalWarningFlags dfs) }
+
+-- | Test whether a 'LangExt.Extension' is set
+xopt :: LangExt.Extension -> DynFlags -> Bool
 xopt f dflags = fromEnum f `IntSet.member` extensionFlags dflags
 
--- | Set a 'ExtensionFlag'
-xopt_set :: DynFlags -> ExtensionFlag -> DynFlags
+-- | Set a 'LangExt.Extension'
+xopt_set :: DynFlags -> LangExt.Extension -> DynFlags
 xopt_set dfs f
     = let onoffs = On f : extensions dfs
       in dfs { extensions = onoffs,
                extensionFlags = flattenExtensionFlags (language dfs) onoffs }
 
--- | Unset a 'ExtensionFlag'
-xopt_unset :: DynFlags -> ExtensionFlag -> DynFlags
+-- | Unset a 'LangExt.Extension'
+xopt_unset :: DynFlags -> LangExt.Extension -> DynFlags
 xopt_unset dfs f
     = let onoffs = Off f : extensions dfs
       in dfs { extensions = onoffs,
@@ -1769,7 +1996,10 @@ lang_set dflags lang =
             extensionFlags = flattenExtensionFlags lang (extensions dflags)
           }
 
--- | Check whether to use unicode syntax for output
+-- | An internal helper to check whether to use unicode syntax for output.
+--
+-- Note: You should very likely be using 'Outputable.unicodeSyntax' instead
+-- of this function.
 useUnicodeSyntax :: DynFlags -> Bool
 useUnicodeSyntax = gopt Opt_PrintUnicodeSyntax
 
@@ -1837,7 +2067,7 @@ combineSafeFlags :: SafeHaskellMode -> SafeHaskellMode -> DynP SafeHaskellMode
 combineSafeFlags a b | a == Sf_None         = return b
                      | b == Sf_None         = return a
                      | a == b               = return a
-                     | otherwise            = addErr errm >> return (panic errm)
+                     | otherwise            = addErr errm >> pure a
     where errm = "Incompatible Safe Haskell flags! ("
                     ++ show a ++ ", " ++ show b ++ ")"
 
@@ -1849,21 +2079,13 @@ combineSafeFlags a b | a == Sf_None         = return b
 unsafeFlags, unsafeFlagsForInfer
   :: [(String, DynFlags -> SrcSpan, DynFlags -> Bool, DynFlags -> DynFlags)]
 unsafeFlags = [ ("-XGeneralizedNewtypeDeriving", newDerivOnLoc,
-                    xopt Opt_GeneralizedNewtypeDeriving,
-                    flip xopt_unset Opt_GeneralizedNewtypeDeriving)
+                    xopt LangExt.GeneralizedNewtypeDeriving,
+                    flip xopt_unset LangExt.GeneralizedNewtypeDeriving)
               , ("-XTemplateHaskell", thOnLoc,
-                    xopt Opt_TemplateHaskell,
-                    flip xopt_unset Opt_TemplateHaskell)
-              ]
-unsafeFlagsForInfer = unsafeFlags ++
-              -- TODO: Can we do better than this for inference?
-              [ ("-XOverlappingInstances", overlapInstLoc,
-                  xopt Opt_OverlappingInstances,
-                  flip xopt_unset Opt_OverlappingInstances)
-              , ("-XIncoherentInstances", incoherentOnLoc,
-                  xopt Opt_IncoherentInstances,
-                  flip xopt_unset Opt_IncoherentInstances)
+                    xopt LangExt.TemplateHaskell,
+                    flip xopt_unset LangExt.TemplateHaskell)
               ]
+unsafeFlagsForInfer = unsafeFlags
 
 
 -- | Retrieve the options corresponding to a particular @opt_*@ field in the correct order
@@ -1891,46 +2113,75 @@ setObjectDir, setHiDir, setStubDir, setDumpDir, setOutputDir,
 setOutputFile, setDynOutputFile, setOutputHi, setDumpPrefixForce
    :: Maybe String -> DynFlags -> DynFlags
 
-setObjectDir  f d = d{ objectDir  = Just f}
-setHiDir      f d = d{ hiDir      = Just f}
-setStubDir    f d = d{ stubDir    = Just f, includePaths = f : includePaths d }
+setObjectDir  f d = d { objectDir  = Just f}
+setHiDir      f d = d { hiDir      = Just f}
+setStubDir    f d = d { stubDir    = Just f, includePaths = f : includePaths d }
   -- -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}
+setDumpDir    f d = d { dumpDir    = Just f}
 setOutputDir  f = setObjectDir 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}
-setDynHiSuf     f d = d{ dynHiSuf     = f}
-setHcSuf        f d = d{ hcSuf        = f}
-
-setOutputFile f d = d{ outputFile = f}
-setDynOutputFile f d = d{ dynOutputFile = f}
-setOutputHi   f d = d{ outputHi   = 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}
+setDynHiSuf     f d = d { dynHiSuf     = f}
+setHcSuf        f d = d { hcSuf        = f}
+
+setOutputFile f d = d { outputFile = f}
+setDynOutputFile f d = d { dynOutputFile = f}
+setOutputHi   f d = d { outputHi   = f}
+
+setJsonLogAction :: DynFlags -> DynFlags
+setJsonLogAction d = d { initLogAction = jsonLogOutput }
+
+thisComponentId :: DynFlags -> ComponentId
+thisComponentId dflags =
+  case thisComponentId_ dflags of
+    Just cid -> cid
+    Nothing  ->
+      case thisUnitIdInsts_ dflags of
+        Just _  ->
+          throwGhcException $ CmdLineError ("Use of -instantiated-with requires -this-component-id")
+        Nothing -> ComponentId (unitIdFS (thisPackage dflags))
+
+thisUnitIdInsts :: DynFlags -> [(ModuleName, Module)]
+thisUnitIdInsts dflags =
+    case thisUnitIdInsts_ dflags of
+        Just insts -> insts
+        Nothing    -> []
+
+thisPackage :: DynFlags -> UnitId
+thisPackage dflags =
+    case thisUnitIdInsts_ dflags of
+        Nothing -> default_uid
+        Just insts
+          | all (\(x,y) -> mkHoleModule x == y) insts
+          -> newUnitId (thisComponentId dflags) insts
+          | otherwise
+          -> default_uid
+  where
+    default_uid = DefiniteUnitId (DefUnitId (thisInstalledUnitId dflags))
 
-parseSigOf :: String -> SigOf
-parseSigOf str = case filter ((=="").snd) (readP_to_S parse str) of
+parseUnitIdInsts :: String -> [(ModuleName, Module)]
+parseUnitIdInsts str = case filter ((=="").snd) (readP_to_S parse str) of
     [(r, "")] -> r
-    _ -> throwGhcException $ CmdLineError ("Can't parse -sig-of: " ++ str)
-  where parse = Map.fromList <$> sepBy parseEntry (R.char ',')
+    _ -> throwGhcException $ CmdLineError ("Can't parse -instantiated-with: " ++ str)
+  where parse = sepBy parseEntry (R.char ',')
         parseEntry = do
-            n <- tok $ parseModuleName
-            -- ToDo: deprecate this 'is' syntax?
-            tok $ ((string "is" >> return ()) +++ (R.char '=' >> return ()))
-            m <- tok $ parseModule
+            n <- parseModuleName
+            _ <- R.char '='
+            m <- parseModuleId
             return (n, m)
-        parseModule = do
-            pk <- munch1 (\c -> isAlphaNum c || c `elem` "-_")
-            _ <- R.char ':'
-            m <- parseModuleName
-            return (mkModule (stringToPackageKey pk) m)
-        tok m = skipSpaces >> m
 
-setSigOf :: String -> DynFlags -> DynFlags
-setSigOf s d = d { sigOf = parseSigOf s }
+setUnitIdInsts :: String -> DynFlags -> DynFlags
+setUnitIdInsts s d =
+    d { thisUnitIdInsts_ = Just (parseUnitIdInsts s) }
+
+setComponentId :: String -> DynFlags -> DynFlags
+setComponentId s d =
+    d { thisComponentId_ = Just (ComponentId (fsLit s)) }
 
 addPluginModuleName :: String -> DynFlags -> DynFlags
 addPluginModuleName name d = d { pluginModNames = (mkModuleName name) : (pluginModNames d) }
@@ -1942,10 +2193,13 @@ addPluginModuleNameOption optflag d = d { pluginModNameOpts = (mkModuleName m, o
           [] -> "" -- should probably signal an error
           (_:plug_opt) -> plug_opt -- ignore the ':' from break
 
+addFrontendPluginOption :: String -> DynFlags -> DynFlags
+addFrontendPluginOption s d = d { frontendPluginOpts = s : frontendPluginOpts d }
+
 parseDynLibLoaderMode f d =
  case splitAt 8 f of
-   ("deploy", "")       -> d{ dynLibLoader = Deployable }
-   ("sysdep", "")       -> d{ dynLibLoader = SystemDependent }
+   ("deploy", "")       -> d { dynLibLoader = Deployable }
+   ("sysdep", "")       -> d { dynLibLoader = SystemDependent }
    _                    -> throwGhcException (CmdLineError ("Unknown dynlib loader: " ++ f))
 
 setDumpPrefixForce f d = d { dumpPrefixForce = f}
@@ -1971,13 +2225,13 @@ addDepExcludeMod m d
 addDepSuffix :: FilePath -> DynFlags -> DynFlags
 addDepSuffix s d = d { depSuffixes = s : depSuffixes d }
 
-addCmdlineFramework f d = d{ cmdlineFrameworks = f : cmdlineFrameworks d}
+addCmdlineFramework f d = d { cmdlineFrameworks = f : cmdlineFrameworks d}
 
-addHaddockOpts f d = d{ haddockOptions = Just f}
+addHaddockOpts f d = d { haddockOptions = Just f}
 
-addGhciScript f d = d{ ghciScripts = f : ghciScripts d}
+addGhciScript f d = d { ghciScripts = f : ghciScripts d}
 
-setInteractivePrint f d = d{ interactivePrint = Just f}
+setInteractivePrint f d = d { interactivePrint = Just f}
 
 -- -----------------------------------------------------------------------------
 -- Command-line options
@@ -2015,28 +2269,6 @@ updOptLevel n dfs
    extra_gopts  = [ f | (ns,f) <- optLevelFlags, final_n `elem` ns ]
    remove_gopts = [ f | (ns,f) <- optLevelFlags, final_n `notElem` ns ]
 
--- -----------------------------------------------------------------------------
--- StgToDo:  abstraction of stg-to-stg passes to run.
-
-data StgToDo
-  = StgDoMassageForProfiling  -- should be (next to) last
-  -- There's also setStgVarInfo, but its absolute "lastness"
-  -- is so critical that it is hardwired in (no flag).
-  | D_stg_stats
-
-getStgToDo :: DynFlags -> [StgToDo]
-getStgToDo dflags
-  = todo2
-  where
-        stg_stats = gopt Opt_StgStats dflags
-
-        todo1 = if stg_stats then [D_stg_stats] else []
-
-        todo2 | WayProf `elem` ways dflags
-              = StgDoMassageForProfiling : todo1
-              | otherwise
-              = todo1
-
 {- **********************************************************************
 %*                                                                      *
                 DynFlags parser
@@ -2127,17 +2359,31 @@ parseDynamicFlagsFull activeFlags cmdline dflags0 args = do
     Just x -> liftIO (setHeapSize x)
     _      -> return ()
 
-  liftIO $ setUnsafeGlobalDynFlags dflags6
+  dflags7 <- liftIO $ setLogAction dflags6
+
+  liftIO $ setUnsafeGlobalDynFlags dflags7
+
+  return (dflags7, leftover, consistency_warnings ++ sh_warns ++ warns)
+
+setLogAction :: DynFlags -> IO DynFlags
+setLogAction dflags = do
+ mlogger <- initLogAction dflags
+ return $
+    maybe
+         dflags
+         (\logger ->
+            dflags
+              { log_action    = getLogAction logger
+              , log_finaliser = getLogFinaliser logger
+              , initLogAction = return $ Nothing -- Don't initialise it twice
+              })
+         mlogger
 
-  return (dflags6, leftover, consistency_warnings ++ sh_warns ++ warns)
 
 updateWays :: DynFlags -> DynFlags
 updateWays dflags
     = let theWays = sort $ nub $ ways dflags
-          f = if WayDyn `elem` theWays then unSetGeneralFlag'
-                                       else setGeneralFlag'
-      in f Opt_Static
-       $ dflags {
+      in dflags {
              ways        = theWays,
              buildTag    = mkBuildTag (filter (not . wayRTSOnly) theWays),
              rtsBuildTag = mkBuildTag                            theWays
@@ -2180,9 +2426,8 @@ safeFlagCheck cmdl dflags =
                     "-fpackage-trust ignored;" ++
                     " must be specified with a Safe Haskell flag"]
 
+    -- Have we inferred Unsafe? See Note [HscMain . Safe Haskell Inference]
     safeFlags = all (\(_,_,t,_) -> not $ t dflags) unsafeFlagsForInfer
-    -- Have we inferred Unsafe?
-    -- See Note [HscMain . Safe Haskell Inference]
 
 
 {- **********************************************************************
@@ -2191,14 +2436,21 @@ safeFlagCheck cmdl dflags =
 %*                                                                      *
 %********************************************************************* -}
 
--- | All dynamic flags option strings. These are the user facing strings for
--- enabling and disabling options.
-allFlags :: [String]
-allFlags = [ '-':flagName flag
-           | flag <- flagsAll
-           , ok (flagOptKind flag) ]
+-- | All dynamic flags option strings without the deprecated ones.
+-- These are the user facing strings for enabling and disabling options.
+allNonDeprecatedFlags :: [String]
+allNonDeprecatedFlags = allFlagsDeps False
+
+-- | All flags with possibility to filter deprecated ones
+allFlagsDeps :: Bool -> [String]
+allFlagsDeps keepDeprecated = [ '-':flagName flag
+                              | (deprecated, flag) <- flagsAllDeps
+                              , ok (flagOptKind flag)
+                              , keepDeprecated || not (isDeprecated deprecated)]
   where ok (PrefixPred _ _) = False
         ok _   = True
+        isDeprecated Deprecated = True
+        isDeprecated _ = False
 
 {-
  - Below we export user facing symbols for GHC dynamic flags for use with the
@@ -2207,222 +2459,345 @@ allFlags = [ '-':flagName flag
 
 -- All dynamic flags present in GHC.
 flagsAll :: [Flag (CmdLineP DynFlags)]
-flagsAll     = package_flags ++ dynamic_flags
+flagsAll = map snd flagsAllDeps
+
+-- All dynamic flags present in GHC with deprecation information.
+flagsAllDeps :: [(Deprecation, Flag (CmdLineP DynFlags))]
+flagsAllDeps =  package_flags_deps ++ dynamic_flags_deps
+
 
 -- All dynamic flags, minus package flags, present in GHC.
 flagsDynamic :: [Flag (CmdLineP DynFlags)]
-flagsDynamic = dynamic_flags
+flagsDynamic = map snd dynamic_flags_deps
 
 -- ALl package flags present in GHC.
 flagsPackage :: [Flag (CmdLineP DynFlags)]
-flagsPackage = package_flags
-
---------------- The main flags themselves ------------------
+flagsPackage = map snd package_flags_deps
+
+----------------Helpers to make flags and keep deprecation information----------
+
+type FlagMaker m = String -> OptKind m -> Flag m
+type DynFlagMaker = FlagMaker (CmdLineP DynFlags)
+data Deprecation = NotDeprecated | Deprecated deriving (Eq, Ord)
+
+-- Make a non-deprecated flag
+make_ord_flag :: DynFlagMaker -> String -> OptKind (CmdLineP DynFlags)
+              -> (Deprecation, Flag (CmdLineP DynFlags))
+make_ord_flag fm name kind = (NotDeprecated, fm name kind)
+
+-- Make a deprecated flag
+make_dep_flag :: DynFlagMaker -> String -> OptKind (CmdLineP DynFlags) -> String
+                 -> (Deprecation, Flag (CmdLineP DynFlags))
+make_dep_flag fm name kind message = (Deprecated,
+                                      fm name $ add_dep_message kind message)
+
+add_dep_message :: OptKind (CmdLineP DynFlags) -> String
+                -> OptKind (CmdLineP DynFlags)
+add_dep_message (NoArg f) message = NoArg $ f >> deprecate message
+add_dep_message (HasArg f) message = HasArg $ \s -> f s >> deprecate message
+add_dep_message (SepArg f) message = SepArg $ \s -> f s >> deprecate message
+add_dep_message (Prefix f) message = Prefix $ \s -> f s >> deprecate message
+add_dep_message (OptPrefix f) message =
+                                  OptPrefix $ \s -> f s >> deprecate message
+add_dep_message (OptIntSuffix f) message =
+                               OptIntSuffix $ \oi -> f oi >> deprecate message
+add_dep_message (IntSuffix f) message =
+                                  IntSuffix $ \i -> f i >> deprecate message
+add_dep_message (FloatSuffix f) message =
+                                FloatSuffix $ \fl -> f fl >> deprecate message
+add_dep_message (PassFlag f) message =
+                                   PassFlag $ \s -> f s >> deprecate message
+add_dep_message (AnySuffix f) message =
+                                  AnySuffix $ \s -> f s >> deprecate message
+add_dep_message (PrefixPred pred f) message =
+                            PrefixPred pred $ \s -> f s >> deprecate message
+add_dep_message (AnySuffixPred pred f) message =
+                         AnySuffixPred pred $ \s -> f s >> deprecate message
+
+----------------------- The main flags themselves ------------------------------
 -- See Note [Updating flag description in the User's Guide]
 -- See Note [Supporting CLI completion]
-dynamic_flags :: [Flag (CmdLineP DynFlags)]
-dynamic_flags = [
-    defFlag "n"
-      (NoArg (addWarn "The -n flag is deprecated and no longer has any effect"))
-  , defFlag "cpp"      (NoArg (setExtensionFlag Opt_Cpp))
-  , defFlag "F"        (NoArg (setGeneralFlag Opt_Pp))
-  , defFlag "#include"
-      (HasArg (\s -> do
-         addCmdlineHCInclude s
+dynamic_flags_deps :: [(Deprecation, Flag (CmdLineP DynFlags))]
+dynamic_flags_deps = [
+    make_dep_flag defFlag "n" (NoArg $ return ())
+        "The -n flag is deprecated and no longer has any effect"
+  , make_ord_flag defFlag "cpp"      (NoArg (setExtensionFlag LangExt.Cpp))
+  , make_ord_flag defFlag "F"        (NoArg (setGeneralFlag Opt_Pp))
+  , (Deprecated, defFlag "#include"
+      (HasArg (\_s ->
          addWarn ("-#include and INCLUDE pragmas are " ++
-                  "deprecated: They no longer have any effect")))
-  , defFlag "v"        (OptIntSuffix setVerbosity)
-
-  , defGhcFlag "j"     (OptIntSuffix (\n -> upd (\d -> d {parMakeCount = n})))
-  , defFlag "sig-of"   (sepArg setSigOf)
+                  "deprecated: They no longer have any effect"))))
+  , make_ord_flag defFlag "v"        (OptIntSuffix setVerbosity)
+
+  , make_ord_flag defGhcFlag "j"     (OptIntSuffix
+        (\n -> case n of
+                 Just n
+                     | n > 0     -> upd (\d -> d { parMakeCount = Just n })
+                     | otherwise -> addErr "Syntax: -j[n] where n > 0"
+                 Nothing -> upd (\d -> d { parMakeCount = Nothing })))
+                 -- When the number of parallel builds
+                 -- is omitted, it is the same
+                 -- as specifing that the number of
+                 -- parallel builds is equal to the
+                 -- result of getNumProcessors
+  , make_ord_flag defFlag "instantiated-with"   (sepArg setUnitIdInsts)
+  , make_ord_flag defFlag "this-component-id"   (sepArg setComponentId)
 
     -- RTS options -------------------------------------------------------------
-  , defFlag "H"           (HasArg (\s -> upd (\d ->
+  , make_ord_flag defFlag "H"           (HasArg (\s -> upd (\d ->
           d { ghcHeapSize = Just $ fromIntegral (decodeSize s)})))
 
-  , defFlag "Rghc-timing" (NoArg (upd (\d -> d { enableTimeStats = True })))
+  , make_ord_flag defFlag "Rghc-timing" (NoArg (upd (\d ->
+                                               d { enableTimeStats = True })))
 
     ------- ways ---------------------------------------------------------------
-  , defGhcFlag "prof"           (NoArg (addWay WayProf))
-  , defGhcFlag "eventlog"       (NoArg (addWay WayEventLog))
-  , defGhcFlag "parallel"       (NoArg (addWay WayPar))
-  , defGhcFlag "smp"
-      (NoArg (addWay WayThreaded >> deprecate "Use -threaded instead"))
-  , defGhcFlag "debug"          (NoArg (addWay WayDebug))
-  , defGhcFlag "threaded"       (NoArg (addWay WayThreaded))
-
-  , defGhcFlag "ticky"
+  , make_ord_flag defGhcFlag "prof"           (NoArg (addWay WayProf))
+  , make_ord_flag defGhcFlag "eventlog"       (NoArg (addWay WayEventLog))
+  , make_dep_flag defGhcFlag "smp"
+      (NoArg $ addWay WayThreaded) "Use -threaded instead"
+  , make_ord_flag defGhcFlag "debug"          (NoArg (addWay WayDebug))
+  , make_ord_flag defGhcFlag "threaded"       (NoArg (addWay WayThreaded))
+
+  , make_ord_flag defGhcFlag "ticky"
       (NoArg (setGeneralFlag Opt_Ticky >> addWay WayDebug))
 
     -- -ticky enables ticky-ticky code generation, and also implies -debug which
     -- is required to get the RTS ticky support.
 
         ----- Linker --------------------------------------------------------
-  , defGhcFlag "static"         (NoArg removeWayDyn)
-  , defGhcFlag "dynamic"        (NoArg (addWay WayDyn))
-  , defGhcFlag "rdynamic" $ noArg $
+  , make_ord_flag defGhcFlag "static"         (NoArg removeWayDyn)
+  , make_ord_flag defGhcFlag "dynamic"        (NoArg (addWay WayDyn))
+  , make_ord_flag defGhcFlag "rdynamic" $ noArg $
 #ifdef linux_HOST_OS
                               addOptl "-rdynamic"
 #elif defined (mingw32_HOST_OS)
-                              addOptl "-export-all-symbols"
+                              addOptl "-Wl,--export-all-symbols"
 #else
     -- ignored for compat w/ gcc:
                               id
 #endif
-  , defGhcFlag "relative-dynlib-paths"
+  , make_ord_flag defGhcFlag "relative-dynlib-paths"
       (NoArg (setGeneralFlag Opt_RelativeDynlibPaths))
 
         ------- Specific phases  --------------------------------------------
     -- need to appear before -pgmL to be parsed as LLVM flags.
-  , defFlag "pgmlo"
+  , make_ord_flag defFlag "pgmlo"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_lo  = (f,[])})))
-  , defFlag "pgmlc"
+  , make_ord_flag defFlag "pgmlc"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_lc  = (f,[])})))
-  , defFlag "pgmL"
+  , make_ord_flag defFlag "pgmi"
+      (hasArg (\f -> alterSettings (\s -> s { sPgm_i  =  f})))
+  , make_ord_flag defFlag "pgmL"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_L   = f})))
-  , defFlag "pgmP"
+  , make_ord_flag defFlag "pgmP"
       (hasArg setPgmP)
-  , defFlag "pgmF"
+  , make_ord_flag defFlag "pgmF"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_F   = f})))
-  , defFlag "pgmc"
+  , make_ord_flag defFlag "pgmc"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_c   = (f,[])})))
-  , defFlag "pgms"
+  , make_ord_flag defFlag "pgms"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_s   = (f,[])})))
-  , defFlag "pgma"
+  , make_ord_flag defFlag "pgma"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_a   = (f,[])})))
-  , defFlag "pgml"
+  , make_ord_flag defFlag "pgml"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_l   = (f,[])})))
-  , defFlag "pgmdll"
+  , make_ord_flag defFlag "pgmdll"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_dll = (f,[])})))
-  , defFlag "pgmwindres"
+  , make_ord_flag defFlag "pgmwindres"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_windres = f})))
-  , defFlag "pgmlibtool"
+  , make_ord_flag defFlag "pgmlibtool"
       (hasArg (\f -> alterSettings (\s -> s { sPgm_libtool = f})))
 
     -- need to appear before -optl/-opta to be parsed as LLVM flags.
-  , defFlag "optlo"
+  , make_ord_flag defFlag "optlo"
       (hasArg (\f -> alterSettings (\s -> s { sOpt_lo  = f : sOpt_lo s})))
-  , defFlag "optlc"
+  , make_ord_flag defFlag "optlc"
       (hasArg (\f -> alterSettings (\s -> s { sOpt_lc  = f : sOpt_lc s})))
-  , defFlag "optL"
+  , make_ord_flag defFlag "opti"
+      (hasArg (\f -> alterSettings (\s -> s { sOpt_i   = f : sOpt_i s})))
+  , make_ord_flag defFlag "optL"
       (hasArg (\f -> alterSettings (\s -> s { sOpt_L   = f : sOpt_L s})))
-  , defFlag "optP"
+  , make_ord_flag defFlag "optP"
       (hasArg addOptP)
-  , defFlag "optF"
+  , make_ord_flag defFlag "optF"
       (hasArg (\f -> alterSettings (\s -> s { sOpt_F   = f : sOpt_F s})))
-  , defFlag "optc"
+  , make_ord_flag defFlag "optc"
       (hasArg addOptc)
-  , defFlag "opta"
+  , make_ord_flag defFlag "opta"
       (hasArg (\f -> alterSettings (\s -> s { sOpt_a   = f : sOpt_a s})))
-  , defFlag "optl"
+  , make_ord_flag defFlag "optl"
       (hasArg addOptl)
-  , defFlag "optwindres"
+  , make_ord_flag defFlag "optwindres"
       (hasArg (\f ->
         alterSettings (\s -> s { sOpt_windres = f : sOpt_windres s})))
 
-  , defGhcFlag "split-objs"
+  , make_ord_flag defGhcFlag "split-objs"
       (NoArg (if can_split
                 then setGeneralFlag Opt_SplitObjs
                 else addWarn "ignoring -fsplit-objs"))
 
+  , make_ord_flag defGhcFlag "split-sections"
+      (noArgM (\dflags -> do
+        if platformHasSubsectionsViaSymbols (targetPlatform dflags)
+          then do addErr $
+                    "-split-sections is not useful on this platform " ++
+                    "since it always uses subsections via symbols."
+                  return dflags
+          else return (gopt_set dflags Opt_SplitSections)))
+
         -------- ghc -M -----------------------------------------------------
-  , defGhcFlag "dep-suffix"               (hasArg addDepSuffix)
-  , defGhcFlag "dep-makefile"             (hasArg setDepMakefile)
-  , defGhcFlag "include-pkg-deps"         (noArg (setDepIncludePkgDeps True))
-  , defGhcFlag "exclude-module"           (hasArg addDepExcludeMod)
+  , make_ord_flag defGhcFlag "dep-suffix"              (hasArg addDepSuffix)
+  , make_ord_flag defGhcFlag "dep-makefile"            (hasArg setDepMakefile)
+  , make_ord_flag defGhcFlag "include-pkg-deps"
+        (noArg (setDepIncludePkgDeps True))
+  , make_ord_flag defGhcFlag "exclude-module"          (hasArg addDepExcludeMod)
 
         -------- Linking ----------------------------------------------------
-  , defGhcFlag "no-link"            (noArg (\d -> d{ ghcLink=NoLink }))
-  , defGhcFlag "shared"             (noArg (\d -> d{ ghcLink=LinkDynLib }))
-  , defGhcFlag "staticlib"          (noArg (\d -> d{ ghcLink=LinkStaticLib }))
-  , defGhcFlag "dynload"            (hasArg parseDynLibLoaderMode)
-  , defGhcFlag "dylib-install-name" (hasArg setDylibInstallName)
+  , make_ord_flag defGhcFlag "no-link"
+        (noArg (\d -> d { ghcLink=NoLink }))
+  , make_ord_flag defGhcFlag "shared"
+        (noArg (\d -> d { ghcLink=LinkDynLib }))
+  , make_ord_flag defGhcFlag "staticlib"
+        (noArg (\d -> d { ghcLink=LinkStaticLib }))
+  , make_ord_flag defGhcFlag "dynload"            (hasArg parseDynLibLoaderMode)
+  , make_ord_flag defGhcFlag "dylib-install-name" (hasArg setDylibInstallName)
     -- -dll-split is an internal flag, used only during the GHC build
-  , defHiddenFlag "dll-split"
-      (hasArg (\f d -> d{ dllSplitFile = Just f, dllSplit = Nothing }))
+  , make_ord_flag defHiddenFlag "dll-split"
+      (hasArg (\f d -> d { dllSplitFile = Just f, dllSplit = Nothing }))
 
         ------- Libraries ---------------------------------------------------
-  , defFlag "L"   (Prefix addLibraryPath)
-  , defFlag "l"   (hasArg (addLdInputs . Option . ("-l" ++)))
+  , make_ord_flag defFlag "L"   (Prefix addLibraryPath)
+  , make_ord_flag defFlag "l"   (hasArg (addLdInputs . Option . ("-l" ++)))
 
         ------- Frameworks --------------------------------------------------
         -- -framework-path should really be -F ...
-  , defFlag "framework-path" (HasArg addFrameworkPath)
-  , defFlag "framework"      (hasArg addCmdlineFramework)
+  , make_ord_flag defFlag "framework-path" (HasArg addFrameworkPath)
+  , make_ord_flag defFlag "framework"      (hasArg addCmdlineFramework)
 
         ------- Output Redirection ------------------------------------------
-  , defGhcFlag "odir"              (hasArg setObjectDir)
-  , defGhcFlag "o"                 (sepArg (setOutputFile . Just))
-  , defGhcFlag "dyno"              (sepArg (setDynOutputFile . Just))
-  , defGhcFlag "ohi"               (hasArg (setOutputHi . Just ))
-  , defGhcFlag "osuf"              (hasArg setObjectSuf)
-  , defGhcFlag "dynosuf"           (hasArg setDynObjectSuf)
-  , defGhcFlag "hcsuf"             (hasArg setHcSuf)
-  , defGhcFlag "hisuf"             (hasArg setHiSuf)
-  , defGhcFlag "dynhisuf"          (hasArg setDynHiSuf)
-  , defGhcFlag "hidir"             (hasArg setHiDir)
-  , defGhcFlag "tmpdir"            (hasArg setTmpDir)
-  , defGhcFlag "stubdir"           (hasArg setStubDir)
-  , defGhcFlag "dumpdir"           (hasArg setDumpDir)
-  , defGhcFlag "outputdir"         (hasArg setOutputDir)
-  , defGhcFlag "ddump-file-prefix" (hasArg (setDumpPrefixForce . Just))
-
-  , defGhcFlag "dynamic-too"       (NoArg (setGeneralFlag Opt_BuildDynamicToo))
+  , make_ord_flag defGhcFlag "odir"              (hasArg setObjectDir)
+  , make_ord_flag defGhcFlag "o"                 (sepArg (setOutputFile . Just))
+  , make_ord_flag defGhcFlag "dyno"
+        (sepArg (setDynOutputFile . Just))
+  , make_ord_flag defGhcFlag "ohi"
+        (hasArg (setOutputHi . Just ))
+  , make_ord_flag defGhcFlag "osuf"              (hasArg setObjectSuf)
+  , 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 "dynhisuf"          (hasArg setDynHiSuf)
+  , make_ord_flag defGhcFlag "hidir"             (hasArg setHiDir)
+  , make_ord_flag defGhcFlag "tmpdir"            (hasArg setTmpDir)
+  , make_ord_flag defGhcFlag "stubdir"           (hasArg setStubDir)
+  , make_ord_flag defGhcFlag "dumpdir"           (hasArg setDumpDir)
+  , make_ord_flag defGhcFlag "outputdir"         (hasArg setOutputDir)
+  , make_ord_flag defGhcFlag "ddump-file-prefix"
+        (hasArg (setDumpPrefixForce . Just))
+
+  , make_ord_flag defGhcFlag "dynamic-too"
+        (NoArg (setGeneralFlag Opt_BuildDynamicToo))
 
         ------- Keeping temporary files -------------------------------------
      -- These can be singular (think ghc -c) or plural (think ghc --make)
-  , defGhcFlag "keep-hc-file"     (NoArg (setGeneralFlag Opt_KeepHcFiles))
-  , defGhcFlag "keep-hc-files"    (NoArg (setGeneralFlag Opt_KeepHcFiles))
-  , defGhcFlag "keep-s-file"      (NoArg (setGeneralFlag Opt_KeepSFiles))
-  , defGhcFlag "keep-s-files"     (NoArg (setGeneralFlag Opt_KeepSFiles))
-  , defGhcFlag "keep-llvm-file"   (NoArg (do setObjTarget HscLlvm
-                                             setGeneralFlag Opt_KeepLlvmFiles))
-  , defGhcFlag "keep-llvm-files"  (NoArg (do setObjTarget HscLlvm
-                                             setGeneralFlag Opt_KeepLlvmFiles))
+  , make_ord_flag defGhcFlag "keep-hc-file"
+        (NoArg (setGeneralFlag Opt_KeepHcFiles))
+  , make_ord_flag defGhcFlag "keep-hc-files"
+        (NoArg (setGeneralFlag Opt_KeepHcFiles))
+  , make_ord_flag defGhcFlag "keep-s-file"
+        (NoArg (setGeneralFlag Opt_KeepSFiles))
+  , make_ord_flag defGhcFlag "keep-s-files"
+        (NoArg (setGeneralFlag Opt_KeepSFiles))
+  , make_ord_flag defGhcFlag "keep-llvm-file"
+        (NoArg $ setObjTarget HscLlvm >> setGeneralFlag Opt_KeepLlvmFiles)
+  , make_ord_flag defGhcFlag "keep-llvm-files"
+        (NoArg $ setObjTarget HscLlvm >> setGeneralFlag Opt_KeepLlvmFiles)
      -- This only makes sense as plural
-  , defGhcFlag "keep-tmp-files"   (NoArg (setGeneralFlag Opt_KeepTmpFiles))
+  , make_ord_flag defGhcFlag "keep-tmp-files"
+        (NoArg (setGeneralFlag Opt_KeepTmpFiles))
+  , make_ord_flag defGhcFlag "keep-hi-file"
+        (NoArg (setGeneralFlag Opt_KeepHiFiles))
+  , make_ord_flag defGhcFlag "no-keep-hi-file"
+        (NoArg (unSetGeneralFlag Opt_KeepHiFiles))
+  , make_ord_flag defGhcFlag "keep-hi-files"
+        (NoArg (setGeneralFlag Opt_KeepHiFiles))
+  , make_ord_flag defGhcFlag "no-keep-hi-files"
+        (NoArg (unSetGeneralFlag Opt_KeepHiFiles))
+  , make_ord_flag defGhcFlag "keep-o-file"
+        (NoArg (setGeneralFlag Opt_KeepOFiles))
+  , make_ord_flag defGhcFlag "no-keep-o-file"
+        (NoArg (unSetGeneralFlag Opt_KeepOFiles))
+  , make_ord_flag defGhcFlag "keep-o-files"
+        (NoArg (setGeneralFlag Opt_KeepOFiles))
+  , make_ord_flag defGhcFlag "no-keep-o-files"
+        (NoArg (unSetGeneralFlag Opt_KeepOFiles))
 
         ------- Miscellaneous ----------------------------------------------
-  , defGhcFlag "no-auto-link-packages"
-      (NoArg (unSetGeneralFlag Opt_AutoLinkPackages))
-  , defGhcFlag "no-hs-main"     (NoArg (setGeneralFlag Opt_NoHsMain))
-  , defGhcFlag "with-rtsopts"   (HasArg setRtsOpts)
-  , defGhcFlag "rtsopts"        (NoArg (setRtsOptsEnabled RtsOptsAll))
-  , defGhcFlag "rtsopts=all"    (NoArg (setRtsOptsEnabled RtsOptsAll))
-  , defGhcFlag "rtsopts=some"   (NoArg (setRtsOptsEnabled RtsOptsSafeOnly))
-  , defGhcFlag "rtsopts=none"   (NoArg (setRtsOptsEnabled RtsOptsNone))
-  , defGhcFlag "no-rtsopts"     (NoArg (setRtsOptsEnabled RtsOptsNone))
-  , defGhcFlag "main-is"        (SepArg setMainIs)
-  , defGhcFlag "haddock"        (NoArg (setGeneralFlag Opt_Haddock))
-  , defGhcFlag "haddock-opts"   (hasArg addHaddockOpts)
-  , defGhcFlag "hpcdir"         (SepArg setOptHpcDir)
-  , defGhciFlag "ghci-script"    (hasArg addGhciScript)
-  , defGhciFlag "interactive-print" (hasArg setInteractivePrint)
-  , defGhcFlag "ticky-allocd"      (NoArg (setGeneralFlag Opt_Ticky_Allocd))
-  , defGhcFlag "ticky-LNE"         (NoArg (setGeneralFlag Opt_Ticky_LNE))
-  , defGhcFlag "ticky-dyn-thunk"   (NoArg (setGeneralFlag Opt_Ticky_Dyn_Thunk))
+  , make_ord_flag defGhcFlag "no-auto-link-packages"
+        (NoArg (unSetGeneralFlag Opt_AutoLinkPackages))
+  , make_ord_flag defGhcFlag "no-hs-main"
+        (NoArg (setGeneralFlag Opt_NoHsMain))
+  , make_ord_flag defGhcFlag "with-rtsopts"
+        (HasArg setRtsOpts)
+  , make_ord_flag defGhcFlag "rtsopts"
+        (NoArg (setRtsOptsEnabled RtsOptsAll))
+  , make_ord_flag defGhcFlag "rtsopts=all"
+        (NoArg (setRtsOptsEnabled RtsOptsAll))
+  , make_ord_flag defGhcFlag "rtsopts=some"
+        (NoArg (setRtsOptsEnabled RtsOptsSafeOnly))
+  , make_ord_flag defGhcFlag "rtsopts=none"
+        (NoArg (setRtsOptsEnabled RtsOptsNone))
+  , make_ord_flag defGhcFlag "no-rtsopts"
+        (NoArg (setRtsOptsEnabled RtsOptsNone))
+  , make_ord_flag defGhcFlag "no-rtsopts-suggestions"
+      (noArg (\d -> d {rtsOptsSuggestions = False}))
+
+  , make_ord_flag defGhcFlag "main-is"              (SepArg setMainIs)
+  , make_ord_flag defGhcFlag "haddock"              (NoArg (setGeneralFlag Opt_Haddock))
+  , make_ord_flag defGhcFlag "haddock-opts"         (hasArg addHaddockOpts)
+  , make_ord_flag defGhcFlag "hpcdir"               (SepArg setOptHpcDir)
+  , make_ord_flag defGhciFlag "ghci-script"         (hasArg addGhciScript)
+  , make_ord_flag defGhciFlag "interactive-print"   (hasArg setInteractivePrint)
+  , make_ord_flag defGhcFlag "ticky-allocd"
+        (NoArg (setGeneralFlag Opt_Ticky_Allocd))
+  , make_ord_flag defGhcFlag "ticky-LNE"
+        (NoArg (setGeneralFlag Opt_Ticky_LNE))
+  , make_ord_flag defGhcFlag "ticky-dyn-thunk"
+        (NoArg (setGeneralFlag Opt_Ticky_Dyn_Thunk))
         ------- recompilation checker --------------------------------------
-  , defGhcFlag "recomp"   (NoArg (do unSetGeneralFlag Opt_ForceRecomp
-                                     deprecate "Use -fno-force-recomp instead"))
-  , defGhcFlag "no-recomp" (NoArg (do setGeneralFlag Opt_ForceRecomp
-                                      deprecate "Use -fforce-recomp instead"))
+  , make_dep_flag defGhcFlag "recomp"
+        (NoArg $ unSetGeneralFlag Opt_ForceRecomp)
+             "Use -fno-force-recomp instead"
+  , make_dep_flag defGhcFlag "no-recomp"
+        (NoArg $ setGeneralFlag Opt_ForceRecomp) "Use -fforce-recomp instead"
+  , make_ord_flag defFlag "freverse-errors"
+        (noArg (\d -> d {reverseErrors = True} ))
+  , make_ord_flag defFlag "fno-reverse-errors"
+        (noArg (\d -> d {reverseErrors = False} ))
 
         ------ HsCpp opts ---------------------------------------------------
-  , defFlag "D"              (AnySuffix (upd . addOptP))
-  , defFlag "U"              (AnySuffix (upd . addOptP))
+  , make_ord_flag defFlag "D"              (AnySuffix (upd . addOptP))
+  , make_ord_flag defFlag "U"              (AnySuffix (upd . addOptP))
 
         ------- Include/Import Paths ----------------------------------------
-  , defFlag "I"              (Prefix    addIncludePath)
-  , defFlag "i"              (OptPrefix addImportPath)
+  , make_ord_flag defFlag "I"              (Prefix    addIncludePath)
+  , make_ord_flag defFlag "i"              (OptPrefix addImportPath)
 
         ------ Output style options -----------------------------------------
-  , defFlag "dppr-user-length" (intSuffix (\n d -> d{ pprUserLength = n }))
-  , defFlag "dppr-cols"        (intSuffix (\n d -> d{ pprCols = n }))
-  , defGhcFlag "dtrace-level"  (intSuffix (\n d -> d{ traceLevel = n }))
+  , make_ord_flag defFlag "dppr-user-length" (intSuffix (\n d ->
+                                                       d { pprUserLength = n }))
+  , make_ord_flag defFlag "dppr-cols"        (intSuffix (\n d ->
+                                                             d { pprCols = n }))
+  , make_ord_flag defFlag "fdiagnostics-color=auto"
+      (NoArg (upd (\d -> d { useColor = Auto })))
+  , make_ord_flag defFlag "fdiagnostics-color=always"
+      (NoArg (upd (\d -> d { useColor = Always })))
+  , make_ord_flag defFlag "fdiagnostics-color=never"
+      (NoArg (upd (\d -> d { useColor = Never })))
+
   -- Suppress all that is suppressable in core dumps.
-  -- Except for uniques, as some simplifier phases introduce new varibles that
+  -- Except for uniques, as some simplifier phases introduce new variables that
   -- have otherwise identical names.
-  , defGhcFlag "dsuppress-all"
+  , make_ord_flag defGhcFlag "dsuppress-all"
       (NoArg $ do setGeneralFlag Opt_SuppressCoercions
                   setGeneralFlag Opt_SuppressVarKinds
                   setGeneralFlag Opt_SuppressModulePrefixes
@@ -2431,325 +2806,502 @@ dynamic_flags = [
                   setGeneralFlag Opt_SuppressTypeSignatures)
 
         ------ Debugging ----------------------------------------------------
-  , defGhcFlag "dstg-stats"              (NoArg (setGeneralFlag Opt_StgStats))
-
-  , defGhcFlag "ddump-cmm"               (setDumpFlag Opt_D_dump_cmm)
-  , defGhcFlag "ddump-cmm-raw"           (setDumpFlag Opt_D_dump_cmm_raw)
-  , defGhcFlag "ddump-cmm-cfg"           (setDumpFlag Opt_D_dump_cmm_cfg)
-  , defGhcFlag "ddump-cmm-cbe"           (setDumpFlag Opt_D_dump_cmm_cbe)
-  , defGhcFlag "ddump-cmm-switch"        (setDumpFlag Opt_D_dump_cmm_switch)
-  , defGhcFlag "ddump-cmm-proc"          (setDumpFlag Opt_D_dump_cmm_proc)
-  , defGhcFlag "ddump-cmm-sink"          (setDumpFlag Opt_D_dump_cmm_sink)
-  , defGhcFlag "ddump-cmm-sp"            (setDumpFlag Opt_D_dump_cmm_sp)
-  , defGhcFlag "ddump-cmm-procmap"       (setDumpFlag Opt_D_dump_cmm_procmap)
-  , defGhcFlag "ddump-cmm-split"         (setDumpFlag Opt_D_dump_cmm_split)
-  , defGhcFlag "ddump-cmm-info"          (setDumpFlag Opt_D_dump_cmm_info)
-  , defGhcFlag "ddump-cmm-cps"           (setDumpFlag Opt_D_dump_cmm_cps)
-  , defGhcFlag "ddump-core-stats"        (setDumpFlag Opt_D_dump_core_stats)
-  , defGhcFlag "ddump-asm"               (setDumpFlag Opt_D_dump_asm)
-  , defGhcFlag "ddump-asm-native"        (setDumpFlag Opt_D_dump_asm_native)
-  , defGhcFlag "ddump-asm-liveness"      (setDumpFlag Opt_D_dump_asm_liveness)
-  , defGhcFlag "ddump-asm-regalloc"      (setDumpFlag Opt_D_dump_asm_regalloc)
-  , defGhcFlag "ddump-asm-conflicts"     (setDumpFlag Opt_D_dump_asm_conflicts)
-  , defGhcFlag "ddump-asm-regalloc-stages"
-      (setDumpFlag Opt_D_dump_asm_regalloc_stages)
-  , defGhcFlag "ddump-asm-stats"         (setDumpFlag Opt_D_dump_asm_stats)
-  , defGhcFlag "ddump-asm-expanded"      (setDumpFlag Opt_D_dump_asm_expanded)
-  , defGhcFlag "ddump-llvm"            (NoArg (do setObjTarget HscLlvm
-                                                  setDumpFlag' Opt_D_dump_llvm))
-  , defGhcFlag "ddump-deriv"             (setDumpFlag Opt_D_dump_deriv)
-  , defGhcFlag "ddump-ds"                (setDumpFlag Opt_D_dump_ds)
-  , defGhcFlag "ddump-foreign"           (setDumpFlag Opt_D_dump_foreign)
-  , defGhcFlag "ddump-inlinings"         (setDumpFlag Opt_D_dump_inlinings)
-  , defGhcFlag "ddump-rule-firings"      (setDumpFlag Opt_D_dump_rule_firings)
-  , defGhcFlag "ddump-rule-rewrites"     (setDumpFlag Opt_D_dump_rule_rewrites)
-  , defGhcFlag "ddump-simpl-trace"       (setDumpFlag Opt_D_dump_simpl_trace)
-  , defGhcFlag "ddump-occur-anal"        (setDumpFlag Opt_D_dump_occur_anal)
-  , defGhcFlag "ddump-parsed"            (setDumpFlag Opt_D_dump_parsed)
-  , defGhcFlag "ddump-rn"                (setDumpFlag Opt_D_dump_rn)
-  , defGhcFlag "ddump-simpl"             (setDumpFlag Opt_D_dump_simpl)
-  , defGhcFlag "ddump-simpl-iterations"
+  , make_ord_flag defGhcFlag "dstg-stats"
+        (NoArg (setGeneralFlag Opt_StgStats))
+
+  , make_ord_flag defGhcFlag "ddump-cmm"
+        (setDumpFlag Opt_D_dump_cmm)
+  , make_ord_flag defGhcFlag "ddump-cmm-from-stg"
+        (setDumpFlag Opt_D_dump_cmm_from_stg)
+  , make_ord_flag defGhcFlag "ddump-cmm-raw"
+        (setDumpFlag Opt_D_dump_cmm_raw)
+  , make_ord_flag defGhcFlag "ddump-cmm-verbose"
+        (setDumpFlag Opt_D_dump_cmm_verbose)
+  , make_ord_flag defGhcFlag "ddump-cmm-cfg"
+        (setDumpFlag Opt_D_dump_cmm_cfg)
+  , make_ord_flag defGhcFlag "ddump-cmm-cbe"
+        (setDumpFlag Opt_D_dump_cmm_cbe)
+  , make_ord_flag defGhcFlag "ddump-cmm-switch"
+        (setDumpFlag Opt_D_dump_cmm_switch)
+  , make_ord_flag defGhcFlag "ddump-cmm-proc"
+        (setDumpFlag Opt_D_dump_cmm_proc)
+  , make_ord_flag defGhcFlag "ddump-cmm-sp"
+        (setDumpFlag Opt_D_dump_cmm_sp)
+  , make_ord_flag defGhcFlag "ddump-cmm-sink"
+        (setDumpFlag Opt_D_dump_cmm_sink)
+  , make_ord_flag defGhcFlag "ddump-cmm-caf"
+        (setDumpFlag Opt_D_dump_cmm_caf)
+  , make_ord_flag defGhcFlag "ddump-cmm-procmap"
+        (setDumpFlag Opt_D_dump_cmm_procmap)
+  , make_ord_flag defGhcFlag "ddump-cmm-split"
+        (setDumpFlag Opt_D_dump_cmm_split)
+  , make_ord_flag defGhcFlag "ddump-cmm-info"
+        (setDumpFlag Opt_D_dump_cmm_info)
+  , make_ord_flag defGhcFlag "ddump-cmm-cps"
+        (setDumpFlag Opt_D_dump_cmm_cps)
+  , make_ord_flag defGhcFlag "ddump-core-stats"
+        (setDumpFlag Opt_D_dump_core_stats)
+  , make_ord_flag defGhcFlag "ddump-asm"
+        (setDumpFlag Opt_D_dump_asm)
+  , make_ord_flag defGhcFlag "ddump-asm-native"
+        (setDumpFlag Opt_D_dump_asm_native)
+  , make_ord_flag defGhcFlag "ddump-asm-liveness"
+        (setDumpFlag Opt_D_dump_asm_liveness)
+  , make_ord_flag defGhcFlag "ddump-asm-regalloc"
+        (setDumpFlag Opt_D_dump_asm_regalloc)
+  , make_ord_flag defGhcFlag "ddump-asm-conflicts"
+        (setDumpFlag Opt_D_dump_asm_conflicts)
+  , make_ord_flag defGhcFlag "ddump-asm-regalloc-stages"
+        (setDumpFlag Opt_D_dump_asm_regalloc_stages)
+  , make_ord_flag defGhcFlag "ddump-asm-stats"
+        (setDumpFlag Opt_D_dump_asm_stats)
+  , make_ord_flag defGhcFlag "ddump-asm-expanded"
+        (setDumpFlag Opt_D_dump_asm_expanded)
+  , make_ord_flag defGhcFlag "ddump-llvm"
+        (NoArg $ setObjTarget HscLlvm >> setDumpFlag' Opt_D_dump_llvm)
+  , make_ord_flag defGhcFlag "ddump-deriv"
+        (setDumpFlag Opt_D_dump_deriv)
+  , make_ord_flag defGhcFlag "ddump-ds"
+        (setDumpFlag Opt_D_dump_ds)
+  , make_ord_flag defGhcFlag "ddump-foreign"
+        (setDumpFlag Opt_D_dump_foreign)
+  , make_ord_flag defGhcFlag "ddump-inlinings"
+        (setDumpFlag Opt_D_dump_inlinings)
+  , make_ord_flag defGhcFlag "ddump-rule-firings"
+        (setDumpFlag Opt_D_dump_rule_firings)
+  , make_ord_flag defGhcFlag "ddump-rule-rewrites"
+        (setDumpFlag Opt_D_dump_rule_rewrites)
+  , make_ord_flag defGhcFlag "ddump-simpl-trace"
+        (setDumpFlag Opt_D_dump_simpl_trace)
+  , make_ord_flag defGhcFlag "ddump-occur-anal"
+        (setDumpFlag Opt_D_dump_occur_anal)
+  , make_ord_flag defGhcFlag "ddump-parsed"
+        (setDumpFlag Opt_D_dump_parsed)
+  , make_ord_flag defGhcFlag "ddump-parsed-ast"
+        (setDumpFlag Opt_D_dump_parsed_ast)
+  , make_ord_flag defGhcFlag "ddump-rn"
+        (setDumpFlag Opt_D_dump_rn)
+  , make_ord_flag defGhcFlag "ddump-simpl"
+        (setDumpFlag Opt_D_dump_simpl)
+  , make_ord_flag defGhcFlag "ddump-simpl-iterations"
       (setDumpFlag Opt_D_dump_simpl_iterations)
-  , defGhcFlag "ddump-spec"              (setDumpFlag Opt_D_dump_spec)
-  , defGhcFlag "ddump-prep"              (setDumpFlag Opt_D_dump_prep)
-  , defGhcFlag "ddump-stg"               (setDumpFlag Opt_D_dump_stg)
-  , defGhcFlag "ddump-call-arity"        (setDumpFlag Opt_D_dump_call_arity)
-  , defGhcFlag "ddump-stranal"           (setDumpFlag Opt_D_dump_stranal)
-  , defGhcFlag "ddump-strsigs"           (setDumpFlag Opt_D_dump_strsigs)
-  , defGhcFlag "ddump-tc"                (setDumpFlag Opt_D_dump_tc)
-  , defGhcFlag "ddump-types"             (setDumpFlag Opt_D_dump_types)
-  , defGhcFlag "ddump-rules"             (setDumpFlag Opt_D_dump_rules)
-  , defGhcFlag "ddump-cse"               (setDumpFlag Opt_D_dump_cse)
-  , defGhcFlag "ddump-worker-wrapper"    (setDumpFlag Opt_D_dump_worker_wrapper)
-  , defGhcFlag "ddump-rn-trace"          (setDumpFlag Opt_D_dump_rn_trace)
-  , defGhcFlag "ddump-if-trace"          (setDumpFlag Opt_D_dump_if_trace)
-  , defGhcFlag "ddump-cs-trace"          (setDumpFlag Opt_D_dump_cs_trace)
-  , defGhcFlag "ddump-tc-trace"          (NoArg (do
-                                            setDumpFlag' Opt_D_dump_tc_trace
-                                            setDumpFlag' Opt_D_dump_cs_trace))
-  , defGhcFlag "ddump-vt-trace"          (setDumpFlag Opt_D_dump_vt_trace)
-  , defGhcFlag "ddump-splices"           (setDumpFlag Opt_D_dump_splices)
-  , defGhcFlag "dth-dec-file"            (setDumpFlag Opt_D_th_dec_file)
-
-  , defGhcFlag "ddump-rn-stats"          (setDumpFlag Opt_D_dump_rn_stats)
-  , defGhcFlag "ddump-opt-cmm"           (setDumpFlag Opt_D_dump_opt_cmm)
-  , defGhcFlag "ddump-simpl-stats"       (setDumpFlag Opt_D_dump_simpl_stats)
-  , defGhcFlag "ddump-bcos"              (setDumpFlag Opt_D_dump_BCOs)
-  , defGhcFlag "dsource-stats"           (setDumpFlag Opt_D_source_stats)
-  , defGhcFlag "dverbose-core2core"      (NoArg (do setVerbosity (Just 2)
-                                                    setVerboseCore2Core))
-  , defGhcFlag "dverbose-stg2stg"        (setDumpFlag Opt_D_verbose_stg2stg)
-  , defGhcFlag "ddump-hi"                (setDumpFlag Opt_D_dump_hi)
-  , defGhcFlag "ddump-minimal-imports"
-      (NoArg (setGeneralFlag Opt_D_dump_minimal_imports))
-  , defGhcFlag "ddump-vect"              (setDumpFlag Opt_D_dump_vect)
-  , defGhcFlag "ddump-hpc"
-      (setDumpFlag Opt_D_dump_ticked) -- back compat
-  , defGhcFlag "ddump-ticked"            (setDumpFlag Opt_D_dump_ticked)
-  , defGhcFlag "ddump-mod-cycles"        (setDumpFlag Opt_D_dump_mod_cycles)
-  , defGhcFlag "ddump-mod-map"           (setDumpFlag Opt_D_dump_mod_map)
-  , defGhcFlag "ddump-view-pattern-commoning"
-      (setDumpFlag Opt_D_dump_view_pattern_commoning)
-  , defGhcFlag "ddump-to-file"           (NoArg (setGeneralFlag Opt_DumpToFile))
-  , defGhcFlag "ddump-hi-diffs"          (setDumpFlag Opt_D_dump_hi_diffs)
-  , defGhcFlag "ddump-rtti"              (setDumpFlag Opt_D_dump_rtti)
-  , defGhcFlag "dcore-lint"
-      (NoArg (setGeneralFlag Opt_DoCoreLinting))
-  , defGhcFlag "dstg-lint"
-      (NoArg (setGeneralFlag Opt_DoStgLinting))
-  , defGhcFlag "dcmm-lint"
-      (NoArg (setGeneralFlag Opt_DoCmmLinting))
-  , defGhcFlag "dasm-lint"
-      (NoArg (setGeneralFlag Opt_DoAsmLinting))
-  , defGhcFlag "dannot-lint"
-      (NoArg (setGeneralFlag Opt_DoAnnotationLinting))
-  , defGhcFlag "dshow-passes"            (NoArg (do forceRecompile
-                                                    setVerbosity $ Just 2))
-  , defGhcFlag "dfaststring-stats"
-      (NoArg (setGeneralFlag Opt_D_faststring_stats))
-  , defGhcFlag "dno-llvm-mangler"
-      (NoArg (setGeneralFlag Opt_NoLlvmMangler)) -- hidden flag
-  , defGhcFlag "ddump-debug"             (setDumpFlag Opt_D_dump_debug)
-
-        ------ Machine dependant (-m<blah>) stuff ---------------------------
-
-  , defGhcFlag "msse"         (noArg (\d -> d{ sseVersion = Just SSE1 }))
-  , defGhcFlag "msse2"        (noArg (\d -> d{ sseVersion = Just SSE2 }))
-  , defGhcFlag "msse3"        (noArg (\d -> d{ sseVersion = Just SSE3 }))
-  , defGhcFlag "msse4"        (noArg (\d -> d{ sseVersion = Just SSE4 }))
-  , defGhcFlag "msse4.2"      (noArg (\d -> d{ sseVersion = Just SSE42 }))
-  , defGhcFlag "mavx"         (noArg (\d -> d{ avx = True }))
-  , defGhcFlag "mavx2"        (noArg (\d -> d{ avx2 = True }))
-  , defGhcFlag "mavx512cd"    (noArg (\d -> d{ avx512cd = True }))
-  , defGhcFlag "mavx512er"    (noArg (\d -> d{ avx512er = True }))
-  , defGhcFlag "mavx512f"     (noArg (\d -> d{ avx512f = True }))
-  , defGhcFlag "mavx512pf"    (noArg (\d -> d{ avx512pf = True }))
+  , make_ord_flag defGhcFlag "ddump-spec"
+        (setDumpFlag Opt_D_dump_spec)
+  , make_ord_flag defGhcFlag "ddump-prep"
+        (setDumpFlag Opt_D_dump_prep)
+  , make_ord_flag defGhcFlag "ddump-stg"
+        (setDumpFlag Opt_D_dump_stg)
+  , make_ord_flag defGhcFlag "ddump-call-arity"
+        (setDumpFlag Opt_D_dump_call_arity)
+  , make_ord_flag defGhcFlag "ddump-stranal"
+        (setDumpFlag Opt_D_dump_stranal)
+  , make_ord_flag defGhcFlag "ddump-str-signatures"
+        (setDumpFlag Opt_D_dump_str_signatures)
+  , make_ord_flag defGhcFlag "ddump-tc"
+        (setDumpFlag Opt_D_dump_tc)
+  , make_ord_flag defGhcFlag "ddump-types"
+        (setDumpFlag Opt_D_dump_types)
+  , make_ord_flag defGhcFlag "ddump-rules"
+        (setDumpFlag Opt_D_dump_rules)
+  , make_ord_flag defGhcFlag "ddump-cse"
+        (setDumpFlag Opt_D_dump_cse)
+  , make_ord_flag defGhcFlag "ddump-worker-wrapper"
+        (setDumpFlag Opt_D_dump_worker_wrapper)
+  , make_ord_flag defGhcFlag "ddump-rn-trace"
+        (setDumpFlag Opt_D_dump_rn_trace)
+  , make_ord_flag defGhcFlag "ddump-shape"
+        (setDumpFlag Opt_D_dump_shape)
+  , make_ord_flag defGhcFlag "ddump-if-trace"
+        (setDumpFlag Opt_D_dump_if_trace)
+  , make_ord_flag defGhcFlag "ddump-cs-trace"
+        (setDumpFlag Opt_D_dump_cs_trace)
+  , make_ord_flag defGhcFlag "ddump-tc-trace"
+        (NoArg (do setDumpFlag' Opt_D_dump_tc_trace
+                   setDumpFlag' Opt_D_dump_cs_trace))
+  , make_ord_flag defGhcFlag "ddump-ec-trace"
+        (setDumpFlag Opt_D_dump_ec_trace)
+  , make_ord_flag defGhcFlag "ddump-vt-trace"
+        (setDumpFlag Opt_D_dump_vt_trace)
+  , make_ord_flag defGhcFlag "ddump-splices"
+        (setDumpFlag Opt_D_dump_splices)
+  , make_ord_flag defGhcFlag "dth-dec-file"
+        (setDumpFlag Opt_D_th_dec_file)
+
+  , make_ord_flag defGhcFlag "ddump-rn-stats"
+        (setDumpFlag Opt_D_dump_rn_stats)
+  , make_ord_flag defGhcFlag "ddump-opt-cmm"
+        (setDumpFlag Opt_D_dump_opt_cmm)
+  , make_ord_flag defGhcFlag "ddump-simpl-stats"
+        (setDumpFlag Opt_D_dump_simpl_stats)
+  , make_ord_flag defGhcFlag "ddump-bcos"
+        (setDumpFlag Opt_D_dump_BCOs)
+  , make_ord_flag defGhcFlag "dsource-stats"
+        (setDumpFlag Opt_D_source_stats)
+  , make_ord_flag defGhcFlag "dverbose-core2core"
+        (NoArg $ setVerbosity (Just 2) >> setVerboseCore2Core)
+  , make_ord_flag defGhcFlag "dverbose-stg2stg"
+        (setDumpFlag Opt_D_verbose_stg2stg)
+  , make_ord_flag defGhcFlag "ddump-hi"
+        (setDumpFlag Opt_D_dump_hi)
+  , make_ord_flag defGhcFlag "ddump-minimal-imports"
+        (NoArg (setGeneralFlag Opt_D_dump_minimal_imports))
+  , make_ord_flag defGhcFlag "ddump-vect"
+        (setDumpFlag Opt_D_dump_vect)
+  , make_ord_flag defGhcFlag "ddump-hpc"
+        (setDumpFlag Opt_D_dump_ticked) -- back compat
+  , make_ord_flag defGhcFlag "ddump-ticked"
+        (setDumpFlag Opt_D_dump_ticked)
+  , make_ord_flag defGhcFlag "ddump-mod-cycles"
+        (setDumpFlag Opt_D_dump_mod_cycles)
+  , make_ord_flag defGhcFlag "ddump-mod-map"
+        (setDumpFlag Opt_D_dump_mod_map)
+  , make_ord_flag defGhcFlag "ddump-view-pattern-commoning"
+        (setDumpFlag Opt_D_dump_view_pattern_commoning)
+  , make_ord_flag defGhcFlag "ddump-to-file"
+        (NoArg (setGeneralFlag Opt_DumpToFile))
+  , make_ord_flag defGhcFlag "ddump-hi-diffs"
+        (setDumpFlag Opt_D_dump_hi_diffs)
+  , make_ord_flag defGhcFlag "ddump-rtti"
+        (setDumpFlag Opt_D_dump_rtti)
+  , make_ord_flag defGhcFlag "dcore-lint"
+        (NoArg (setGeneralFlag Opt_DoCoreLinting))
+  , make_ord_flag defGhcFlag "dstg-lint"
+        (NoArg (setGeneralFlag Opt_DoStgLinting))
+  , make_ord_flag defGhcFlag "dcmm-lint"
+        (NoArg (setGeneralFlag Opt_DoCmmLinting))
+  , make_ord_flag defGhcFlag "dasm-lint"
+        (NoArg (setGeneralFlag Opt_DoAsmLinting))
+  , make_ord_flag defGhcFlag "dannot-lint"
+        (NoArg (setGeneralFlag Opt_DoAnnotationLinting))
+  , make_ord_flag defGhcFlag "dshow-passes"
+        (NoArg $ forceRecompile >> (setVerbosity $ Just 2))
+  , make_ord_flag defGhcFlag "dfaststring-stats"
+        (NoArg (setGeneralFlag Opt_D_faststring_stats))
+  , make_ord_flag defGhcFlag "dno-llvm-mangler"
+        (NoArg (setGeneralFlag Opt_NoLlvmMangler)) -- hidden flag
+  , make_ord_flag defGhcFlag "ddump-debug"        (setDumpFlag Opt_D_dump_debug)
+
+  , make_ord_flag defGhcFlag "ddump-json"
+        (noArg (flip dopt_set Opt_D_dump_json . setJsonLogAction ) )
+
+        ------ Machine dependent (-m<blah>) stuff ---------------------------
+
+  , make_ord_flag defGhcFlag "msse"         (noArg (\d ->
+                                                  d { sseVersion = Just SSE1 }))
+  , make_ord_flag defGhcFlag "msse2"        (noArg (\d ->
+                                                  d { sseVersion = Just SSE2 }))
+  , make_ord_flag defGhcFlag "msse3"        (noArg (\d ->
+                                                  d { sseVersion = Just SSE3 }))
+  , make_ord_flag defGhcFlag "msse4"        (noArg (\d ->
+                                                  d { sseVersion = Just SSE4 }))
+  , make_ord_flag defGhcFlag "msse4.2"      (noArg (\d ->
+                                                 d { sseVersion = Just SSE42 }))
+  , make_ord_flag defGhcFlag "mavx"         (noArg (\d -> d { avx = True }))
+  , make_ord_flag defGhcFlag "mavx2"        (noArg (\d -> d { avx2 = True }))
+  , make_ord_flag defGhcFlag "mavx512cd"    (noArg (\d ->
+                                                         d { avx512cd = True }))
+  , make_ord_flag defGhcFlag "mavx512er"    (noArg (\d ->
+                                                         d { avx512er = True }))
+  , make_ord_flag defGhcFlag "mavx512f"     (noArg (\d -> d { avx512f = True }))
+  , make_ord_flag defGhcFlag "mavx512pf"    (noArg (\d ->
+                                                         d { avx512pf = True }))
 
      ------ Warning opts -------------------------------------------------
-  , defFlag "W"      (NoArg (mapM_ setWarningFlag minusWOpts))
-  , defFlag "Werror" (NoArg (setGeneralFlag           Opt_WarnIsError))
-  , defFlag "Wwarn"  (NoArg (unSetGeneralFlag         Opt_WarnIsError))
-  , defFlag "Wall"   (NoArg (mapM_ setWarningFlag minusWallOpts))
-  , defFlag "Wnot"   (NoArg (do upd (\dfs -> dfs {warningFlags = IntSet.empty})
-                                deprecate "Use -w instead"))
-  , defFlag "w"      (NoArg (upd (\dfs -> dfs {warningFlags = IntSet.empty})))
+  , make_ord_flag defFlag "W"       (NoArg (mapM_ setWarningFlag minusWOpts))
+  , make_ord_flag defFlag "Werror"
+               (NoArg (do { setGeneralFlag Opt_WarnIsError
+                          ; mapM_ setFatalWarningFlag minusWeverythingOpts   }))
+  , make_ord_flag defFlag "Wwarn"
+               (NoArg (do { unSetGeneralFlag Opt_WarnIsError
+                          ; mapM_ unSetFatalWarningFlag minusWeverythingOpts }))
+                          -- Opt_WarnIsError is still needed to pass -Werror
+                          -- to CPP; see runCpp in SysTools
+  , make_dep_flag defFlag "Wnot"    (NoArg (upd (\d ->
+                                              d {warningFlags = IntSet.empty})))
+                                             "Use -w or -Wno-everything instead"
+  , make_ord_flag defFlag "w"       (NoArg (upd (\d ->
+                                              d {warningFlags = IntSet.empty})))
+
+     -- New-style uniform warning sets
+     --
+     -- Note that -Weverything > -Wall > -Wextra > -Wdefault > -Wno-everything
+  , make_ord_flag defFlag "Weverything"    (NoArg (mapM_
+                                           setWarningFlag minusWeverythingOpts))
+  , make_ord_flag defFlag "Wno-everything"
+                           (NoArg (upd (\d -> d {warningFlags = IntSet.empty})))
+
+  , make_ord_flag defFlag "Wall"           (NoArg (mapM_
+                                                  setWarningFlag minusWallOpts))
+  , make_ord_flag defFlag "Wno-all"        (NoArg (mapM_
+                                                unSetWarningFlag minusWallOpts))
+
+  , make_ord_flag defFlag "Wextra"         (NoArg (mapM_
+                                                     setWarningFlag minusWOpts))
+  , make_ord_flag defFlag "Wno-extra"      (NoArg (mapM_
+                                                   unSetWarningFlag minusWOpts))
+
+  , make_ord_flag defFlag "Wdefault"       (NoArg (mapM_
+                                               setWarningFlag standardWarnings))
+  , make_ord_flag defFlag "Wno-default"    (NoArg (mapM_
+                                             unSetWarningFlag standardWarnings))
+
+  , make_ord_flag defFlag "Wcompat"        (NoArg (mapM_
+                                               setWarningFlag minusWcompatOpts))
+  , make_ord_flag defFlag "Wno-compat"     (NoArg (mapM_
+                                             unSetWarningFlag minusWcompatOpts))
 
         ------ Plugin flags ------------------------------------------------
-  , defGhcFlag "fplugin-opt" (hasArg addPluginModuleNameOption)
-  , defGhcFlag "fplugin"     (hasArg addPluginModuleName)
+  , make_ord_flag defGhcFlag "fplugin-opt" (hasArg addPluginModuleNameOption)
+  , make_ord_flag defGhcFlag "fplugin"     (hasArg addPluginModuleName)
+  , make_ord_flag defGhcFlag "ffrontend-opt" (hasArg addFrontendPluginOption)
 
         ------ Optimisation flags ------------------------------------------
-  , defGhcFlag "O"      (noArgM (setOptLevel 1))
-  , defGhcFlag "Onot"   (noArgM (\dflags -> do deprecate "Use -O0 instead"
-                                               setOptLevel 0 dflags))
-  , defGhcFlag "Odph"   (noArgM setDPHOpt)
-  , defGhcFlag "O"      (optIntSuffixM (\mb_n -> setOptLevel (mb_n `orElse` 1)))
+  , make_ord_flag defGhcFlag "O"      (noArgM (setOptLevel 1))
+  , make_dep_flag defGhcFlag "Onot"   (noArgM $ setOptLevel 0 )
+                                                            "Use -O0 instead"
+  , make_ord_flag defGhcFlag "Odph"   (noArgM setDPHOpt)
+  , make_ord_flag defGhcFlag "O"      (optIntSuffixM (\mb_n ->
+                                                setOptLevel (mb_n `orElse` 1)))
                 -- If the number is missing, use 1
 
 
-  , defFlag "fmax-relevant-binds"
-      (intSuffix (\n d -> d{ maxRelevantBinds = Just n }))
-  , defFlag "fno-max-relevant-binds"
-      (noArg (\d -> d{ maxRelevantBinds = Nothing }))
-  , defFlag "fsimplifier-phases"
-      (intSuffix (\n d -> d{ simplPhases = n }))
-  , defFlag "fmax-simplifier-iterations"
-      (intSuffix (\n d -> d{ maxSimplIterations = n }))
-  , defFlag "fsimpl-tick-factor"
-      (intSuffix (\n d -> d{ simplTickFactor = n }))
-  , defFlag "fspec-constr-threshold"
-      (intSuffix (\n d -> d{ specConstrThreshold = Just n }))
-  , defFlag "fno-spec-constr-threshold"
-      (noArg (\d -> d{ specConstrThreshold = Nothing }))
-  , defFlag "fspec-constr-count"
-      (intSuffix (\n d -> d{ specConstrCount = Just n }))
-  , defFlag "fno-spec-constr-count"
-      (noArg (\d -> d{ specConstrCount = Nothing }))
-  , defFlag "fspec-constr-recursive"
-      (intSuffix (\n d -> d{ specConstrRecursive = n }))
-  , defFlag "fliberate-case-threshold"
-      (intSuffix (\n d -> d{ liberateCaseThreshold = Just n }))
-  , defFlag "fno-liberate-case-threshold"
-      (noArg (\d -> d{ liberateCaseThreshold = Nothing }))
-  , defFlag "frule-check"
-      (sepArg (\s d -> d{ ruleCheck = Just s }))
-  , defFlag "freduction-depth"
-      (intSuffix (\n d -> d{ reductionDepth = treatZeroAsInf n }))
-  , defFlag "fcontext-stack"
+  , make_ord_flag defFlag "fmax-relevant-binds"
+      (intSuffix (\n d -> d { maxRelevantBinds = Just n }))
+  , make_ord_flag defFlag "fno-max-relevant-binds"
+      (noArg (\d -> d { maxRelevantBinds = Nothing }))
+  , make_ord_flag defFlag "fmax-uncovered-patterns"
+      (intSuffix (\n d -> d { maxUncoveredPatterns = n }))
+  , make_ord_flag defFlag "fsimplifier-phases"
+      (intSuffix (\n d -> d { simplPhases = n }))
+  , make_ord_flag defFlag "fmax-simplifier-iterations"
+      (intSuffix (\n d -> d { maxSimplIterations = n }))
+  , make_ord_flag defFlag "fmax-pmcheck-iterations"
+      (intSuffix (\n d -> d{ maxPmCheckIterations = n }))
+  , make_ord_flag defFlag "fsimpl-tick-factor"
+      (intSuffix (\n d -> d { simplTickFactor = n }))
+  , make_ord_flag defFlag "fspec-constr-threshold"
+      (intSuffix (\n d -> d { specConstrThreshold = Just n }))
+  , make_ord_flag defFlag "fno-spec-constr-threshold"
+      (noArg (\d -> d { specConstrThreshold = Nothing }))
+  , make_ord_flag defFlag "fspec-constr-count"
+      (intSuffix (\n d -> d { specConstrCount = Just n }))
+  , make_ord_flag defFlag "fno-spec-constr-count"
+      (noArg (\d -> d { specConstrCount = Nothing }))
+  , make_ord_flag defFlag "fspec-constr-recursive"
+      (intSuffix (\n d -> d { specConstrRecursive = n }))
+  , make_ord_flag defFlag "fliberate-case-threshold"
+      (intSuffix (\n d -> d { liberateCaseThreshold = Just n }))
+  , make_ord_flag defFlag "fno-liberate-case-threshold"
+      (noArg (\d -> d { liberateCaseThreshold = Nothing }))
+  , make_ord_flag defFlag "frule-check"
+      (sepArg (\s d -> d { ruleCheck = Just s }))
+  , make_ord_flag defFlag "freduction-depth"
+      (intSuffix (\n d -> d { reductionDepth = treatZeroAsInf n }))
+  , make_ord_flag defFlag "fconstraint-solver-iterations"
+      (intSuffix (\n d -> d { solverIterations = treatZeroAsInf n }))
+  , (Deprecated, defFlag "fcontext-stack"
       (intSuffixM (\n d ->
        do { deprecate $ "use -freduction-depth=" ++ show n ++ " instead"
-          ; return $ d{ reductionDepth = treatZeroAsInf n } }))
-  , defFlag "ftype-function-depth"
+          ; return $ d { reductionDepth = treatZeroAsInf n } })))
+  , (Deprecated, defFlag "ftype-function-depth"
       (intSuffixM (\n d ->
        do { deprecate $ "use -freduction-depth=" ++ show n ++ " instead"
-          ; return $ d{ reductionDepth = treatZeroAsInf n } }))
-  , defFlag "fstrictness-before"
-      (intSuffix (\n d -> d{ strictnessBefore = n : strictnessBefore d }))
-  , defFlag "ffloat-lam-args"
-      (intSuffix (\n d -> d{ floatLamArgs = Just n }))
-  , defFlag "ffloat-all-lams"
-      (noArg (\d -> d{ floatLamArgs = Nothing }))
-
-  , defFlag "fhistory-size"           (intSuffix (\n d -> d{ historySize = n }))
-
-  , defFlag "funfolding-creation-threshold"
+          ; return $ d { reductionDepth = treatZeroAsInf n } })))
+  , make_ord_flag defFlag "fstrictness-before"
+      (intSuffix (\n d -> d { strictnessBefore = n : strictnessBefore d }))
+  , make_ord_flag defFlag "ffloat-lam-args"
+      (intSuffix (\n d -> d { floatLamArgs = Just n }))
+  , make_ord_flag defFlag "ffloat-all-lams"
+      (noArg (\d -> d { floatLamArgs = Nothing }))
+  , make_ord_flag defFlag "fhistory-size"
+      (intSuffix (\n d -> d { historySize = n }))
+  , make_ord_flag defFlag "funfolding-creation-threshold"
       (intSuffix   (\n d -> d {ufCreationThreshold = n}))
-  , defFlag "funfolding-use-threshold"
+  , make_ord_flag defFlag "funfolding-use-threshold"
       (intSuffix   (\n d -> d {ufUseThreshold = n}))
-  , defFlag "funfolding-fun-discount"
+  , make_ord_flag defFlag "funfolding-fun-discount"
       (intSuffix   (\n d -> d {ufFunAppDiscount = n}))
-  , defFlag "funfolding-dict-discount"
+  , make_ord_flag defFlag "funfolding-dict-discount"
       (intSuffix   (\n d -> d {ufDictDiscount = n}))
-  , defFlag "funfolding-keeness-factor"
+  , make_ord_flag defFlag "funfolding-keeness-factor"
       (floatSuffix (\n d -> d {ufKeenessFactor = n}))
-
-  , defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n}))
-
-  , defGhciFlag "fghci-hist-size" (intSuffix (\n d -> d {ghciHistSize = n}))
-  , defGhcFlag "fmax-inline-alloc-size"
-      (intSuffix (\n d -> d{ maxInlineAllocSize = n }))
-  , defGhcFlag "fmax-inline-memcpy-insns"
-      (intSuffix (\n d -> d{ maxInlineMemcpyInsns = n }))
-  , defGhcFlag "fmax-inline-memset-insns"
-      (intSuffix (\n d -> d{ maxInlineMemsetInsns = n }))
+  , make_ord_flag defFlag "fmax-worker-args"
+      (intSuffix (\n d -> d {maxWorkerArgs = n}))
+  , make_ord_flag defGhciFlag "fghci-hist-size"
+      (intSuffix (\n d -> d {ghciHistSize = n}))
+  , make_ord_flag defGhcFlag "fmax-inline-alloc-size"
+      (intSuffix (\n d -> d { maxInlineAllocSize = n }))
+  , make_ord_flag defGhcFlag "fmax-inline-memcpy-insns"
+      (intSuffix (\n d -> d { maxInlineMemcpyInsns = n }))
+  , make_ord_flag defGhcFlag "fmax-inline-memset-insns"
+      (intSuffix (\n d -> d { maxInlineMemsetInsns = n }))
+  , make_ord_flag defGhcFlag "dinitial-unique"
+      (intSuffix (\n d -> d { initialUnique = n }))
+  , make_ord_flag defGhcFlag "dunique-increment"
+      (intSuffix (\n d -> d { uniqueIncrement = n }))
 
         ------ Profiling ----------------------------------------------------
 
         -- OLD profiling flags
-  , defGhcFlag "auto-all"    (noArg (\d -> d { profAuto = ProfAutoAll } ))
-  , defGhcFlag "no-auto-all" (noArg (\d -> d { profAuto = NoProfAuto } ))
-  , defGhcFlag "auto"        (noArg (\d -> d { profAuto = ProfAutoExports } ))
-  , defGhcFlag "no-auto"     (noArg (\d -> d { profAuto = NoProfAuto } ))
-  , defGhcFlag "caf-all"
-      (NoArg (setGeneralFlag Opt_AutoSccsOnIndividualCafs))
-  , defGhcFlag "no-caf-all"
-      (NoArg (unSetGeneralFlag Opt_AutoSccsOnIndividualCafs))
+  , make_dep_flag defGhcFlag "auto-all"
+                    (noArg (\d -> d { profAuto = ProfAutoAll } ))
+                    "Use -fprof-auto instead"
+  , make_dep_flag defGhcFlag "no-auto-all"
+                    (noArg (\d -> d { profAuto = NoProfAuto } ))
+                    "Use -fno-prof-auto instead"
+  , make_dep_flag defGhcFlag "auto"
+                    (noArg (\d -> d { profAuto = ProfAutoExports } ))
+                    "Use -fprof-auto-exported instead"
+  , make_dep_flag defGhcFlag "no-auto"
+            (noArg (\d -> d { profAuto = NoProfAuto } ))
+                    "Use -fno-prof-auto instead"
+  , make_dep_flag defGhcFlag "caf-all"
+            (NoArg (setGeneralFlag Opt_AutoSccsOnIndividualCafs))
+                    "Use -fprof-cafs instead"
+  , make_dep_flag defGhcFlag "no-caf-all"
+            (NoArg (unSetGeneralFlag Opt_AutoSccsOnIndividualCafs))
+                    "Use -fno-prof-cafs instead"
 
         -- NEW profiling flags
-  , defGhcFlag "fprof-auto"
+  , make_ord_flag defGhcFlag "fprof-auto"
       (noArg (\d -> d { profAuto = ProfAutoAll } ))
-  , defGhcFlag "fprof-auto-top"
+  , make_ord_flag defGhcFlag "fprof-auto-top"
       (noArg (\d -> d { profAuto = ProfAutoTop } ))
-  , defGhcFlag "fprof-auto-exported"
+  , make_ord_flag defGhcFlag "fprof-auto-exported"
       (noArg (\d -> d { profAuto = ProfAutoExports } ))
-  , defGhcFlag "fprof-auto-calls"
+  , make_ord_flag defGhcFlag "fprof-auto-calls"
       (noArg (\d -> d { profAuto = ProfAutoCalls } ))
-  , defGhcFlag "fno-prof-auto"
+  , make_ord_flag defGhcFlag "fno-prof-auto"
       (noArg (\d -> d { profAuto = NoProfAuto } ))
 
         ------ Compiler flags -----------------------------------------------
 
-  , defGhcFlag "fasm"             (NoArg (setObjTarget HscAsm))
-  , defGhcFlag "fvia-c"           (NoArg
+  , make_ord_flag defGhcFlag "fasm"             (NoArg (setObjTarget HscAsm))
+  , make_ord_flag defGhcFlag "fvia-c"           (NoArg
          (addWarn $ "The -fvia-c flag does nothing; " ++
                     "it will be removed in a future GHC release"))
-  , defGhcFlag "fvia-C"           (NoArg
+  , make_ord_flag defGhcFlag "fvia-C"           (NoArg
          (addWarn $ "The -fvia-C flag does nothing; " ++
                     "it will be removed in a future GHC release"))
-  , defGhcFlag "fllvm"            (NoArg (setObjTarget HscLlvm))
-
-  , defFlag "fno-code"         (NoArg (do upd $ \d -> d{ ghcLink=NoLink }
-                                          setTarget HscNothing))
-  , defFlag "fbyte-code"       (NoArg (setTarget HscInterpreted))
-  , defFlag "fobject-code"     (NoArg (setTargetWithPlatform defaultHscTarget))
-  , defFlag "fglasgow-exts"
-      (NoArg (do enableGlasgowExts
-                 deprecate "Use individual extensions instead"))
-  , defFlag "fno-glasgow-exts"
-      (NoArg (do disableGlasgowExts
-                 deprecate "Use individual extensions instead"))
-  , defFlag "fwarn-unused-binds" (NoArg enableUnusedBinds)
-  , defFlag "fno-warn-unused-binds" (NoArg disableUnusedBinds)
+  , make_ord_flag defGhcFlag "fllvm"            (NoArg (setObjTarget HscLlvm))
+
+  , make_ord_flag defFlag "fno-code"         (NoArg ((upd $ \d ->
+                  d { ghcLink=NoLink }) >> setTarget HscNothing))
+  , make_ord_flag defFlag "fbyte-code"       (NoArg (setTarget HscInterpreted))
+  , make_ord_flag defFlag "fobject-code"     (NoArg (setTargetWithPlatform
+                                                             defaultHscTarget))
+  , make_dep_flag defFlag "fglasgow-exts"
+      (NoArg enableGlasgowExts) "Use individual extensions instead"
+  , make_dep_flag defFlag "fno-glasgow-exts"
+      (NoArg disableGlasgowExts) "Use individual extensions instead"
+  , make_ord_flag defFlag "Wunused-binds" (NoArg enableUnusedBinds)
+  , make_ord_flag defFlag "Wno-unused-binds" (NoArg disableUnusedBinds)
+  , make_ord_flag defHiddenFlag "fwarn-unused-binds" (NoArg enableUnusedBinds)
+  , make_ord_flag defHiddenFlag "fno-warn-unused-binds" (NoArg
+                                                            disableUnusedBinds)
 
         ------ Safe Haskell flags -------------------------------------------
-  , defFlag "fpackage-trust"   (NoArg setPackageTrust)
-  , defFlag "fno-safe-infer"   (noArg (\d -> d { safeInfer = False  } ))
-  , defGhcFlag "fPIC"          (NoArg (setGeneralFlag Opt_PIC))
-  , defGhcFlag "fno-PIC"       (NoArg (unSetGeneralFlag Opt_PIC))
+  , make_ord_flag defFlag "fpackage-trust"   (NoArg setPackageTrust)
+  , make_ord_flag defFlag "fno-safe-infer"   (noArg (\d ->
+                                                    d { safeInfer = False }))
+  , make_ord_flag defGhcFlag "fPIC"          (NoArg (setGeneralFlag Opt_PIC))
+  , make_ord_flag defGhcFlag "fno-PIC"       (NoArg (unSetGeneralFlag Opt_PIC))
 
          ------ Debugging flags ----------------------------------------------
-  , defGhcFlag "g"             (NoArg (setGeneralFlag Opt_Debug))
+  , make_ord_flag defGhcFlag "g"             (OptIntSuffix setDebugLevel)
  ]
- ++ map (mkFlag turnOn  ""     setGeneralFlag  ) negatableFlags
- ++ map (mkFlag turnOff "no-"  unSetGeneralFlag) negatableFlags
- ++ map (mkFlag turnOn  "d"    setGeneralFlag  ) dFlags
- ++ map (mkFlag turnOff "dno-" unSetGeneralFlag) dFlags
- ++ map (mkFlag turnOn  "f"    setGeneralFlag  ) fFlags
- ++ map (mkFlag turnOff "fno-" unSetGeneralFlag) fFlags
- ++ map (mkFlag turnOn  "f"    setWarningFlag  ) fWarningFlags
- ++ map (mkFlag turnOff "fno-" unSetWarningFlag) fWarningFlags
- ++ map (mkFlag turnOn  "f"    setExtensionFlag  ) fLangFlags
- ++ map (mkFlag turnOff "fno-" unSetExtensionFlag) fLangFlags
- ++ map (mkFlag turnOn  "X"    setExtensionFlag  ) xFlags
- ++ map (mkFlag turnOff "XNo"  unSetExtensionFlag) xFlags
- ++ map (mkFlag turnOn  "X"    setLanguage) languageFlags
- ++ map (mkFlag turnOn  "X"    setSafeHaskell) safeHaskellFlags
- ++ [ defFlag "XGenerics"
-        (NoArg (deprecate $
-                  "it does nothing; look into -XDefaultSignatures " ++
-                  "and -XDeriveGeneric for generic programming support."))
-    , defFlag "XNoGenerics"
-        (NoArg (deprecate $
-                  "it does nothing; look into -XDefaultSignatures and " ++
-                  "-XDeriveGeneric for generic programming support.")) ]
+ ++ map (mkFlag turnOn  ""          setGeneralFlag    ) negatableFlagsDeps
+ ++ map (mkFlag turnOff "no-"       unSetGeneralFlag  ) negatableFlagsDeps
+ ++ map (mkFlag turnOn  "d"         setGeneralFlag    ) dFlagsDeps
+ ++ map (mkFlag turnOff "dno-"      unSetGeneralFlag  ) dFlagsDeps
+ ++ map (mkFlag turnOn  "f"         setGeneralFlag    ) fFlagsDeps
+ ++ map (mkFlag turnOff "fno-"      unSetGeneralFlag  ) fFlagsDeps
+ ++ map (mkFlag turnOn  "W"         setWarningFlag    ) wWarningFlagsDeps
+ ++ map (mkFlag turnOff "Wno-"      unSetWarningFlag  ) wWarningFlagsDeps
+ ++ map (mkFlag turnOn  "Werror="   (\flag -> do {
+                                       ; setWarningFlag flag
+                                       ; setFatalWarningFlag flag }))
+                                                        wWarningFlagsDeps
+ ++ map (mkFlag turnOn  "Wwarn="     unSetFatalWarningFlag )
+                                                        wWarningFlagsDeps
+ ++ map (mkFlag turnOn  "Wno-error=" unSetFatalWarningFlag )
+                                                        wWarningFlagsDeps
+ ++ map (mkFlag turnOn  "fwarn-"    setWarningFlag   . hideFlag)
+    wWarningFlagsDeps
+ ++ map (mkFlag turnOff "fno-warn-" unSetWarningFlag . hideFlag)
+    wWarningFlagsDeps
+ ++ [ (NotDeprecated, unrecognisedWarning "W"),
+      (Deprecated,    unrecognisedWarning "fwarn-"),
+      (Deprecated,    unrecognisedWarning "fno-warn-") ]
+ ++ map (mkFlag turnOn  "f"         setExtensionFlag  ) fLangFlagsDeps
+ ++ map (mkFlag turnOff "fno-"      unSetExtensionFlag) fLangFlagsDeps
+ ++ map (mkFlag turnOn  "X"         setExtensionFlag  ) xFlagsDeps
+ ++ map (mkFlag turnOff "XNo"       unSetExtensionFlag) xFlagsDeps
+ ++ map (mkFlag turnOn  "X"         setLanguage       ) languageFlagsDeps
+ ++ map (mkFlag turnOn  "X"         setSafeHaskell    ) safeHaskellFlagsDeps
+ ++ [ make_dep_flag defFlag "XGenerics"
+        (NoArg $ return ())
+                  ("it does nothing; look into -XDefaultSignatures " ++
+                   "and -XDeriveGeneric for generic programming support.")
+    , make_dep_flag defFlag "XNoGenerics"
+        (NoArg $ return ())
+               ("it does nothing; look into -XDefaultSignatures and " ++
+                  "-XDeriveGeneric for generic programming support.") ]
+
+-- | This is where we handle unrecognised warning flags. We only issue a warning
+-- if -Wunrecognised-warning-flags is set. See Trac #11429 for context.
+unrecognisedWarning :: String -> Flag (CmdLineP DynFlags)
+unrecognisedWarning prefix = defHiddenFlag prefix (Prefix action)
+  where
+    action :: String -> EwM (CmdLineP DynFlags) ()
+    action flag = do
+      f <- wopt Opt_WarnUnrecognisedWarningFlags <$> liftEwM getCmdLineState
+      when f $ addWarn $ "unrecognised warning flag: -" ++ prefix ++ flag
 
 -- See Note [Supporting CLI completion]
-package_flags :: [Flag (CmdLineP DynFlags)]
-package_flags = [
+package_flags_deps :: [(Deprecation, Flag (CmdLineP DynFlags))]
+package_flags_deps = [
         ------- Packages ----------------------------------------------------
-    defFlag "package-db"            (HasArg (addPkgConfRef . PkgConfFile))
-  , defFlag "clear-package-db"      (NoArg clearPkgConf)
-  , defFlag "no-global-package-db"  (NoArg removeGlobalPkgConf)
-  , defFlag "no-user-package-db"    (NoArg removeUserPkgConf)
-  , defFlag "global-package-db"     (NoArg (addPkgConfRef GlobalPkgConf))
-  , defFlag "user-package-db"       (NoArg (addPkgConfRef UserPkgConf))
-
+    make_ord_flag defFlag "package-db"
+      (HasArg (addPkgConfRef . PkgConfFile))
+  , make_ord_flag defFlag "clear-package-db"      (NoArg clearPkgConf)
+  , make_ord_flag defFlag "no-global-package-db"  (NoArg removeGlobalPkgConf)
+  , make_ord_flag defFlag "no-user-package-db"    (NoArg removeUserPkgConf)
+  , make_ord_flag defFlag "global-package-db"
+      (NoArg (addPkgConfRef GlobalPkgConf))
+  , make_ord_flag defFlag "user-package-db"
+      (NoArg (addPkgConfRef UserPkgConf))
     -- backwards compat with GHC<=7.4 :
-  , defFlag "package-conf"          (HasArg $ \path -> do
-                                       addPkgConfRef (PkgConfFile path)
-                                       deprecate "Use -package-db instead")
-  , defFlag "no-user-package-conf"
-      (NoArg $ do removeUserPkgConf
-                  deprecate "Use -no-user-package-db instead")
-
-  , defGhcFlag "package-name"      (HasArg $ \name -> do
-                                      upd (setPackageKey name)
-                                      deprecate "Use -this-package-key instead")
-  , defGhcFlag "this-package-key"   (hasArg setPackageKey)
-  , defFlag "package-id"            (HasArg exposePackageId)
-  , defFlag "package"               (HasArg exposePackage)
-  , defFlag "package-key"           (HasArg exposePackageKey)
-  , defFlag "hide-package"          (HasArg hidePackage)
-  , defFlag "hide-all-packages"     (NoArg (setGeneralFlag Opt_HideAllPackages))
-  , defFlag "package-env"           (HasArg setPackageEnv)
-  , defFlag "ignore-package"        (HasArg ignorePackage)
-  , defFlag "syslib"
-      (HasArg (\s -> do exposePackage s
-                        deprecate "Use -package instead"))
-  , defFlag "distrust-all-packages"
+  , make_dep_flag defFlag "package-conf"
+      (HasArg $ addPkgConfRef . PkgConfFile) "Use -package-db instead"
+  , make_dep_flag defFlag "no-user-package-conf"
+      (NoArg removeUserPkgConf)              "Use -no-user-package-db instead"
+  , make_ord_flag defGhcFlag "package-name"       (HasArg $ \name -> do
+                                      upd (setUnitId name))
+                                      -- TODO: Since we JUST deprecated
+                                      -- -this-package-key, let's keep this
+                                      -- undeprecated for another cycle.
+                                      -- Deprecate this eventually.
+                                      -- deprecate "Use -this-unit-id instead")
+  , make_dep_flag defGhcFlag "this-package-key"   (HasArg $ upd . setUnitId)
+                                                  "Use -this-unit-id instead"
+  , make_ord_flag defGhcFlag "this-unit-id"       (hasArg setUnitId)
+  , make_ord_flag defFlag "package"               (HasArg exposePackage)
+  , make_ord_flag defFlag "plugin-package-id"     (HasArg exposePluginPackageId)
+  , make_ord_flag defFlag "plugin-package"        (HasArg exposePluginPackage)
+  , make_ord_flag defFlag "package-id"            (HasArg exposePackageId)
+  , make_ord_flag defFlag "hide-package"          (HasArg hidePackage)
+  , make_ord_flag defFlag "hide-all-packages"
+      (NoArg (setGeneralFlag Opt_HideAllPackages))
+  , make_ord_flag defFlag "hide-all-plugin-packages"
+      (NoArg (setGeneralFlag Opt_HideAllPluginPackages))
+  , make_ord_flag defFlag "package-env"           (HasArg setPackageEnv)
+  , make_ord_flag defFlag "ignore-package"        (HasArg ignorePackage)
+  , make_dep_flag defFlag "syslib" (HasArg exposePackage) "Use -package instead"
+  , make_ord_flag defFlag "distrust-all-packages"
       (NoArg (setGeneralFlag Opt_DistrustAllPackages))
-  , defFlag "trust"                 (HasArg trustPackage)
-  , defFlag "distrust"              (HasArg distrustPackage)
+  , make_ord_flag defFlag "trust"                 (HasArg trustPackage)
+  , make_ord_flag defFlag "distrust"              (HasArg distrustPackage)
   ]
   where
     setPackageEnv env = upd $ \s -> s { packageEnv = Just env }
@@ -2785,126 +3337,217 @@ data FlagSpec flag
        }
 
 -- | Define a new flag.
-flagSpec :: String -> flag -> FlagSpec flag
+flagSpec :: String -> flag -> (Deprecation, FlagSpec flag)
 flagSpec name flag = flagSpec' name flag nop
 
 -- | Define a new flag with an effect.
-flagSpec' :: String -> flag -> (TurnOnFlag -> DynP ()) -> FlagSpec flag
-flagSpec' name flag act = FlagSpec name flag act AllModes
+flagSpec' :: String -> flag -> (TurnOnFlag -> DynP ())
+          -> (Deprecation, FlagSpec flag)
+flagSpec' name flag act = (NotDeprecated, FlagSpec name flag act AllModes)
+
+-- | Define a new deprecated flag with an effect.
+depFlagSpecOp :: String -> flag -> (TurnOnFlag -> DynP ()) -> String
+            -> (Deprecation, FlagSpec flag)
+depFlagSpecOp name flag act dep =
+    (Deprecated, snd (flagSpec' name flag (\f -> act f >> deprecate dep)))
+
+-- | Define a new deprecated flag.
+depFlagSpec :: String -> flag -> String
+            -> (Deprecation, FlagSpec flag)
+depFlagSpec name flag dep = depFlagSpecOp name flag nop dep
+
+-- | Define a new deprecated flag with an effect where the deprecation message
+-- depends on the flag value
+depFlagSpecOp' :: String
+             -> flag
+             -> (TurnOnFlag -> DynP ())
+             -> (TurnOnFlag -> String)
+             -> (Deprecation, FlagSpec flag)
+depFlagSpecOp' name flag act dep =
+    (Deprecated, FlagSpec name flag (\f -> act f >> (deprecate $ dep f))
+                                                                       AllModes)
+
+-- | Define a new deprecated flag where the deprecation message
+-- depends on the flag value
+depFlagSpec' :: String
+             -> flag
+             -> (TurnOnFlag -> String)
+             -> (Deprecation, FlagSpec flag)
+depFlagSpec' name flag dep = depFlagSpecOp' name flag nop dep
+
+
+-- | Define a new deprecated flag where the deprecation message
+-- is shown depending on the flag value
+depFlagSpecCond :: String
+                -> flag
+                -> (TurnOnFlag -> Bool)
+                -> String
+                -> (Deprecation, FlagSpec flag)
+depFlagSpecCond name flag cond dep =
+    (Deprecated, FlagSpec name flag (\f -> when (cond f) $ deprecate dep)
+                                                                       AllModes)
 
 -- | Define a new flag for GHCi.
-flagGhciSpec :: String -> flag -> FlagSpec flag
+flagGhciSpec :: String -> flag -> (Deprecation, FlagSpec flag)
 flagGhciSpec name flag = flagGhciSpec' name flag nop
 
 -- | Define a new flag for GHCi with an effect.
-flagGhciSpec' :: String -> flag -> (TurnOnFlag -> DynP ()) -> FlagSpec flag
-flagGhciSpec' name flag act = FlagSpec name flag act OnlyGhci
+flagGhciSpec' :: String -> flag -> (TurnOnFlag -> DynP ())
+              -> (Deprecation, FlagSpec flag)
+flagGhciSpec' name flag act = (NotDeprecated, FlagSpec name flag act OnlyGhci)
 
 -- | Define a new flag invisible to CLI completion.
-flagHiddenSpec :: String -> flag -> FlagSpec flag
+flagHiddenSpec :: String -> flag -> (Deprecation, FlagSpec flag)
 flagHiddenSpec name flag = flagHiddenSpec' name flag nop
 
 -- | Define a new flag invisible to CLI completion with an effect.
-flagHiddenSpec' :: String -> flag -> (TurnOnFlag -> DynP ()) -> FlagSpec flag
-flagHiddenSpec' name flag act = FlagSpec name flag act HiddenFlag
+flagHiddenSpec' :: String -> flag -> (TurnOnFlag -> DynP ())
+                -> (Deprecation, FlagSpec flag)
+flagHiddenSpec' name flag act = (NotDeprecated, FlagSpec name flag act
+                                                                     HiddenFlag)
+
+-- | Hide a 'FlagSpec' from being displayed in @--show-options@.
+--
+-- This is for example useful for flags that are obsolete, but should not
+-- (yet) be deprecated for compatibility reasons.
+hideFlag :: (Deprecation, FlagSpec a) -> (Deprecation, FlagSpec a)
+hideFlag (dep, fs) = (dep, fs { flagSpecGhcMode = HiddenFlag })
 
 mkFlag :: TurnOnFlag            -- ^ True <=> it should be turned on
        -> String                -- ^ The flag prefix
        -> (flag -> DynP ())     -- ^ What to do when the flag is found
-       -> FlagSpec flag         -- ^ Specification of this particular flag
-       -> Flag (CmdLineP DynFlags)
-mkFlag turn_on flagPrefix f (FlagSpec name flag extra_action mode)
-    = Flag (flagPrefix ++ name) (NoArg (f flag >> extra_action turn_on)) mode
-
-deprecatedForExtension :: String -> TurnOnFlag -> DynP ()
+       -> (Deprecation, FlagSpec flag)  -- ^ Specification of
+                                        -- this particular flag
+       -> (Deprecation, Flag (CmdLineP DynFlags))
+mkFlag turn_on flagPrefix f (dep, (FlagSpec name flag extra_action mode))
+    = (dep,
+       Flag (flagPrefix ++ name) (NoArg (f flag >> extra_action turn_on)) mode)
+
+deprecatedForExtension :: String -> TurnOnFlag -> String
 deprecatedForExtension lang turn_on
-    = deprecate ("use -X"  ++ flag ++
-                 " or pragma {-# LANGUAGE " ++ flag ++ " #-} instead")
+    = "use -X" ++ flag ++
+      " or pragma {-# LANGUAGE " ++ flag ++ " #-} instead"
     where
-      flag | turn_on    = lang
-           | otherwise = "No"++lang
+      flag | turn_on   = lang
+           | otherwise = "No" ++ lang
 
-useInstead :: String -> TurnOnFlag -> DynP ()
+useInstead :: String -> TurnOnFlag -> String
 useInstead flag turn_on
-  = deprecate ("Use -f" ++ no ++ flag ++ " instead")
+  = "Use -f" ++ no ++ flag ++ " instead"
   where
     no = if turn_on then "" else "no-"
 
 nop :: TurnOnFlag -> DynP ()
 nop _ = return ()
 
--- | These @-f\<blah\>@ flags can all be reversed with @-fno-\<blah\>@
-fWarningFlags :: [FlagSpec WarningFlag]
-fWarningFlags = [
+-- | Find the 'FlagSpec' for a 'WarningFlag'.
+flagSpecOf :: WarningFlag -> Maybe (FlagSpec WarningFlag)
+flagSpecOf flag = listToMaybe $ filter check wWarningFlags
+  where
+    check fs = flagSpecFlag fs == flag
+
+-- | These @-W\<blah\>@ flags can all be reversed with @-Wno-\<blah\>@
+wWarningFlags :: [FlagSpec WarningFlag]
+wWarningFlags = map snd (sortBy (comparing fst) wWarningFlagsDeps)
+
+wWarningFlagsDeps :: [(Deprecation, FlagSpec WarningFlag)]
+wWarningFlagsDeps = [
 -- See Note [Updating flag description in the User's Guide]
 -- See Note [Supporting CLI completion]
 -- Please keep the list of flags below sorted alphabetically
-  flagSpec "warn-alternative-layout-rule-transitional"
+  flagSpec "alternative-layout-rule-transitional"
                                       Opt_WarnAlternativeLayoutRuleTransitional,
-  flagSpec' "warn-amp"                        Opt_WarnAMP
-    (\_ -> deprecate "it has no effect, and will be removed in GHC 7.12"),
-  flagSpec "warn-auto-orphans"                Opt_WarnAutoOrphans,
-  flagSpec "warn-deprecations"                Opt_WarnWarningsDeprecations,
-  flagSpec "warn-deprecated-flags"            Opt_WarnDeprecatedFlags,
-  flagSpec "warn-deriving-typeable"           Opt_WarnDerivingTypeable,
-  flagSpec "warn-dodgy-exports"               Opt_WarnDodgyExports,
-  flagSpec "warn-dodgy-foreign-imports"       Opt_WarnDodgyForeignImports,
-  flagSpec "warn-dodgy-imports"               Opt_WarnDodgyImports,
-  flagSpec "warn-empty-enumerations"          Opt_WarnEmptyEnumerations,
-  flagSpec "warn-context-quantification"      Opt_WarnContextQuantification,
-  flagSpec' "warn-duplicate-constraints"      Opt_WarnDuplicateConstraints
-    (\_ -> deprecate "it is subsumed by -fwarn-redundant-constraints"),
-  flagSpec "warn-redundant-constraints"       Opt_WarnRedundantConstraints,
-  flagSpec "warn-duplicate-exports"           Opt_WarnDuplicateExports,
-  flagSpec "warn-hi-shadowing"                Opt_WarnHiShadows,
-  flagSpec "warn-implicit-prelude"            Opt_WarnImplicitPrelude,
-  flagSpec "warn-incomplete-patterns"         Opt_WarnIncompletePatterns,
-  flagSpec "warn-incomplete-record-updates"   Opt_WarnIncompletePatternsRecUpd,
-  flagSpec "warn-incomplete-uni-patterns"     Opt_WarnIncompleteUniPatterns,
-  flagSpec "warn-inline-rule-shadowing"       Opt_WarnInlineRuleShadowing,
-  flagSpec "warn-identities"                  Opt_WarnIdentities,
-  flagSpec "warn-missing-fields"              Opt_WarnMissingFields,
-  flagSpec "warn-missing-import-lists"        Opt_WarnMissingImportList,
-  flagSpec "warn-missing-local-sigs"          Opt_WarnMissingLocalSigs,
-  flagSpec "warn-missing-methods"             Opt_WarnMissingMethods,
-  flagSpec "warn-missing-signatures"          Opt_WarnMissingSigs,
-  flagSpec "warn-missing-exported-sigs"       Opt_WarnMissingExportedSigs,
-  flagSpec "warn-monomorphism-restriction"    Opt_WarnMonomorphism,
-  flagSpec "warn-name-shadowing"              Opt_WarnNameShadowing,
-  flagSpec "warn-orphans"                     Opt_WarnOrphans,
-  flagSpec "warn-overflowed-literals"         Opt_WarnOverflowedLiterals,
-  flagSpec "warn-overlapping-patterns"        Opt_WarnOverlappingPatterns,
-  flagSpec "warn-pointless-pragmas"           Opt_WarnPointlessPragmas,
-  flagSpec' "warn-safe"                       Opt_WarnSafe setWarnSafe,
-  flagSpec "warn-trustworthy-safe"            Opt_WarnTrustworthySafe,
-  flagSpec "warn-tabs"                        Opt_WarnTabs,
-  flagSpec "warn-type-defaults"               Opt_WarnTypeDefaults,
-  flagSpec "warn-typed-holes"                 Opt_WarnTypedHoles,
-  flagSpec "warn-partial-type-signatures"     Opt_WarnPartialTypeSignatures,
-  flagSpec "warn-unrecognised-pragmas"        Opt_WarnUnrecognisedPragmas,
-  flagSpec' "warn-unsafe"                     Opt_WarnUnsafe setWarnUnsafe,
-  flagSpec "warn-unsupported-calling-conventions"
+  depFlagSpec "amp"                      Opt_WarnAMP
+    "it has no effect",
+  depFlagSpec "auto-orphans"             Opt_WarnAutoOrphans
+    "it has no effect",
+  flagSpec "cpp-undef"                   Opt_WarnCPPUndef,
+  flagSpec "unbanged-strict-patterns"    Opt_WarnUnbangedStrictPatterns,
+  flagSpec "deferred-type-errors"        Opt_WarnDeferredTypeErrors,
+  flagSpec "deferred-out-of-scope-variables"
+                                         Opt_WarnDeferredOutOfScopeVariables,
+  flagSpec "deprecations"                Opt_WarnWarningsDeprecations,
+  flagSpec "deprecated-flags"            Opt_WarnDeprecatedFlags,
+  flagSpec "deriving-typeable"           Opt_WarnDerivingTypeable,
+  flagSpec "dodgy-exports"               Opt_WarnDodgyExports,
+  flagSpec "dodgy-foreign-imports"       Opt_WarnDodgyForeignImports,
+  flagSpec "dodgy-imports"               Opt_WarnDodgyImports,
+  flagSpec "empty-enumerations"          Opt_WarnEmptyEnumerations,
+  depFlagSpec "duplicate-constraints"    Opt_WarnDuplicateConstraints
+    "it is subsumed by -Wredundant-constraints",
+  flagSpec "redundant-constraints"       Opt_WarnRedundantConstraints,
+  flagSpec "duplicate-exports"           Opt_WarnDuplicateExports,
+  flagSpec "hi-shadowing"                Opt_WarnHiShadows,
+  flagSpec "implicit-prelude"            Opt_WarnImplicitPrelude,
+  flagSpec "incomplete-patterns"         Opt_WarnIncompletePatterns,
+  flagSpec "incomplete-record-updates"   Opt_WarnIncompletePatternsRecUpd,
+  flagSpec "incomplete-uni-patterns"     Opt_WarnIncompleteUniPatterns,
+  flagSpec "inline-rule-shadowing"       Opt_WarnInlineRuleShadowing,
+  flagSpec "identities"                  Opt_WarnIdentities,
+  flagSpec "missing-fields"              Opt_WarnMissingFields,
+  flagSpec "missing-import-lists"        Opt_WarnMissingImportList,
+  depFlagSpec "missing-local-sigs"       Opt_WarnMissingLocalSignatures
+    "it is replaced by -Wmissing-local-signatures",
+  flagSpec "missing-local-signatures"    Opt_WarnMissingLocalSignatures,
+  flagSpec "missing-methods"             Opt_WarnMissingMethods,
+  flagSpec "missing-monadfail-instances" Opt_WarnMissingMonadFailInstances,
+  flagSpec "semigroup"                   Opt_WarnSemigroup,
+  flagSpec "missing-signatures"          Opt_WarnMissingSignatures,
+  depFlagSpec "missing-exported-sigs"    Opt_WarnMissingExportedSignatures
+    "it is replaced by -Wmissing-exported-signatures",
+  flagSpec "missing-exported-signatures" Opt_WarnMissingExportedSignatures,
+  flagSpec "monomorphism-restriction"    Opt_WarnMonomorphism,
+  flagSpec "name-shadowing"              Opt_WarnNameShadowing,
+  flagSpec "noncanonical-monad-instances"
+                                         Opt_WarnNonCanonicalMonadInstances,
+  flagSpec "noncanonical-monadfail-instances"
+                                         Opt_WarnNonCanonicalMonadFailInstances,
+  flagSpec "noncanonical-monoid-instances"
+                                         Opt_WarnNonCanonicalMonoidInstances,
+  flagSpec "orphans"                     Opt_WarnOrphans,
+  flagSpec "overflowed-literals"         Opt_WarnOverflowedLiterals,
+  flagSpec "overlapping-patterns"        Opt_WarnOverlappingPatterns,
+  flagSpec "missed-specialisations"      Opt_WarnMissedSpecs,
+  flagSpec "missed-specializations"      Opt_WarnMissedSpecs,
+  flagSpec "all-missed-specialisations"  Opt_WarnAllMissedSpecs,
+  flagSpec "all-missed-specializations"  Opt_WarnAllMissedSpecs,
+  flagSpec' "safe"                       Opt_WarnSafe setWarnSafe,
+  flagSpec "trustworthy-safe"            Opt_WarnTrustworthySafe,
+  flagSpec "tabs"                        Opt_WarnTabs,
+  flagSpec "type-defaults"               Opt_WarnTypeDefaults,
+  flagSpec "typed-holes"                 Opt_WarnTypedHoles,
+  flagSpec "partial-type-signatures"     Opt_WarnPartialTypeSignatures,
+  flagSpec "unrecognised-pragmas"        Opt_WarnUnrecognisedPragmas,
+  flagSpec' "unsafe"                     Opt_WarnUnsafe setWarnUnsafe,
+  flagSpec "unsupported-calling-conventions"
                                          Opt_WarnUnsupportedCallingConventions,
-  flagSpec "warn-unsupported-llvm-version"    Opt_WarnUnsupportedLlvmVersion,
-  flagSpec "warn-unticked-promoted-constructors"
+  flagSpec "unsupported-llvm-version"    Opt_WarnUnsupportedLlvmVersion,
+  flagSpec "unticked-promoted-constructors"
                                          Opt_WarnUntickedPromotedConstructors,
-  flagSpec "warn-unused-do-bind"              Opt_WarnUnusedDoBind,
-  flagSpec "warn-unused-imports"              Opt_WarnUnusedImports,
-  flagSpec "warn-unused-local-binds"          Opt_WarnUnusedLocalBinds,
-  flagSpec "warn-unused-matches"              Opt_WarnUnusedMatches,
-  flagSpec "warn-unused-pattern-binds"        Opt_WarnUnusedPatternBinds,
-  flagSpec "warn-unused-top-binds"            Opt_WarnUnusedTopBinds,
-  flagSpec "warn-warnings-deprecations"       Opt_WarnWarningsDeprecations,
-  flagSpec "warn-wrong-do-bind"               Opt_WarnWrongDoBind]
+  flagSpec "unused-do-bind"              Opt_WarnUnusedDoBind,
+  flagSpec "unused-foralls"              Opt_WarnUnusedForalls,
+  flagSpec "unused-imports"              Opt_WarnUnusedImports,
+  flagSpec "unused-local-binds"          Opt_WarnUnusedLocalBinds,
+  flagSpec "unused-matches"              Opt_WarnUnusedMatches,
+  flagSpec "unused-pattern-binds"        Opt_WarnUnusedPatternBinds,
+  flagSpec "unused-top-binds"            Opt_WarnUnusedTopBinds,
+  flagSpec "unused-type-patterns"        Opt_WarnUnusedTypePatterns,
+  flagSpec "warnings-deprecations"       Opt_WarnWarningsDeprecations,
+  flagSpec "wrong-do-bind"               Opt_WarnWrongDoBind,
+  flagSpec "missing-pattern-synonym-signatures"
+                                    Opt_WarnMissingPatternSynonymSignatures,
+  flagSpec "simplifiable-class-constraints" Opt_WarnSimplifiableClassConstraints,
+  flagSpec "missing-home-modules"        Opt_WarnMissingHomeModules,
+  flagSpec "unrecognised-warning-flags"  Opt_WarnUnrecognisedWarningFlags ]
 
 -- | These @-\<blah\>@ flags can all be reversed with @-no-\<blah\>@
-negatableFlags :: [FlagSpec GeneralFlag]
-negatableFlags = [
-  flagGhciSpec "ignore-dot-ghci"              Opt_IgnoreDotGhci ]
+negatableFlagsDeps :: [(Deprecation, FlagSpec GeneralFlag)]
+negatableFlagsDeps = [
+  flagGhciSpec "ignore-dot-ghci"         Opt_IgnoreDotGhci ]
 
 -- | These @-d\<blah\>@ flags can all be reversed with @-dno-\<blah\>@
-dFlags :: [FlagSpec GeneralFlag]
-dFlags = [
+dFlagsDeps :: [(Deprecation, FlagSpec GeneralFlag)]
+dFlagsDeps = [
 -- See Note [Updating flag description in the User's Guide]
 -- See Note [Supporting CLI completion]
 -- Please keep the list of flags below sorted alphabetically
@@ -2912,6 +3555,7 @@ dFlags = [
   flagSpec "ppr-ticks"                  Opt_PprShowTicks,
   flagSpec "suppress-coercions"         Opt_SuppressCoercions,
   flagSpec "suppress-idinfo"            Opt_SuppressIdInfo,
+  flagSpec "suppress-unfoldings"        Opt_SuppressUnfoldings,
   flagSpec "suppress-module-prefixes"   Opt_SuppressModulePrefixes,
   flagSpec "suppress-type-applications" Opt_SuppressTypeApplications,
   flagSpec "suppress-type-signatures"   Opt_SuppressTypeSignatures,
@@ -2920,7 +3564,10 @@ dFlags = [
 
 -- | These @-f\<blah\>@ flags can all be reversed with @-fno-\<blah\>@
 fFlags :: [FlagSpec GeneralFlag]
-fFlags = [
+fFlags = map snd fFlagsDeps
+
+fFlagsDeps :: [(Deprecation, FlagSpec GeneralFlag)]
+fFlagsDeps = [
 -- See Note [Updating flag description in the User's Guide]
 -- See Note [Supporting CLI completion]
 -- Please keep the list of flags below sorted alphabetically
@@ -2929,11 +3576,16 @@ fFlags = [
   flagSpec "building-cabal-package"           Opt_BuildingCabalPackage,
   flagSpec "call-arity"                       Opt_CallArity,
   flagSpec "case-merge"                       Opt_CaseMerge,
+  flagSpec "case-folding"                     Opt_CaseFolding,
   flagSpec "cmm-elim-common-blocks"           Opt_CmmElimCommonBlocks,
   flagSpec "cmm-sink"                         Opt_CmmSink,
   flagSpec "cse"                              Opt_CSE,
+  flagSpec "stg-cse"                          Opt_StgCSE,
+  flagSpec "cpr-anal"                         Opt_CprAnal,
   flagSpec "defer-type-errors"                Opt_DeferTypeErrors,
   flagSpec "defer-typed-holes"                Opt_DeferTypedHoles,
+  flagSpec "defer-out-of-scope-variables"     Opt_DeferOutOfScopeVariables,
+  flagSpec "diagnostics-show-caret"           Opt_DiagnosticsShowCaret,
   flagSpec "dicts-cheap"                      Opt_DictsCheap,
   flagSpec "dicts-strict"                     Opt_DictsStrict,
   flagSpec "dmd-tx-dict-sel"                  Opt_DmdTxDictSel,
@@ -2945,6 +3597,7 @@ fFlags = [
   flagSpec "error-spans"                      Opt_ErrorSpans,
   flagSpec "excess-precision"                 Opt_ExcessPrecision,
   flagSpec "expose-all-unfoldings"            Opt_ExposeAllUnfoldings,
+  flagSpec "external-interpreter"             Opt_ExternalInterpreter,
   flagSpec "flat-cache"                       Opt_FlatCache,
   flagSpec "float-in"                         Opt_FloatIn,
   flagSpec "force-recomp"                     Opt_ForceRecomp,
@@ -2952,6 +3605,7 @@ fFlags = [
   flagSpec "fun-to-thunk"                     Opt_FunToThunk,
   flagSpec "gen-manifest"                     Opt_GenManifest,
   flagSpec "ghci-history"                     Opt_GhciHistory,
+  flagGhciSpec "local-ghci-history"           Opt_LocalGhciHistory,
   flagSpec "ghci-sandbox"                     Opt_GhciSandbox,
   flagSpec "helpful-errors"                   Opt_HelpfulErrors,
   flagSpec "hpc"                              Opt_Hpc,
@@ -2965,9 +3619,11 @@ fFlags = [
   flagSpec "liberate-case"                    Opt_LiberateCase,
   flagHiddenSpec "llvm-pass-vectors-in-regs"  Opt_LlvmPassVectorsInRegisters,
   flagHiddenSpec "llvm-tbaa"                  Opt_LlvmTBAA,
+  flagHiddenSpec "llvm-fill-undef-with-garbage" Opt_LlvmFillUndefWithGarbage,
   flagSpec "loopification"                    Opt_Loopification,
   flagSpec "omit-interface-pragmas"           Opt_OmitInterfacePragmas,
   flagSpec "omit-yields"                      Opt_OmitYields,
+  flagSpec "optimal-applicative-do"           Opt_OptimalApplicativeDo,
   flagSpec "pedantic-bottoms"                 Opt_PedanticBottoms,
   flagSpec "pre-inlining"                     Opt_SimplPreInlining,
   flagGhciSpec "print-bind-contents"          Opt_PrintBindContents,
@@ -2975,18 +3631,27 @@ fFlags = [
   flagGhciSpec "print-evld-with-show"         Opt_PrintEvldWithShow,
   flagSpec "print-explicit-foralls"           Opt_PrintExplicitForalls,
   flagSpec "print-explicit-kinds"             Opt_PrintExplicitKinds,
+  flagSpec "print-explicit-coercions"         Opt_PrintExplicitCoercions,
+  flagSpec "print-explicit-runtime-reps"      Opt_PrintExplicitRuntimeReps,
+  flagSpec "print-equality-relations"         Opt_PrintEqualityRelations,
   flagSpec "print-unicode-syntax"             Opt_PrintUnicodeSyntax,
+  flagSpec "print-expanded-synonyms"          Opt_PrintExpandedSynonyms,
+  flagSpec "print-potential-instances"        Opt_PrintPotentialInstances,
+  flagSpec "print-typechecker-elaboration"    Opt_PrintTypecheckerElaboration,
   flagSpec "prof-cafs"                        Opt_AutoSccsOnIndividualCafs,
   flagSpec "prof-count-entries"               Opt_ProfCountEntries,
   flagSpec "regs-graph"                       Opt_RegsGraph,
   flagSpec "regs-iterative"                   Opt_RegsIterative,
-  flagSpec' "rewrite-rules"                   Opt_EnableRewriteRules
+  depFlagSpec' "rewrite-rules"                Opt_EnableRewriteRules
     (useInstead "enable-rewrite-rules"),
   flagSpec "shared-implib"                    Opt_SharedImplib,
-  flagSpec "simple-list-literals"             Opt_SimpleListLiterals,
   flagSpec "spec-constr"                      Opt_SpecConstr,
   flagSpec "specialise"                       Opt_Specialise,
+  flagSpec "specialize"                       Opt_Specialise,
   flagSpec "specialise-aggressively"          Opt_SpecialiseAggressively,
+  flagSpec "specialize-aggressively"          Opt_SpecialiseAggressively,
+  flagSpec "cross-module-specialise"          Opt_CrossModuleSpecialise,
+  flagSpec "cross-module-specialize"          Opt_CrossModuleSpecialise,
   flagSpec "static-argument-transformation"   Opt_StaticArgumentTransformation,
   flagSpec "strictness"                       Opt_Strictness,
   flagSpec "use-rpaths"                       Opt_RPath,
@@ -2994,66 +3659,80 @@ fFlags = [
   flagSpec "unbox-small-strict-fields"        Opt_UnboxSmallStrictFields,
   flagSpec "unbox-strict-fields"              Opt_UnboxStrictFields,
   flagSpec "vectorisation-avoidance"          Opt_VectorisationAvoidance,
-  flagSpec "vectorise"                        Opt_Vectorise
+  flagSpec "vectorise"                        Opt_Vectorise,
+  flagSpec "version-macros"                   Opt_VersionMacros,
+  flagSpec "worker-wrapper"                   Opt_WorkerWrapper,
+  flagSpec "solve-constant-dicts"             Opt_SolveConstantDicts,
+  flagSpec "show-warning-groups"              Opt_ShowWarnGroups,
+  flagSpec "hide-source-paths"                Opt_HideSourcePaths,
+  flagSpec "show-hole-constraints"            Opt_ShowHoleConstraints
   ]
 
 -- | These @-f\<blah\>@ flags can all be reversed with @-fno-\<blah\>@
-fLangFlags :: [FlagSpec ExtensionFlag]
-fLangFlags = [
+fLangFlags :: [FlagSpec LangExt.Extension]
+fLangFlags = map snd fLangFlagsDeps
+
+fLangFlagsDeps :: [(Deprecation, FlagSpec LangExt.Extension)]
+fLangFlagsDeps = [
 -- See Note [Updating flag description in the User's Guide]
 -- See Note [Supporting CLI completion]
-  flagSpec' "th"                              Opt_TemplateHaskell
-    (\on -> deprecatedForExtension "TemplateHaskell" on
-         >> checkTemplateHaskellOk on),
-  flagSpec' "fi"                              Opt_ForeignFunctionInterface
+  depFlagSpecOp' "th"                           LangExt.TemplateHaskell
+    checkTemplateHaskellOk
+    (deprecatedForExtension "TemplateHaskell"),
+  depFlagSpec' "fi"                             LangExt.ForeignFunctionInterface
     (deprecatedForExtension "ForeignFunctionInterface"),
-  flagSpec' "ffi"                             Opt_ForeignFunctionInterface
+  depFlagSpec' "ffi"                            LangExt.ForeignFunctionInterface
     (deprecatedForExtension "ForeignFunctionInterface"),
-  flagSpec' "arrows"                          Opt_Arrows
+  depFlagSpec' "arrows"                         LangExt.Arrows
     (deprecatedForExtension "Arrows"),
-  flagSpec' "implicit-prelude"                Opt_ImplicitPrelude
+  depFlagSpec' "implicit-prelude"               LangExt.ImplicitPrelude
     (deprecatedForExtension "ImplicitPrelude"),
-  flagSpec' "bang-patterns"                   Opt_BangPatterns
+  depFlagSpec' "bang-patterns"                  LangExt.BangPatterns
     (deprecatedForExtension "BangPatterns"),
-  flagSpec' "monomorphism-restriction"        Opt_MonomorphismRestriction
+  depFlagSpec' "monomorphism-restriction"       LangExt.MonomorphismRestriction
     (deprecatedForExtension "MonomorphismRestriction"),
-  flagSpec' "mono-pat-binds"                  Opt_MonoPatBinds
+  depFlagSpec' "mono-pat-binds"                 LangExt.MonoPatBinds
     (deprecatedForExtension "MonoPatBinds"),
-  flagSpec' "extended-default-rules"          Opt_ExtendedDefaultRules
+  depFlagSpec' "extended-default-rules"         LangExt.ExtendedDefaultRules
     (deprecatedForExtension "ExtendedDefaultRules"),
-  flagSpec' "implicit-params"                 Opt_ImplicitParams
+  depFlagSpec' "implicit-params"                LangExt.ImplicitParams
     (deprecatedForExtension "ImplicitParams"),
-  flagSpec' "scoped-type-variables"           Opt_ScopedTypeVariables
+  depFlagSpec' "scoped-type-variables"          LangExt.ScopedTypeVariables
     (deprecatedForExtension "ScopedTypeVariables"),
-  flagSpec' "parr"                            Opt_ParallelArrays
+  depFlagSpec' "parr"                           LangExt.ParallelArrays
     (deprecatedForExtension "ParallelArrays"),
-  flagSpec' "PArr"                            Opt_ParallelArrays
+  depFlagSpec' "PArr"                           LangExt.ParallelArrays
     (deprecatedForExtension "ParallelArrays"),
-  flagSpec' "allow-overlapping-instances"     Opt_OverlappingInstances
+  depFlagSpec' "allow-overlapping-instances"    LangExt.OverlappingInstances
     (deprecatedForExtension "OverlappingInstances"),
-  flagSpec' "allow-undecidable-instances"     Opt_UndecidableInstances
+  depFlagSpec' "allow-undecidable-instances"    LangExt.UndecidableInstances
     (deprecatedForExtension "UndecidableInstances"),
-  flagSpec' "allow-incoherent-instances"      Opt_IncoherentInstances
+  depFlagSpec' "allow-incoherent-instances"     LangExt.IncoherentInstances
     (deprecatedForExtension "IncoherentInstances")
   ]
 
 supportedLanguages :: [String]
-supportedLanguages = map flagSpecName languageFlags
+supportedLanguages = map (flagSpecName . snd) languageFlagsDeps
 
 supportedLanguageOverlays :: [String]
-supportedLanguageOverlays = map flagSpecName safeHaskellFlags
+supportedLanguageOverlays = map (flagSpecName . snd) safeHaskellFlagsDeps
 
 supportedExtensions :: [String]
-supportedExtensions
-    = concatMap (\name -> [name, "No" ++ name]) (map flagSpecName xFlags)
+supportedExtensions = concatMap toFlagSpecNamePair xFlags
+  where
+    toFlagSpecNamePair flg
+      | otherwise = [name, noName]
+      where
+        noName = "No" ++ name
+        name = flagSpecName flg
 
 supportedLanguagesAndExtensions :: [String]
 supportedLanguagesAndExtensions =
     supportedLanguages ++ supportedLanguageOverlays ++ supportedExtensions
 
 -- | These -X<blah> flags cannot be reversed with -XNo<blah>
-languageFlags :: [FlagSpec Language]
-languageFlags = [
+languageFlagsDeps :: [(Deprecation, FlagSpec Language)]
+languageFlagsDeps = [
   flagSpec "Haskell98"   Haskell98,
   flagSpec "Haskell2010" Haskell2010
   ]
@@ -3061,149 +3740,172 @@ languageFlags = [
 -- | These -X<blah> flags cannot be reversed with -XNo<blah>
 -- They are used to place hard requirements on what GHC Haskell language
 -- features can be used.
-safeHaskellFlags :: [FlagSpec SafeHaskellMode]
-safeHaskellFlags = [mkF Sf_Unsafe, mkF Sf_Trustworthy, mkF Sf_Safe]
+safeHaskellFlagsDeps :: [(Deprecation, FlagSpec SafeHaskellMode)]
+safeHaskellFlagsDeps = [mkF Sf_Unsafe, mkF Sf_Trustworthy, mkF Sf_Safe]
     where mkF flag = flagSpec (show flag) flag
 
 -- | These -X<blah> flags can all be reversed with -XNo<blah>
-xFlags :: [FlagSpec ExtensionFlag]
-xFlags = [
+xFlags :: [FlagSpec LangExt.Extension]
+xFlags = map snd xFlagsDeps
+
+xFlagsDeps :: [(Deprecation, FlagSpec LangExt.Extension)]
+xFlagsDeps = [
 -- See Note [Updating flag description in the User's Guide]
 -- See Note [Supporting CLI completion]
+-- See Note [Adding a language extension]
 -- Please keep the list of flags below sorted alphabetically
-  flagSpec "AllowAmbiguousTypes"              Opt_AllowAmbiguousTypes,
-  flagSpec "AlternativeLayoutRule"            Opt_AlternativeLayoutRule,
+  flagSpec "AllowAmbiguousTypes"              LangExt.AllowAmbiguousTypes,
+  flagSpec "AlternativeLayoutRule"            LangExt.AlternativeLayoutRule,
   flagSpec "AlternativeLayoutRuleTransitional"
-                                          Opt_AlternativeLayoutRuleTransitional,
-  flagSpec "Arrows"                           Opt_Arrows,
-  flagSpec "AutoDeriveTypeable"               Opt_AutoDeriveTypeable,
-  flagSpec "BangPatterns"                     Opt_BangPatterns,
-  flagSpec "BinaryLiterals"                   Opt_BinaryLiterals,
-  flagSpec "CApiFFI"                          Opt_CApiFFI,
-  flagSpec "CPP"                              Opt_Cpp,
-  flagSpec "ConstrainedClassMethods"          Opt_ConstrainedClassMethods,
-  flagSpec "ConstraintKinds"                  Opt_ConstraintKinds,
-  flagSpec "DataKinds"                        Opt_DataKinds,
-  flagSpec' "DatatypeContexts"                Opt_DatatypeContexts
-    (\ turn_on -> when turn_on $
-         deprecate $ "It was widely considered a misfeature, " ++
+                                              LangExt.AlternativeLayoutRuleTransitional,
+  flagSpec "Arrows"                           LangExt.Arrows,
+  flagSpec "AutoDeriveTypeable"               LangExt.AutoDeriveTypeable,
+  flagSpec "BangPatterns"                     LangExt.BangPatterns,
+  flagSpec "BinaryLiterals"                   LangExt.BinaryLiterals,
+  flagSpec "CApiFFI"                          LangExt.CApiFFI,
+  flagSpec "CPP"                              LangExt.Cpp,
+  flagSpec "ConstrainedClassMethods"          LangExt.ConstrainedClassMethods,
+  flagSpec "ConstraintKinds"                  LangExt.ConstraintKinds,
+  flagSpec "DataKinds"                        LangExt.DataKinds,
+  depFlagSpecCond "DatatypeContexts"          LangExt.DatatypeContexts
+    id
+         ("It was widely considered a misfeature, " ++
                      "and has been removed from the Haskell language."),
-  flagSpec "DefaultSignatures"                Opt_DefaultSignatures,
-  flagSpec "DeriveAnyClass"                   Opt_DeriveAnyClass,
-  flagSpec "DeriveDataTypeable"               Opt_DeriveDataTypeable,
-  flagSpec "DeriveFoldable"                   Opt_DeriveFoldable,
-  flagSpec "DeriveFunctor"                    Opt_DeriveFunctor,
-  flagSpec "DeriveGeneric"                    Opt_DeriveGeneric,
-  flagSpec "DeriveTraversable"                Opt_DeriveTraversable,
-  flagSpec "DisambiguateRecordFields"         Opt_DisambiguateRecordFields,
-  flagSpec "DoAndIfThenElse"                  Opt_DoAndIfThenElse,
-  flagSpec' "DoRec"                           Opt_RecursiveDo
+  flagSpec "DefaultSignatures"                LangExt.DefaultSignatures,
+  flagSpec "DeriveAnyClass"                   LangExt.DeriveAnyClass,
+  flagSpec "DeriveDataTypeable"               LangExt.DeriveDataTypeable,
+  flagSpec "DeriveFoldable"                   LangExt.DeriveFoldable,
+  flagSpec "DeriveFunctor"                    LangExt.DeriveFunctor,
+  flagSpec "DeriveGeneric"                    LangExt.DeriveGeneric,
+  flagSpec "DeriveLift"                       LangExt.DeriveLift,
+  flagSpec "DeriveTraversable"                LangExt.DeriveTraversable,
+  flagSpec "DerivingStrategies"               LangExt.DerivingStrategies,
+  flagSpec "DisambiguateRecordFields"         LangExt.DisambiguateRecordFields,
+  flagSpec "DoAndIfThenElse"                  LangExt.DoAndIfThenElse,
+  depFlagSpec' "DoRec"                        LangExt.RecursiveDo
     (deprecatedForExtension "RecursiveDo"),
-  flagSpec "EmptyCase"                        Opt_EmptyCase,
-  flagSpec "EmptyDataDecls"                   Opt_EmptyDataDecls,
-  flagSpec "ExistentialQuantification"        Opt_ExistentialQuantification,
-  flagSpec "ExplicitForAll"                   Opt_ExplicitForAll,
-  flagSpec "ExplicitNamespaces"               Opt_ExplicitNamespaces,
-  flagSpec "ExtendedDefaultRules"             Opt_ExtendedDefaultRules,
-  flagSpec "FlexibleContexts"                 Opt_FlexibleContexts,
-  flagSpec "FlexibleInstances"                Opt_FlexibleInstances,
-  flagSpec "ForeignFunctionInterface"         Opt_ForeignFunctionInterface,
-  flagSpec "FunctionalDependencies"           Opt_FunctionalDependencies,
-  flagSpec "GADTSyntax"                       Opt_GADTSyntax,
-  flagSpec "GADTs"                            Opt_GADTs,
-  flagSpec "GHCForeignImportPrim"             Opt_GHCForeignImportPrim,
-  flagSpec' "GeneralizedNewtypeDeriving"      Opt_GeneralizedNewtypeDeriving
+  flagSpec "DuplicateRecordFields"            LangExt.DuplicateRecordFields,
+  flagSpec "EmptyCase"                        LangExt.EmptyCase,
+  flagSpec "EmptyDataDecls"                   LangExt.EmptyDataDecls,
+  flagSpec "ExistentialQuantification"        LangExt.ExistentialQuantification,
+  flagSpec "ExplicitForAll"                   LangExt.ExplicitForAll,
+  flagSpec "ExplicitNamespaces"               LangExt.ExplicitNamespaces,
+  flagSpec "ExtendedDefaultRules"             LangExt.ExtendedDefaultRules,
+  flagSpec "FlexibleContexts"                 LangExt.FlexibleContexts,
+  flagSpec "FlexibleInstances"                LangExt.FlexibleInstances,
+  flagSpec "ForeignFunctionInterface"         LangExt.ForeignFunctionInterface,
+  flagSpec "FunctionalDependencies"           LangExt.FunctionalDependencies,
+  flagSpec "GADTSyntax"                       LangExt.GADTSyntax,
+  flagSpec "GADTs"                            LangExt.GADTs,
+  flagSpec "GHCForeignImportPrim"             LangExt.GHCForeignImportPrim,
+  flagSpec' "GeneralizedNewtypeDeriving"      LangExt.GeneralizedNewtypeDeriving
                                               setGenDeriving,
-  flagSpec "ImplicitParams"                   Opt_ImplicitParams,
-  flagSpec "ImplicitPrelude"                  Opt_ImplicitPrelude,
-  flagSpec "ImpredicativeTypes"               Opt_ImpredicativeTypes,
-  flagSpec' "IncoherentInstances"             Opt_IncoherentInstances
+  flagSpec "ImplicitParams"                   LangExt.ImplicitParams,
+  flagSpec "ImplicitPrelude"                  LangExt.ImplicitPrelude,
+  flagSpec "ImpredicativeTypes"               LangExt.ImpredicativeTypes,
+  flagSpec' "IncoherentInstances"             LangExt.IncoherentInstances
                                               setIncoherentInsts,
-  flagSpec "InstanceSigs"                     Opt_InstanceSigs,
-  flagSpec "InterruptibleFFI"                 Opt_InterruptibleFFI,
-  flagSpec "JavaScriptFFI"                    Opt_JavaScriptFFI,
-  flagSpec "KindSignatures"                   Opt_KindSignatures,
-  flagSpec "LambdaCase"                       Opt_LambdaCase,
-  flagSpec "LiberalTypeSynonyms"              Opt_LiberalTypeSynonyms,
-  flagSpec "MagicHash"                        Opt_MagicHash,
-  flagSpec "MonadComprehensions"              Opt_MonadComprehensions,
-  flagSpec "MonoLocalBinds"                   Opt_MonoLocalBinds,
-  flagSpec' "MonoPatBinds"                    Opt_MonoPatBinds
-    (\ turn_on -> when turn_on $
-         deprecate "Experimental feature now removed; has no effect"),
-  flagSpec "MonomorphismRestriction"          Opt_MonomorphismRestriction,
-  flagSpec "MultiParamTypeClasses"            Opt_MultiParamTypeClasses,
-  flagSpec "MultiWayIf"                       Opt_MultiWayIf,
-  flagSpec "NPlusKPatterns"                   Opt_NPlusKPatterns,
-  flagSpec "NamedFieldPuns"                   Opt_RecordPuns,
-  flagSpec "NamedWildCards"                   Opt_NamedWildCards,
-  flagSpec "NegativeLiterals"                 Opt_NegativeLiterals,
-  flagSpec "NondecreasingIndentation"         Opt_NondecreasingIndentation,
-  flagSpec' "NullaryTypeClasses"              Opt_NullaryTypeClasses
+  flagSpec "TypeFamilyDependencies"           LangExt.TypeFamilyDependencies,
+  flagSpec "InstanceSigs"                     LangExt.InstanceSigs,
+  flagSpec "ApplicativeDo"                    LangExt.ApplicativeDo,
+  flagSpec "InterruptibleFFI"                 LangExt.InterruptibleFFI,
+  flagSpec "JavaScriptFFI"                    LangExt.JavaScriptFFI,
+  flagSpec "KindSignatures"                   LangExt.KindSignatures,
+  flagSpec "LambdaCase"                       LangExt.LambdaCase,
+  flagSpec "LiberalTypeSynonyms"              LangExt.LiberalTypeSynonyms,
+  flagSpec "MagicHash"                        LangExt.MagicHash,
+  flagSpec "MonadComprehensions"              LangExt.MonadComprehensions,
+  flagSpec "MonadFailDesugaring"              LangExt.MonadFailDesugaring,
+  flagSpec "MonoLocalBinds"                   LangExt.MonoLocalBinds,
+  depFlagSpecCond "MonoPatBinds"              LangExt.MonoPatBinds
+    id
+         "Experimental feature now removed; has no effect",
+  flagSpec "MonomorphismRestriction"          LangExt.MonomorphismRestriction,
+  flagSpec "MultiParamTypeClasses"            LangExt.MultiParamTypeClasses,
+  flagSpec "MultiWayIf"                       LangExt.MultiWayIf,
+  flagSpec "NPlusKPatterns"                   LangExt.NPlusKPatterns,
+  flagSpec "NamedFieldPuns"                   LangExt.RecordPuns,
+  flagSpec "NamedWildCards"                   LangExt.NamedWildCards,
+  flagSpec "NegativeLiterals"                 LangExt.NegativeLiterals,
+  flagSpec "NondecreasingIndentation"         LangExt.NondecreasingIndentation,
+  depFlagSpec' "NullaryTypeClasses"           LangExt.NullaryTypeClasses
     (deprecatedForExtension "MultiParamTypeClasses"),
-  flagSpec "NumDecimals"                      Opt_NumDecimals,
-  flagSpec' "OverlappingInstances"            Opt_OverlappingInstances
-                                              setOverlappingInsts,
-  flagSpec "OverloadedLists"                  Opt_OverloadedLists,
-  flagSpec "OverloadedStrings"                Opt_OverloadedStrings,
-  flagSpec "PackageImports"                   Opt_PackageImports,
-  flagSpec "ParallelArrays"                   Opt_ParallelArrays,
-  flagSpec "ParallelListComp"                 Opt_ParallelListComp,
-  flagSpec "PartialTypeSignatures"            Opt_PartialTypeSignatures,
-  flagSpec "PatternGuards"                    Opt_PatternGuards,
-  flagSpec' "PatternSignatures"               Opt_ScopedTypeVariables
+  flagSpec "NumDecimals"                      LangExt.NumDecimals,
+  depFlagSpecOp "OverlappingInstances"        LangExt.OverlappingInstances
+    setOverlappingInsts
+    "instead use per-instance pragmas OVERLAPPING/OVERLAPPABLE/OVERLAPS",
+  flagSpec "OverloadedLabels"                 LangExt.OverloadedLabels,
+  flagSpec "OverloadedLists"                  LangExt.OverloadedLists,
+  flagSpec "OverloadedStrings"                LangExt.OverloadedStrings,
+  flagSpec "PackageImports"                   LangExt.PackageImports,
+  flagSpec "ParallelArrays"                   LangExt.ParallelArrays,
+  flagSpec "ParallelListComp"                 LangExt.ParallelListComp,
+  flagSpec "PartialTypeSignatures"            LangExt.PartialTypeSignatures,
+  flagSpec "PatternGuards"                    LangExt.PatternGuards,
+  depFlagSpec' "PatternSignatures"            LangExt.ScopedTypeVariables
     (deprecatedForExtension "ScopedTypeVariables"),
-  flagSpec "PatternSynonyms"                  Opt_PatternSynonyms,
-  flagSpec "PolyKinds"                        Opt_PolyKinds,
-  flagSpec "PolymorphicComponents"            Opt_RankNTypes,
-  flagSpec "PostfixOperators"                 Opt_PostfixOperators,
-  flagSpec "QuasiQuotes"                      Opt_QuasiQuotes,
-  flagSpec "Rank2Types"                       Opt_RankNTypes,
-  flagSpec "RankNTypes"                       Opt_RankNTypes,
-  flagSpec "RebindableSyntax"                 Opt_RebindableSyntax,
-  flagSpec' "RecordPuns"                      Opt_RecordPuns
+  flagSpec "PatternSynonyms"                  LangExt.PatternSynonyms,
+  flagSpec "PolyKinds"                        LangExt.PolyKinds,
+  flagSpec "PolymorphicComponents"            LangExt.RankNTypes,
+  flagSpec "PostfixOperators"                 LangExt.PostfixOperators,
+  flagSpec "QuasiQuotes"                      LangExt.QuasiQuotes,
+  flagSpec "Rank2Types"                       LangExt.RankNTypes,
+  flagSpec "RankNTypes"                       LangExt.RankNTypes,
+  flagSpec "RebindableSyntax"                 LangExt.RebindableSyntax,
+  depFlagSpec' "RecordPuns"                   LangExt.RecordPuns
     (deprecatedForExtension "NamedFieldPuns"),
-  flagSpec "RecordWildCards"                  Opt_RecordWildCards,
-  flagSpec "RecursiveDo"                      Opt_RecursiveDo,
-  flagSpec "RelaxedLayout"                    Opt_RelaxedLayout,
-  flagSpec' "RelaxedPolyRec"                  Opt_RelaxedPolyRec
-    (\ turn_on -> unless turn_on $
-         deprecate "You can't turn off RelaxedPolyRec any more"),
-  flagSpec "RoleAnnotations"                  Opt_RoleAnnotations,
-  flagSpec "ScopedTypeVariables"              Opt_ScopedTypeVariables,
-  flagSpec "StandaloneDeriving"               Opt_StandaloneDeriving,
-  flagSpec "StaticPointers"                   Opt_StaticPointers,
-  flagSpec' "TemplateHaskell"                 Opt_TemplateHaskell
+  flagSpec "RecordWildCards"                  LangExt.RecordWildCards,
+  flagSpec "RecursiveDo"                      LangExt.RecursiveDo,
+  flagSpec "RelaxedLayout"                    LangExt.RelaxedLayout,
+  depFlagSpecCond "RelaxedPolyRec"            LangExt.RelaxedPolyRec
+    not
+         "You can't turn off RelaxedPolyRec any more",
+  flagSpec "RoleAnnotations"                  LangExt.RoleAnnotations,
+  flagSpec "ScopedTypeVariables"              LangExt.ScopedTypeVariables,
+  flagSpec "StandaloneDeriving"               LangExt.StandaloneDeriving,
+  flagSpec "StaticPointers"                   LangExt.StaticPointers,
+  flagSpec "Strict"                           LangExt.Strict,
+  flagSpec "StrictData"                       LangExt.StrictData,
+  flagSpec' "TemplateHaskell"                 LangExt.TemplateHaskell
                                               checkTemplateHaskellOk,
-  flagSpec "TraditionalRecordSyntax"          Opt_TraditionalRecordSyntax,
-  flagSpec "TransformListComp"                Opt_TransformListComp,
-  flagSpec "TupleSections"                    Opt_TupleSections,
-  flagSpec "TypeFamilies"                     Opt_TypeFamilies,
-  flagSpec "TypeOperators"                    Opt_TypeOperators,
-  flagSpec "TypeSynonymInstances"             Opt_TypeSynonymInstances,
-  flagSpec "UnboxedTuples"                    Opt_UnboxedTuples,
-  flagSpec "UndecidableInstances"             Opt_UndecidableInstances,
-  flagSpec "UnicodeSyntax"                    Opt_UnicodeSyntax,
-  flagSpec "UnliftedFFITypes"                 Opt_UnliftedFFITypes,
-  flagSpec "ViewPatterns"                     Opt_ViewPatterns
+  flagSpec "TemplateHaskellQuotes"            LangExt.TemplateHaskellQuotes,
+  flagSpec "TraditionalRecordSyntax"          LangExt.TraditionalRecordSyntax,
+  flagSpec "TransformListComp"                LangExt.TransformListComp,
+  flagSpec "TupleSections"                    LangExt.TupleSections,
+  flagSpec "TypeApplications"                 LangExt.TypeApplications,
+  flagSpec "TypeInType"                       LangExt.TypeInType,
+  flagSpec "TypeFamilies"                     LangExt.TypeFamilies,
+  flagSpec "TypeOperators"                    LangExt.TypeOperators,
+  flagSpec "TypeSynonymInstances"             LangExt.TypeSynonymInstances,
+  flagSpec "UnboxedTuples"                    LangExt.UnboxedTuples,
+  flagSpec "UnboxedSums"                      LangExt.UnboxedSums,
+  flagSpec "UndecidableInstances"             LangExt.UndecidableInstances,
+  flagSpec "UndecidableSuperClasses"          LangExt.UndecidableSuperClasses,
+  flagSpec "UnicodeSyntax"                    LangExt.UnicodeSyntax,
+  flagSpec "UnliftedFFITypes"                 LangExt.UnliftedFFITypes,
+  flagSpec "ViewPatterns"                     LangExt.ViewPatterns
   ]
 
 defaultFlags :: Settings -> [GeneralFlag]
 defaultFlags settings
 -- See Note [Updating flag description in the User's Guide]
   = [ Opt_AutoLinkPackages,
+      Opt_DiagnosticsShowCaret,
       Opt_EmbedManifest,
       Opt_FlatCache,
       Opt_GenManifest,
       Opt_GhciHistory,
       Opt_GhciSandbox,
       Opt_HelpfulErrors,
+      Opt_KeepHiFiles,
+      Opt_KeepOFiles,
       Opt_OmitYields,
       Opt_PrintBindContents,
       Opt_ProfCountEntries,
       Opt_RPath,
       Opt_SharedImplib,
-      Opt_SimplPreInlining
+      Opt_SimplPreInlining,
+      Opt_VersionMacros
     ]
 
     ++ [f | (ns,f) <- optLevelFlags, 0 `elem` ns]
@@ -3211,9 +3913,7 @@ defaultFlags settings
 
     ++ default_PIC platform
 
-    ++ (if pc_DYNAMIC_BY_DEFAULT (sPlatformConstants settings)
-        then wayGeneralFlags platform WayDyn
-        else [])
+    ++ concatMap (wayGeneralFlags platform) (defaultWays settings)
 
     where platform = sTargetPlatform settings
 
@@ -3221,53 +3921,79 @@ default_PIC :: Platform -> [GeneralFlag]
 default_PIC platform =
   case (platformOS platform, platformArch platform) of
     (OSDarwin, ArchX86_64) -> [Opt_PIC]
+    (OSOpenBSD, ArchX86_64) -> [Opt_PIC] -- Due to PIE support in
+                                         -- OpenBSD since 5.3 release
+                                         -- (1 May 2013) we need to
+                                         -- always generate PIC. See
+                                         -- #10597 for more
+                                         -- information.
     _                      -> []
 
+-- General flags that are switched on/off when other general flags are switched
+-- on
 impliedGFlags :: [(GeneralFlag, TurnOnFlag, GeneralFlag)]
-impliedGFlags = [(Opt_DeferTypeErrors, turnOn, Opt_DeferTypedHoles)]
+impliedGFlags = [(Opt_DeferTypeErrors, turnOn, Opt_DeferTypedHoles)
+                ,(Opt_DeferTypeErrors, turnOn, Opt_DeferOutOfScopeVariables)
+                ,(Opt_Strictness, turnOn, Opt_WorkerWrapper)
+                ]
 
-impliedXFlags :: [(ExtensionFlag, TurnOnFlag, ExtensionFlag)]
+-- General flags that are switched on/off when other general flags are switched
+-- off
+impliedOffGFlags :: [(GeneralFlag, TurnOnFlag, GeneralFlag)]
+impliedOffGFlags = [(Opt_Strictness, turnOff, Opt_WorkerWrapper)]
+
+impliedXFlags :: [(LangExt.Extension, TurnOnFlag, LangExt.Extension)]
 impliedXFlags
 -- See Note [Updating flag description in the User's Guide]
-  = [ (Opt_RankNTypes,                turnOn, Opt_ExplicitForAll)
-    , (Opt_ScopedTypeVariables,       turnOn, Opt_ExplicitForAll)
-    , (Opt_LiberalTypeSynonyms,       turnOn, Opt_ExplicitForAll)
-    , (Opt_ExistentialQuantification, turnOn, Opt_ExplicitForAll)
-    , (Opt_FlexibleInstances,         turnOn, Opt_TypeSynonymInstances)
-    , (Opt_FunctionalDependencies,    turnOn, Opt_MultiParamTypeClasses)
-    , (Opt_MultiParamTypeClasses,     turnOn, Opt_ConstrainedClassMethods)  -- c.f. Trac #7854
-
-    , (Opt_RebindableSyntax, turnOff, Opt_ImplicitPrelude)      -- NB: turn off!
-
-    , (Opt_GADTs,            turnOn, Opt_GADTSyntax)
-    , (Opt_GADTs,            turnOn, Opt_MonoLocalBinds)
-    , (Opt_TypeFamilies,     turnOn, Opt_MonoLocalBinds)
-
-    , (Opt_TypeFamilies,     turnOn, Opt_KindSignatures)  -- Type families use kind signatures
-    , (Opt_PolyKinds,        turnOn, Opt_KindSignatures)  -- Ditto polymorphic kinds
+  = [ (LangExt.RankNTypes,                turnOn, LangExt.ExplicitForAll)
+    , (LangExt.ScopedTypeVariables,       turnOn, LangExt.ExplicitForAll)
+    , (LangExt.LiberalTypeSynonyms,       turnOn, LangExt.ExplicitForAll)
+    , (LangExt.ExistentialQuantification, turnOn, LangExt.ExplicitForAll)
+    , (LangExt.FlexibleInstances,         turnOn, LangExt.TypeSynonymInstances)
+    , (LangExt.FunctionalDependencies,    turnOn, LangExt.MultiParamTypeClasses)
+    , (LangExt.MultiParamTypeClasses,     turnOn, LangExt.ConstrainedClassMethods)  -- c.f. Trac #7854
+    , (LangExt.TypeFamilyDependencies,    turnOn, LangExt.TypeFamilies)
+
+    , (LangExt.RebindableSyntax, turnOff, LangExt.ImplicitPrelude)      -- NB: turn off!
+
+    , (LangExt.GADTs,            turnOn, LangExt.GADTSyntax)
+    , (LangExt.GADTs,            turnOn, LangExt.MonoLocalBinds)
+    , (LangExt.TypeFamilies,     turnOn, LangExt.MonoLocalBinds)
+
+    , (LangExt.TypeFamilies,     turnOn, LangExt.KindSignatures)  -- Type families use kind signatures
+    , (LangExt.PolyKinds,        turnOn, LangExt.KindSignatures)  -- Ditto polymorphic kinds
+    , (LangExt.TypeInType,       turnOn, LangExt.DataKinds)
+    , (LangExt.TypeInType,       turnOn, LangExt.PolyKinds)
+    , (LangExt.TypeInType,       turnOn, LangExt.KindSignatures)
 
     -- AutoDeriveTypeable is not very useful without DeriveDataTypeable
-    , (Opt_AutoDeriveTypeable, turnOn, Opt_DeriveDataTypeable)
+    , (LangExt.AutoDeriveTypeable, turnOn, LangExt.DeriveDataTypeable)
 
     -- We turn this on so that we can export associated type
     -- type synonyms in subordinates (e.g. MyClass(type AssocType))
-    , (Opt_TypeFamilies,     turnOn, Opt_ExplicitNamespaces)
-    , (Opt_TypeOperators, turnOn, Opt_ExplicitNamespaces)
+    , (LangExt.TypeFamilies,     turnOn, LangExt.ExplicitNamespaces)
+    , (LangExt.TypeOperators, turnOn, LangExt.ExplicitNamespaces)
 
-    , (Opt_ImpredicativeTypes,  turnOn, Opt_RankNTypes)
+    , (LangExt.ImpredicativeTypes,  turnOn, LangExt.RankNTypes)
 
         -- Record wild-cards implies field disambiguation
         -- Otherwise if you write (C {..}) you may well get
         -- stuff like " 'a' not in scope ", which is a bit silly
         -- if the compiler has just filled in field 'a' of constructor 'C'
-    , (Opt_RecordWildCards,     turnOn, Opt_DisambiguateRecordFields)
+    , (LangExt.RecordWildCards,     turnOn, LangExt.DisambiguateRecordFields)
+
+    , (LangExt.ParallelArrays, turnOn, LangExt.ParallelListComp)
+
+    , (LangExt.JavaScriptFFI, turnOn, LangExt.InterruptibleFFI)
 
-    , (Opt_ParallelArrays, turnOn, Opt_ParallelListComp)
+    , (LangExt.DeriveTraversable, turnOn, LangExt.DeriveFunctor)
+    , (LangExt.DeriveTraversable, turnOn, LangExt.DeriveFoldable)
 
-    , (Opt_JavaScriptFFI, turnOn, Opt_InterruptibleFFI)
+    -- Duplicate record fields require field disambiguation
+    , (LangExt.DuplicateRecordFields, turnOn, LangExt.DisambiguateRecordFields)
 
-    , (Opt_DeriveTraversable, turnOn, Opt_DeriveFunctor)
-    , (Opt_DeriveTraversable, turnOn, Opt_DeriveFoldable)
+    , (LangExt.TemplateHaskell, turnOn, LangExt.TemplateHaskellQuotes)
+    , (LangExt.Strict, turnOn, LangExt.StrictData)
   ]
 
 -- Note [Documenting optimisation flags]
@@ -3276,8 +4002,8 @@ impliedXFlags
 -- If you change the list of flags enabled for particular optimisation levels
 -- please remember to update the User's Guide. The relevant files are:
 --
---  * docs/users_guide/flags.xml
---  * docs/users_guide/using.xml
+--  * utils/mkUserGuidePart/Options/
+--  * docs/users_guide/using.rst
 --
 -- The first contains the Flag Refrence section, which breifly lists all
 -- available flags. The second contains a detailed description of the
@@ -3287,6 +4013,7 @@ impliedXFlags
 optLevelFlags :: [([Int], GeneralFlag)]
 optLevelFlags -- see Note [Documenting optimisation flags]
   = [ ([0,1,2], Opt_DoLambdaEtaExpansion)
+    , ([0,1,2], Opt_DoEtaReduction)       -- See Note [Eta-reduction in -O0]
     , ([0,1,2], Opt_DmdTxDictSel)
     , ([0,1,2], Opt_LlvmTBAA)
     , ([0,1,2], Opt_VectorisationAvoidance)
@@ -3300,10 +4027,11 @@ optLevelFlags -- see Note [Documenting optimisation flags]
 
     , ([1,2],   Opt_CallArity)
     , ([1,2],   Opt_CaseMerge)
+    , ([1,2],   Opt_CaseFolding)
     , ([1,2],   Opt_CmmElimCommonBlocks)
     , ([1,2],   Opt_CmmSink)
     , ([1,2],   Opt_CSE)
-    , ([1,2],   Opt_DoEtaReduction)
+    , ([1,2],   Opt_StgCSE)
     , ([1,2],   Opt_EnableRewriteRules)  -- Off for -O0; see Note [Scoping for Builtin rules]
                                          --              in PrelRules
     , ([1,2],   Opt_FloatIn)
@@ -3311,8 +4039,12 @@ optLevelFlags -- see Note [Documenting optimisation flags]
     , ([1,2],   Opt_IgnoreAsserts)
     , ([1,2],   Opt_Loopification)
     , ([1,2],   Opt_Specialise)
+    , ([1,2],   Opt_CrossModuleSpecialise)
     , ([1,2],   Opt_Strictness)
     , ([1,2],   Opt_UnboxSmallStrictFields)
+    , ([1,2],   Opt_CprAnal)
+    , ([1,2],   Opt_WorkerWrapper)
+    , ([1,2],   Opt_SolveConstantDicts)
 
     , ([2],     Opt_LiberateCase)
     , ([2],     Opt_SpecConstr)
@@ -3322,6 +4054,21 @@ optLevelFlags -- see Note [Documenting optimisation flags]
 --   Static Argument Transformation needs investigation. See #9374
     ]
 
+{- Note [Eta-reduction in -O0]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Trac #11562 showed an example which tripped an ASSERT in CoreToStg; a
+function was marked as MayHaveCafRefs when in fact it obviously
+didn't.  Reason was:
+ * Eta reduction wasn't happening in the simplifier, but it was
+   happening in CorePrep, on
+        $fBla = MkDict (/\a. K a)
+ * Result: rhsIsStatic told TidyPgm that $fBla might have CAF refs
+   but the eta-reduced version (MkDict K) obviously doesn't
+Simple solution: just let the simplifier do eta-reduction even in -O0.
+After all, CorePrep does it unconditionally!  Not a big deal, but
+removes an assertion failure. -}
+
+
 -- -----------------------------------------------------------------------------
 -- Standard sets of warning options
 
@@ -3331,18 +4078,65 @@ optLevelFlags -- see Note [Documenting optimisation flags]
 -- If you change the list of warning enabled by default
 -- please remember to update the User's Guide. The relevant file is:
 --
---  * docs/users_guide/using.xml
+--  * utils/mkUserGuidePart/
+--  * docs/users_guide/using-warnings.rst
+
+-- | Warning groups.
+--
+-- As all warnings are in the Weverything set, it is ignored when
+-- displaying to the user which group a warning is in.
+warningGroups :: [(String, [WarningFlag])]
+warningGroups =
+    [ ("compat",       minusWcompatOpts)
+    , ("unused-binds", unusedBindsFlags)
+    , ("default",      standardWarnings)
+    , ("extra",        minusWOpts)
+    , ("all",          minusWallOpts)
+    , ("everything",   minusWeverythingOpts)
+    ]
 
+-- | Warning group hierarchies, where there is an explicit inclusion
+-- relation.
+--
+-- Each inner list is a hierarchy of warning groups, ordered from
+-- smallest to largest, where each group is a superset of the one
+-- before it.
+--
+-- Separating this from 'warningGroups' allows for multiple
+-- hierarchies with no inherent relation to be defined.
+--
+-- The special-case Weverything group is not included.
+warningHierarchies :: [[String]]
+warningHierarchies = hierarchies ++ map (:[]) rest
+  where
+    hierarchies = [["default", "extra", "all"]]
+    rest = filter (`notElem` "everything" : concat hierarchies) $
+           map fst warningGroups
+
+-- | Find the smallest group in every hierarchy which a warning
+-- belongs to, excluding Weverything.
+smallestGroups :: WarningFlag -> [String]
+smallestGroups flag = mapMaybe go warningHierarchies where
+    -- Because each hierarchy is arranged from smallest to largest,
+    -- the first group we find in a hierarchy which contains the flag
+    -- is the smallest.
+    go (group:rest) = fromMaybe (go rest) $ do
+        flags <- lookup group warningGroups
+        guard (flag `elem` flags)
+        pure (Just group)
+    go [] = Nothing
+
+-- | Warnings enabled unless specified otherwise
 standardWarnings :: [WarningFlag]
 standardWarnings -- see Note [Documenting warning flags]
     = [ Opt_WarnOverlappingPatterns,
         Opt_WarnWarningsDeprecations,
         Opt_WarnDeprecatedFlags,
+        Opt_WarnDeferredTypeErrors,
         Opt_WarnTypedHoles,
+        Opt_WarnDeferredOutOfScopeVariables,
         Opt_WarnPartialTypeSignatures,
         Opt_WarnUnrecognisedPragmas,
-        Opt_WarnPointlessPragmas,
-        Opt_WarnRedundantConstraints,
         Opt_WarnDuplicateExports,
         Opt_WarnOverflowedLiterals,
         Opt_WarnEmptyEnumerations,
@@ -3354,36 +4148,56 @@ standardWarnings -- see Note [Documenting warning flags]
         Opt_WarnInlineRuleShadowing,
         Opt_WarnAlternativeLayoutRuleTransitional,
         Opt_WarnUnsupportedLlvmVersion,
-        Opt_WarnContextQuantification,
-        Opt_WarnTabs
+        Opt_WarnTabs,
+        Opt_WarnUnrecognisedWarningFlags,
+        Opt_WarnSimplifiableClassConstraints
       ]
 
+-- | Things you get with -W
 minusWOpts :: [WarningFlag]
--- Things you get with -W
 minusWOpts
     = standardWarnings ++
       [ Opt_WarnUnusedTopBinds,
         Opt_WarnUnusedLocalBinds,
         Opt_WarnUnusedPatternBinds,
         Opt_WarnUnusedMatches,
+        Opt_WarnUnusedForalls,
         Opt_WarnUnusedImports,
         Opt_WarnIncompletePatterns,
         Opt_WarnDodgyExports,
-        Opt_WarnDodgyImports
+        Opt_WarnDodgyImports,
+        Opt_WarnUnbangedStrictPatterns
       ]
 
+-- | Things you get with -Wall
 minusWallOpts :: [WarningFlag]
--- Things you get with -Wall
 minusWallOpts
     = minusWOpts ++
       [ Opt_WarnTypeDefaults,
         Opt_WarnNameShadowing,
-        Opt_WarnMissingSigs,
+        Opt_WarnMissingSignatures,
         Opt_WarnHiShadows,
         Opt_WarnOrphans,
         Opt_WarnUnusedDoBind,
         Opt_WarnTrustworthySafe,
-        Opt_WarnUntickedPromotedConstructors
+        Opt_WarnUntickedPromotedConstructors,
+        Opt_WarnMissingPatternSynonymSignatures
+      ]
+
+-- | Things you get with -Weverything, i.e. *all* known warnings flags
+minusWeverythingOpts :: [WarningFlag]
+minusWeverythingOpts = [ toEnum 0 .. ]
+
+-- | Things you get with -Wcompat.
+--
+-- This is intended to group together warnings that will be enabled by default
+-- at some point in the future, so that library authors eager to make their
+-- code future compatible to fix issues before they even generate warnings.
+minusWcompatOpts :: [WarningFlag]
+minusWcompatOpts
+    = [ Opt_WarnMissingMonadFailInstances
+      , Opt_WarnSemigroup
+      , Opt_WarnNonCanonicalMonoidInstances
       ]
 
 enableUnusedBinds :: DynP ()
@@ -3392,7 +4206,7 @@ enableUnusedBinds = mapM_ setWarningFlag unusedBindsFlags
 disableUnusedBinds :: DynP ()
 disableUnusedBinds = mapM_ unSetWarningFlag unusedBindsFlags
 
--- Things you get with -fwarn-unused-binds
+-- Things you get with -Wunused-binds
 unusedBindsFlags :: [WarningFlag]
 unusedBindsFlags = [ Opt_WarnUnusedTopBinds
                    , Opt_WarnUnusedLocalBinds
@@ -3407,50 +4221,46 @@ disableGlasgowExts :: DynP ()
 disableGlasgowExts = do unSetGeneralFlag Opt_PrintExplicitForalls
                         mapM_ unSetExtensionFlag glasgowExtsFlags
 
-glasgowExtsFlags :: [ExtensionFlag]
+glasgowExtsFlags :: [LangExt.Extension]
 glasgowExtsFlags = [
-             Opt_ConstrainedClassMethods
-           , Opt_DeriveDataTypeable
-           , Opt_DeriveFoldable
-           , Opt_DeriveFunctor
-           , Opt_DeriveGeneric
-           , Opt_DeriveTraversable
-           , Opt_EmptyDataDecls
-           , Opt_ExistentialQuantification
-           , Opt_ExplicitNamespaces
-           , Opt_FlexibleContexts
-           , Opt_FlexibleInstances
-           , Opt_ForeignFunctionInterface
-           , Opt_FunctionalDependencies
-           , Opt_GeneralizedNewtypeDeriving
-           , Opt_ImplicitParams
-           , Opt_KindSignatures
-           , Opt_LiberalTypeSynonyms
-           , Opt_MagicHash
-           , Opt_MultiParamTypeClasses
-           , Opt_ParallelListComp
-           , Opt_PatternGuards
-           , Opt_PostfixOperators
-           , Opt_RankNTypes
-           , Opt_RecursiveDo
-           , Opt_ScopedTypeVariables
-           , Opt_StandaloneDeriving
-           , Opt_TypeOperators
-           , Opt_TypeSynonymInstances
-           , Opt_UnboxedTuples
-           , Opt_UnicodeSyntax
-           , Opt_UnliftedFFITypes ]
-
-#ifdef GHCI
--- Consult the RTS to find whether GHC itself has been built profiled
--- If so, you can't use Template Haskell
+             LangExt.ConstrainedClassMethods
+           , LangExt.DeriveDataTypeable
+           , LangExt.DeriveFoldable
+           , LangExt.DeriveFunctor
+           , LangExt.DeriveGeneric
+           , LangExt.DeriveTraversable
+           , LangExt.EmptyDataDecls
+           , LangExt.ExistentialQuantification
+           , LangExt.ExplicitNamespaces
+           , LangExt.FlexibleContexts
+           , LangExt.FlexibleInstances
+           , LangExt.ForeignFunctionInterface
+           , LangExt.FunctionalDependencies
+           , LangExt.GeneralizedNewtypeDeriving
+           , LangExt.ImplicitParams
+           , LangExt.KindSignatures
+           , LangExt.LiberalTypeSynonyms
+           , LangExt.MagicHash
+           , LangExt.MultiParamTypeClasses
+           , LangExt.ParallelListComp
+           , LangExt.PatternGuards
+           , LangExt.PostfixOperators
+           , LangExt.RankNTypes
+           , LangExt.RecursiveDo
+           , LangExt.ScopedTypeVariables
+           , LangExt.StandaloneDeriving
+           , LangExt.TypeOperators
+           , LangExt.TypeSynonymInstances
+           , LangExt.UnboxedTuples
+           , LangExt.UnicodeSyntax
+           , LangExt.UnliftedFFITypes ]
+
 foreign import ccall unsafe "rts_isProfiled" rtsIsProfiledIO :: IO CInt
 
+-- | Was the runtime system built with profiling enabled?
 rtsIsProfiled :: Bool
 rtsIsProfiled = unsafeDupablePerformIO rtsIsProfiledIO /= 0
-#endif
 
-#ifdef GHCI
 -- Consult the RTS to find whether GHC itself has been built with
 -- dynamic linking.  This can't be statically known at compile-time,
 -- because we build both the static and dynamic versions together with
@@ -3459,10 +4269,6 @@ foreign import ccall unsafe "rts_isDynamic" rtsIsDynamicIO :: IO CInt
 
 dynamicGhc :: Bool
 dynamicGhc = unsafeDupablePerformIO rtsIsDynamicIO /= 0
-#else
-dynamicGhc :: Bool
-dynamicGhc = False
-#endif
 
 setWarnSafe :: Bool -> DynP ()
 setWarnSafe True  = getCurLoc >>= \l -> upd (\d -> d { warnSafeOnLoc = l })
@@ -3487,7 +4293,6 @@ setOverlappingInsts False = return ()
 setOverlappingInsts True = do
   l <- getCurLoc
   upd (\d -> d { overlapInstLoc = l })
-  deprecate "instead use per-instance pragmas OVERLAPPING/OVERLAPPABLE/OVERLAPS"
 
 setIncoherentInsts :: TurnOnFlag -> DynP ()
 setIncoherentInsts False = return ()
@@ -3496,27 +4301,8 @@ setIncoherentInsts True = do
   upd (\d -> d { incoherentOnLoc = l })
 
 checkTemplateHaskellOk :: TurnOnFlag -> DynP ()
-#ifdef GHCI
-checkTemplateHaskellOk turn_on
-  | turn_on && rtsIsProfiled
-  = addErr "You can't use Template Haskell with a profiled compiler"
-  | otherwise
+checkTemplateHaskellOk _turn_on
   = getCurLoc >>= \l -> upd (\d -> d { thOnLoc = l })
-#else
--- In stage 1, Template Haskell is simply illegal, except with -M
--- We don't bleat with -M because there's no problem with TH there,
--- and in fact GHC's build system does ghc -M of the DPH libraries
--- with a stage1 compiler
-checkTemplateHaskellOk turn_on
-  | turn_on = do dfs <- liftEwM getCmdLineState
-                 case ghcMode dfs of
-                    MkDepend -> return ()
-                    _        -> addErr msg
-  | otherwise = return ()
-  where
-    msg = "Template Haskell requires GHC with interpreter support\n    " ++
-          "Perhaps you are using a stage-1 compiler?"
-#endif
 
 {- **********************************************************************
 %*                                                                      *
@@ -3571,12 +4357,11 @@ addWay w = upd (addWay' w)
 addWay' :: Way -> DynFlags -> DynFlags
 addWay' w dflags0 = let platform = targetPlatform dflags0
                         dflags1 = dflags0 { ways = w : ways dflags0 }
-                        dflags2 = wayExtras platform w dflags1
-                        dflags3 = foldr setGeneralFlag' dflags2
+                        dflags2 = foldr setGeneralFlag' dflags1
                                         (wayGeneralFlags platform w)
-                        dflags4 = foldr unSetGeneralFlag' dflags3
+                        dflags3 = foldr unSetGeneralFlag' dflags2
                                         (wayUnsetGeneralFlags platform w)
-                    in dflags4
+                    in dflags3
 
 removeWayDyn :: DynP ()
 removeWayDyn = upd (\dfs -> dfs { ways = filter (WayDyn /=) (ways dfs) })
@@ -3597,20 +4382,33 @@ setGeneralFlag' f dflags = foldr ($) (gopt_set dflags f) deps
         --     implies further flags
 
 unSetGeneralFlag' :: GeneralFlag -> DynFlags -> DynFlags
-unSetGeneralFlag' f dflags = gopt_unset dflags f
-   -- When you un-set f, however, we don't un-set the things it implies
+unSetGeneralFlag' f dflags = foldr ($) (gopt_unset dflags f) deps
+  where
+    deps = [ if turn_on then setGeneralFlag' d
+                        else unSetGeneralFlag' d
+           | (f', turn_on, d) <- impliedOffGFlags, f' == f ]
+   -- In general, when you un-set f, we don't un-set the things it implies.
+   -- There are however some exceptions, e.g., -fno-strictness implies
+   -- -fno-worker-wrapper.
+   --
+   -- NB: use unSetGeneralFlag' recursively, in case the implied off flags
+   --     imply further flags.
 
 --------------------------
 setWarningFlag, unSetWarningFlag :: WarningFlag -> DynP ()
 setWarningFlag   f = upd (\dfs -> wopt_set dfs f)
 unSetWarningFlag f = upd (\dfs -> wopt_unset dfs f)
 
+setFatalWarningFlag, unSetFatalWarningFlag :: WarningFlag -> DynP ()
+setFatalWarningFlag   f = upd (\dfs -> wopt_set_fatal dfs f)
+unSetFatalWarningFlag f = upd (\dfs -> wopt_unset_fatal dfs f)
+
 --------------------------
-setExtensionFlag, unSetExtensionFlag :: ExtensionFlag -> DynP ()
+setExtensionFlag, unSetExtensionFlag :: LangExt.Extension -> DynP ()
 setExtensionFlag f = upd (setExtensionFlag' f)
 unSetExtensionFlag f = upd (unSetExtensionFlag' f)
 
-setExtensionFlag', unSetExtensionFlag' :: ExtensionFlag -> DynFlags -> DynFlags
+setExtensionFlag', unSetExtensionFlag' :: LangExt.Extension -> DynFlags -> DynFlags
 setExtensionFlag' f dflags = foldr ($) (xopt_set dflags f) deps
   where
     deps = [ if turn_on then setExtensionFlag'   d
@@ -3656,8 +4454,8 @@ setVerboseCore2Core = setDumpFlag' Opt_D_verbose_core2core
 setVerbosity :: Maybe Int -> DynP ()
 setVerbosity mb_n = upd (\dfs -> dfs{ verbosity = mb_n `orElse` 3 })
 
-addCmdlineHCInclude :: String -> DynP ()
-addCmdlineHCInclude a = upd (\s -> s{cmdlineHcIncludes =  a : cmdlineHcIncludes s})
+setDebugLevel :: Maybe Int -> DynP ()
+setDebugLevel mb_n = upd (\dfs -> dfs{ debugLevel = mb_n `orElse` 2 })
 
 data PkgConfRef
   = GlobalPkgConf
@@ -3682,22 +4480,22 @@ removeGlobalPkgConf = upd $ \s -> s { extraPkgConfs = filter isNotGlobal . extra
 clearPkgConf :: DynP ()
 clearPkgConf = upd $ \s -> s { extraPkgConfs = const [] }
 
-parseModuleName :: ReadP ModuleName
-parseModuleName = fmap mkModuleName
-                $ munch1 (\c -> isAlphaNum c || c `elem` ".")
-
-parsePackageFlag :: (String -> PackageArg) -- type of argument
+parsePackageFlag :: String                 -- the flag
+                 -> ReadP PackageArg       -- type of argument
                  -> String                 -- string to parse
                  -> PackageFlag
-parsePackageFlag constr str = case filter ((=="").snd) (readP_to_S parse str) of
+parsePackageFlag flag arg_parse str
+ = case filter ((=="").snd) (readP_to_S parse str) of
     [(r, "")] -> r
     _ -> throwGhcException $ CmdLineError ("Can't parse package flag: " ++ str)
-  where parse = do
-            pkg <- tok $ munch1 (\c -> isAlphaNum c || c `elem` ":-_.")
+  where doc = flag ++ " " ++ str
+        parse = do
+            pkg_arg <- tok arg_parse
+            let mk_expose = ExposePackage doc pkg_arg
             ( do _ <- tok $ string "with"
-                 fmap (ExposePackage (constr pkg) . ModRenaming True) parseRns
-             <++ fmap (ExposePackage (constr pkg) . ModRenaming False) parseRns
-             <++ return (ExposePackage (constr pkg) (ModRenaming True [])))
+                 fmap (mk_expose . ModRenaming True) parseRns
+             <++ fmap (mk_expose . ModRenaming False) parseRns
+             <++ return (mk_expose (ModRenaming True [])))
         parseRns = do _ <- tok $ R.char '('
                       rns <- tok $ sepBy parseItem (tok $ R.char ',')
                       _ <- tok $ R.char ')'
@@ -3711,76 +4509,112 @@ parsePackageFlag constr str = case filter ((=="").snd) (readP_to_S parse str) of
              return (orig, orig))
         tok m = m >>= \x -> skipSpaces >> return x
 
-exposePackage, exposePackageId, exposePackageKey, hidePackage, ignorePackage,
+exposePackage, exposePackageId, hidePackage,
+        exposePluginPackage, exposePluginPackageId,
+        ignorePackage,
         trustPackage, distrustPackage :: String -> DynP ()
 exposePackage p = upd (exposePackage' p)
 exposePackageId p =
   upd (\s -> s{ packageFlags =
-    parsePackageFlag PackageIdArg p : packageFlags s })
-exposePackageKey p =
-  upd (\s -> s{ packageFlags =
-    parsePackageFlag PackageKeyArg p : packageFlags s })
+    parsePackageFlag "-package-id" parseUnitIdArg p : packageFlags s })
+exposePluginPackage p =
+  upd (\s -> s{ pluginPackageFlags =
+    parsePackageFlag "-plugin-package" parsePackageArg p : pluginPackageFlags s })
+exposePluginPackageId p =
+  upd (\s -> s{ pluginPackageFlags =
+    parsePackageFlag "-plugin-package-id" parseUnitIdArg p : pluginPackageFlags s })
 hidePackage p =
   upd (\s -> s{ packageFlags = HidePackage p : packageFlags s })
 ignorePackage p =
-  upd (\s -> s{ packageFlags = IgnorePackage p : packageFlags s })
+  upd (\s -> s{ ignorePackageFlags = IgnorePackage p : ignorePackageFlags s })
+
 trustPackage p = exposePackage p >> -- both trust and distrust also expose a package
-  upd (\s -> s{ packageFlags = TrustPackage p : packageFlags s })
+  upd (\s -> s{ trustFlags = TrustPackage p : trustFlags s })
 distrustPackage p = exposePackage p >>
-  upd (\s -> s{ packageFlags = DistrustPackage p : packageFlags s })
+  upd (\s -> s{ trustFlags = DistrustPackage p : trustFlags s })
 
 exposePackage' :: String -> DynFlags -> DynFlags
 exposePackage' p dflags
     = dflags { packageFlags =
-            parsePackageFlag PackageArg p : packageFlags dflags }
+            parsePackageFlag "-package" parsePackageArg p : packageFlags dflags }
+
+parsePackageArg :: ReadP PackageArg
+parsePackageArg =
+    fmap PackageArg (munch1 (\c -> isAlphaNum c || c `elem` ":-_."))
+
+parseUnitIdArg :: ReadP PackageArg
+parseUnitIdArg =
+    fmap UnitIdArg parseUnitId
+
+setUnitId :: String -> DynFlags -> DynFlags
+setUnitId p d = d { thisInstalledUnitId = stringToInstalledUnitId p }
+
+-- | Given a 'ModuleName' of a signature in the home library, find
+-- out how it is instantiated.  E.g., the canonical form of
+-- A in @p[A=q[]:A]@ is @q[]:A@.
+canonicalizeHomeModule :: DynFlags -> ModuleName -> Module
+canonicalizeHomeModule dflags mod_name =
+    case lookup mod_name (thisUnitIdInsts dflags) of
+        Nothing  -> mkModule (thisPackage dflags) mod_name
+        Just mod -> mod
 
-setPackageKey :: String -> DynFlags -> DynFlags
-setPackageKey p s =  s{ thisPackage = stringToPackageKey p }
 
 -- -----------------------------------------------------------------------------
 -- | Find the package environment (if one exists)
 --
 -- We interpret the package environment as a set of package flags; to be
--- specific, if we find a package environment
+-- specific, if we find a package environment file like
 --
--- > id1
--- > id2
--- > ..
--- > idn
+-- > clear-package-db
+-- > global-package-db
+-- > package-db blah/package.conf.d
+-- > package-id id1
+-- > package-id id2
 --
 -- we interpret this as
 --
 -- > [ -hide-all-packages
+-- > , -clear-package-db
+-- > , -global-package-db
+-- > , -package-db blah/package.conf.d
 -- > , -package-id id1
 -- > , -package-id id2
--- > , ..
--- > , -package-id idn
 -- > ]
+--
+-- There's also an older syntax alias for package-id, which is just an
+-- unadorned package id
+--
+-- > id1
+-- > id2
+--
 interpretPackageEnv :: DynFlags -> IO DynFlags
 interpretPackageEnv dflags = do
     mPkgEnv <- runMaybeT $ msum $ [
                    getCmdLineArg >>= \env -> msum [
-                       loadEnvFile  env
-                     , loadEnvName  env
+                       probeEnvFile env
+                     , probeEnvName env
                      , cmdLineError env
                      ]
                  , getEnvVar >>= \env -> msum [
-                       loadEnvFile env
-                     , loadEnvName env
-                     , envError    env
+                       probeEnvFile env
+                     , probeEnvName env
+                     , envError     env
+                     ]
+                 , notIfHideAllPackages >> msum [
+                       findLocalEnvFile >>= probeEnvFile
+                     , probeEnvName defaultEnvName
                      ]
-                 , loadEnvFile localEnvFile
-                 , loadEnvName defaultEnvName
                  ]
     case mPkgEnv of
       Nothing ->
         -- No environment found. Leave DynFlags unchanged.
         return dflags
-      Just ids -> do
+      Just envfile -> do
+        content <- readFile envfile
         let setFlags :: DynP ()
             setFlags = do
               setGeneralFlag Opt_HideAllPackages
-              mapM_ exposePackageId (lines ids)
+              parseEnvFile envfile content
 
             (_, dflags') = runCmdLine (runEwM setFlags) dflags
 
@@ -3790,16 +4624,36 @@ interpretPackageEnv dflags = do
 
     namedEnvPath :: String -> MaybeT IO FilePath
     namedEnvPath name = do
-     appdir <- liftMaybeT $ versionedAppDir dflags
+     appdir <- versionedAppDir dflags
      return $ appdir </> "environments" </> name
 
-    loadEnvName :: String -> MaybeT IO String
-    loadEnvName name = loadEnvFile =<< namedEnvPath name
+    probeEnvName :: String -> MaybeT IO FilePath
+    probeEnvName name = probeEnvFile =<< namedEnvPath name
 
-    loadEnvFile :: String -> MaybeT IO String
-    loadEnvFile path = do
+    probeEnvFile :: FilePath -> MaybeT IO FilePath
+    probeEnvFile path = do
       guard =<< liftMaybeT (doesFileExist path)
-      liftMaybeT $ readFile path
+      return path
+
+    parseEnvFile :: FilePath -> String -> DynP ()
+    parseEnvFile envfile = mapM_ parseEntry . lines
+      where
+        parseEntry str = case words str of
+          ("package-db": _)     -> addPkgConfRef (PkgConfFile (envdir </> db))
+            -- relative package dbs are interpreted relative to the env file
+            where envdir = takeDirectory envfile
+                  db     = drop 11 str
+          ["clear-package-db"]  -> clearPkgConf
+          ["global-package-db"] -> addPkgConfRef GlobalPkgConf
+          ["user-package-db"]   -> addPkgConfRef UserPkgConf
+          ["package-id", pkgid] -> exposePackageId pkgid
+          (('-':'-':_):_)       -> return () -- comments
+          -- and the original syntax introduced in 7.10:
+          [pkgid]               -> exposePackageId pkgid
+          []                    -> return ()
+          _                     -> throwGhcException $ CmdLineError $
+                                        "Can't parse environment file entry: "
+                                     ++ envfile ++ ": " ++ str
 
     -- Various ways to define which environment to use
 
@@ -3814,11 +4668,34 @@ interpretPackageEnv dflags = do
         Left err  -> if isDoesNotExistError err then mzero
                                                 else liftMaybeT $ throwIO err
 
+    notIfHideAllPackages :: MaybeT IO ()
+    notIfHideAllPackages =
+      guard (not (gopt Opt_HideAllPackages dflags))
+
     defaultEnvName :: String
     defaultEnvName = "default"
 
-    localEnvFile :: FilePath
-    localEnvFile = "./.ghc.environment"
+    -- e.g. .ghc.environment.x86_64-linux-7.6.3
+    localEnvFileName :: FilePath
+    localEnvFileName = ".ghc.environment" <.> versionedFilePath dflags
+
+    -- Search for an env file, starting in the current dir and looking upwards.
+    -- Fail if we get to the users home dir or the filesystem root. That is,
+    -- we don't look for an env file in the user's home dir. The user-wide
+    -- env lives in ghc's versionedAppDir/environments/default
+    findLocalEnvFile :: MaybeT IO FilePath
+    findLocalEnvFile = do
+        curdir  <- liftMaybeT getCurrentDirectory
+        homedir <- tryMaybeT getHomeDirectory
+        let probe dir | isDrive dir || dir == homedir
+                      = mzero
+            probe dir = do
+              let file = dir </> localEnvFileName
+              exists <- liftMaybeT (doesFileExist file)
+              if exists
+                then return file
+                else probe (takeDirectory dir)
+        probe curdir
 
     -- Error reporting
 
@@ -3830,7 +4707,7 @@ interpretPackageEnv dflags = do
     envError env = liftMaybeT . throwGhcExceptionIO . CmdLineError $
          "Package environment "
       ++ show env
-      ++ " (specified in GHC_ENVIRIONMENT) not found"
+      ++ " (specified in GHC_ENVIRONMENT) not found"
 
 
 -- If we're linking a binary, then only targets that produce object
@@ -3859,13 +4736,14 @@ setObjTarget l = updM set
      | otherwise = return dflags
 
 setOptLevel :: Int -> DynFlags -> DynP DynFlags
-setOptLevel n dflags
+setOptLevel n dflags = return (updOptLevel n dflags)
+
+checkOptLevel :: Int -> DynFlags -> Either String DynFlags
+checkOptLevel n dflags
    | hscTarget dflags == HscInterpreted && n > 0
-        = do addWarn "-O conflicts with --interactive; -O ignored."
-             return dflags
+     = Left "-O conflicts with --interactive; -O ignored."
    | otherwise
-        = return (updOptLevel n dflags)
-
+     = Right dflags
 
 -- -Odph is equivalent to
 --
@@ -3882,14 +4760,14 @@ setMainIs :: String -> DynP ()
 setMainIs arg
   | not (null main_fn) && isLower (head main_fn)
      -- The arg looked like "Foo.Bar.baz"
-  = upd $ \d -> d{ mainFunIs = Just main_fn,
-                   mainModIs = mkModule mainPackageKey (mkModuleName main_mod) }
+  = upd $ \d -> d { mainFunIs = Just main_fn,
+                   mainModIs = mkModule mainUnitId (mkModuleName main_mod) }
 
   | isUpper (head arg)  -- The arg looked like "Foo" or "Foo.Bar"
-  = upd $ \d -> d{ mainModIs = mkModule mainPackageKey (mkModuleName arg) }
+  = upd $ \d -> d { mainModIs = mkModule mainUnitId (mkModuleName arg) }
 
   | otherwise                   -- The arg looked like "baz"
-  = upd $ \d -> d{ mainFunIs = Just arg }
+  = upd $ \d -> d { mainFunIs = Just arg }
   where
     (main_mod, main_fn) = splitLongestPrefix arg (== '.')
 
@@ -3992,7 +4870,7 @@ setRtsOptsEnabled arg  = upd $ \ d -> d {rtsOptsEnabled = arg}
 -- Hpc stuff
 
 setOptHpcDir :: String -> DynP ()
-setOptHpcDir arg  = upd $ \ d -> d{hpcDir = arg}
+setOptHpcDir arg  = upd $ \ d -> d {hpcDir = arg}
 
 -----------------------------------------------------------------------------
 -- Via-C compilation stuff
@@ -4031,7 +4909,7 @@ picCCOpts dflags
       -- correctly.  They need to reference data in the Haskell
       -- objects, but can't without -fPIC.  See
       -- http://ghc.haskell.org/trac/ghc/wiki/Commentary/PositionIndependentCode
-       | gopt Opt_PIC dflags || not (gopt Opt_Static dflags) ->
+       | gopt Opt_PIC dflags || WayDyn `elem` ways dflags ->
           ["-fPIC", "-U__PIC__", "-D__PIC__"]
        | otherwise                             -> []
 
@@ -4072,24 +4950,46 @@ compilerInfo dflags
        ("Support SMP",                 cGhcWithSMP),
        ("Tables next to code",         cGhcEnableTablesNextToCode),
        ("RTS ways",                    cGhcRTSWays),
-       ("Support dynamic-too",         if isWindows then "NO" else "YES"),
+       ("RTS expects libdw",           showBool cGhcRtsWithLibdw),
+       -- Whether or not we support @-dynamic-too@
+       ("Support dynamic-too",         showBool $ not isWindows),
+       -- Whether or not we support the @-j@ flag with @--make@.
        ("Support parallel --make",     "YES"),
+       -- Whether or not we support "Foo from foo-0.1-XXX:Foo" syntax in
+       -- installed package info.
        ("Support reexported-modules",  "YES"),
+       -- Whether or not we support extended @-package foo (Foo)@ syntax.
        ("Support thinning and renaming package flags", "YES"),
+       -- Whether or not we support Backpack.
+       ("Support Backpack", "YES"),
+       -- If true, we require that the 'id' field in installed package info
+       -- match what is passed to the @-this-unit-id@ flag for modules
+       -- built in it
+       ("Requires unified installed package IDs", "YES"),
+       -- Whether or not we support the @-this-package-key@ flag.  Prefer
+       -- "Uses unit IDs" over it.
        ("Uses package keys",           "YES"),
-       ("Dynamic by default",          if dYNAMIC_BY_DEFAULT dflags
-                                       then "YES" else "NO"),
-       ("GHC Dynamic",                 if dynamicGhc
-                                       then "YES" else "NO"),
+       -- Whether or not we support the @-this-unit-id@ flag
+       ("Uses unit IDs",               "YES"),
+       -- Whether or not GHC compiles libraries as dynamic by default
+       ("Dynamic by default",          showBool $ dYNAMIC_BY_DEFAULT dflags),
+       -- Whether or not GHC was compiled using -dynamic
+       ("GHC Dynamic",                 showBool dynamicGhc),
+       -- Whether or not GHC was compiled using -prof
+       ("GHC Profiled",                showBool rtsIsProfiled),
        ("Leading underscore",          cLeadingUnderscore),
        ("Debug on",                    show debugIsOn),
        ("LibDir",                      topDir dflags),
+       -- The path of the global package database used by GHC
        ("Global Package DB",           systemPackageConfig dflags)
       ]
   where
+    showBool True  = "YES"
+    showBool False = "NO"
     isWindows = platformOS (targetPlatform dflags) == OSMinGW32
 
-#include "../includes/dist-derivedconstants/header/GHCConstantsHaskellWrappers.hs"
+-- Produced by deriveConstants
+#include "GHCConstantsHaskellWrappers.hs"
 
 bLOCK_SIZE_W :: DynFlags -> Int
 bLOCK_SIZE_W dflags = bLOCK_SIZE dflags `quot` wORD_SIZE dflags
@@ -4121,10 +5021,40 @@ tARGET_MAX_WORD dflags
       8 -> toInteger (maxBound :: Word64)
       w -> panic ("tARGET_MAX_WORD: Unknown platformWordSize: " ++ show w)
 
+
+{- -----------------------------------------------------------------------------
+Note [DynFlags consistency]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are a number of number of DynFlags configurations which either
+do not make sense or lead to unimplemented or buggy codepaths in the
+compiler. makeDynFlagsConsistent is responsible for verifying the validity
+of a set of DynFlags, fixing any issues, and reporting them back to the
+caller.
+
+GHCi and -O
+---------------
+
+When using optimization, the compiler can introduce several things
+(such as unboxed tuples) into the intermediate code, which GHCi later
+chokes on since the bytecode interpreter can't handle this (and while
+this is arguably a bug these aren't handled, there are no plans to fix
+it.)
+
+While the driver pipeline always checks for this particular erroneous
+combination when parsing flags, we also need to check when we update
+the flags; this is because API clients may parse flags but update the
+DynFlags afterwords, before finally running code inside a session (see
+T10052 and #10052).
+-}
+
+-- | Resolve any internal inconsistencies in a set of 'DynFlags'.
+-- Returns the consistent 'DynFlags' as well as a list of warnings
+-- to report to the user.
+makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Located String])
 -- Whenever makeDynFlagsConsistent does anything, it starts over, to
 -- ensure that a later change doesn't invalidate an earlier check.
 -- Be careful not to introduce potential loops!
-makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Located String])
 makeDynFlagsConsistent dflags
  -- Disable -dynamic-too on Windows (#8228, #7134, #5987)
  | os == OSMinGW32 && gopt Opt_BuildDynamicToo dflags
@@ -4140,6 +5070,10 @@ makeDynFlagsConsistent dflags
       else let dflags' = dflags { hscTarget = HscLlvm }
                warn = "Compiler not unregisterised, so using LLVM rather than compiling via C"
            in loop dflags' warn
+ | gopt Opt_Hpc dflags && hscTarget dflags == HscInterpreted
+    = let dflags' = gopt_unset dflags Opt_Hpc
+          warn = "Hpc can't be used with byte-code interpreter. Ignoring -fhpc."
+      in loop dflags' warn
  | hscTarget dflags == HscAsm &&
    platformUnregisterised (targetPlatform dflags)
     = loop (dflags { hscTarget = HscC })
@@ -4152,7 +5086,7 @@ makeDynFlagsConsistent dflags
  | hscTarget dflags == HscLlvm &&
    not ((arch == ArchX86_64) && (os == OSLinux || os == OSDarwin || os == OSFreeBSD)) &&
    not ((isARM arch) && (os == OSLinux)) &&
-   (not (gopt Opt_Static dflags) || gopt Opt_PIC dflags)
+   (gopt Opt_PIC dflags || WayDyn `elem` ways dflags)
     = if cGhcWithNativeCodeGen == "YES"
       then let dflags' = dflags { hscTarget = HscAsm }
                warn = "Using native code generator rather than LLVM, as LLVM is incompatible with -fPIC and -dynamic on this platform"
@@ -4163,6 +5097,17 @@ makeDynFlagsConsistent dflags
    not (gopt Opt_PIC dflags)
     = loop (gopt_set dflags Opt_PIC)
            "Enabling -fPIC as it is always on for this platform"
+ | Left err <- checkOptLevel (optLevel dflags) dflags
+    = loop (updOptLevel 0 dflags) err
+
+ | LinkInMemory <- ghcLink dflags
+ , not (gopt Opt_ExternalInterpreter dflags)
+ , rtsIsProfiled
+ , isObjectTarget (hscTarget dflags)
+ , WayProf `notElem` ways dflags
+    = loop dflags{ways = WayProf : ways dflags}
+         "Enabling -prof, because -fobject-code is enabled and GHCi is profiled"
+
  | otherwise = (dflags, [])
     where loc = mkGeneralSrcSpan (fsLit "when making flags consistent")
           loop updated_dflags warning
@@ -4172,6 +5117,7 @@ makeDynFlagsConsistent dflags
           arch = platformArch platform
           os   = platformOS   platform
 
+
 --------------------------------------------------------------------------
 -- Do not use unsafeGlobalDynFlags!
 --
@@ -4182,7 +5128,23 @@ makeDynFlagsConsistent dflags
 -- Do not use it if you can help it. You may get the wrong value, or this
 -- panic!
 
-GLOBAL_VAR(v_unsafeGlobalDynFlags, panic "v_unsafeGlobalDynFlags: not initialised", DynFlags)
+-- | This is the value that 'unsafeGlobalDynFlags' takes before it is
+-- initialized.
+defaultGlobalDynFlags :: DynFlags
+defaultGlobalDynFlags =
+    (defaultDynFlags settings) { verbosity = 2 }
+  where
+    settings = panic "v_unsafeGlobalDynFlags: not initialised"
+
+#if STAGE < 2
+GLOBAL_VAR(v_unsafeGlobalDynFlags, defaultGlobalDynFlags, DynFlags)
+#else
+SHARED_GLOBAL_VAR( v_unsafeGlobalDynFlags
+                 , getOrSetLibHSghcGlobalDynFlags
+                 , "getOrSetLibHSghcGlobalDynFlags"
+                 , defaultGlobalDynFlags
+                 , DynFlags )
+#endif
 
 unsafeGlobalDynFlags :: DynFlags
 unsafeGlobalDynFlags = unsafePerformIO $ readIORef v_unsafeGlobalDynFlags
@@ -4251,6 +5213,7 @@ data LinkerInfo
   | GnuGold  [Option]
   | DarwinLD [Option]
   | SolarisLD [Option]
+  | AixLD    [Option]
   | UnknownLD
   deriving Eq