    {-# LANGUAGE ImportQualifiedPost #-}
    {-# LANGUAGE LambdaCase, NamedFieldPuns, ScopedTypeVariables #-}

    {-
        Suggest removal of unnecessary extensions
        i.e. They have {-# LANGUAGE RecursiveDo #-} but no mdo keywords
    <TEST>
    {-# LANGUAGE Arrows #-} \
    f = id --
    {-# LANGUAGE RebindableSyntax #-} \
    f = id
    {-# LANGUAGE RebindableSyntax, ParallelListComp, ImplicitParams #-} \
    f = [(a,c) | a <- b | c <- d] -- {-# LANGUAGE RebindableSyntax, ParallelListComp #-}
    {-# LANGUAGE EmptyDataDecls #-} \
    data Foo
    {-# LANGUAGE TemplateHaskell #-} \
    $(deriveNewtypes typeInfo)
    {-# LANGUAGE TemplateHaskell #-} \
    main = foo ''Bar --
    {-# LANGUAGE QuasiQuotes, TemplateHaskell #-} \
    f x = x + [e| x + 1 |] + [foo| x + 1 |] -- {-# LANGUAGE QuasiQuotes #-}
    {-# LANGUAGE PatternGuards #-} \
    test = case x of _ | y <- z -> w
    {-# LANGUAGE TemplateHaskell,EmptyDataDecls #-} \
    $(fmap return $ dataD (return []) (mkName "Void") [] [] [])
    {-# LANGUAGE RecursiveDo #-} \
    main = mdo x <- y; return y
    {-# LANGUAGE RecursiveDo #-} \
    main = do {rec {x <- return 1}; print x}
    {-# LANGUAGE ImplicitParams, BangPatterns #-} \
    sort :: (?cmp :: a -> a -> Bool) => [a] -> [a] \
    sort !f = undefined
    {-# LANGUAGE KindSignatures #-} \
    data Set (cxt :: * -> *) a = Set [a]
    {-# LANGUAGE BangPatterns #-} \
    foo x = let !y = x in y
    {-# LANGUAGE BangPatterns #-} \
    data Foo = Foo !Int --
    {-# LANGUAGE TypeOperators #-} \
    data (<+>) a b = Foo a b
    {-# LANGUAGE TypeOperators #-} \
    data Foo a b = a :+ b --
    {-# LANGUAGE TypeOperators #-} \
    type (<+>) a b = Foo a b
    {-# LANGUAGE TypeOperators #-} \
    type Foo a b = a :+ b
    {-# LANGUAGE TypeOperators, TypeFamilies #-} \
    type family Foo a b :: Type where Foo a b = a :+ b
    {-# LANGUAGE TypeOperators, TypeFamilies #-} \
    type family Foo a b :: Type where Foo a b = (<+>) a b -- {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE TypeOperators, TypeFamilies #-} \
    class Foo a where data (<+>) a
    {-# LANGUAGE TypeOperators, TypeFamilies #-} \
    class Foo a where foo :: a -> Int <+> Bool
    {-# LANGUAGE TypeOperators #-} \
    class (<+>) a where
    {-# LANGUAGE TypeOperators #-} \
    foo :: Int -> Double <+> Bool \
    foo x = y
    {-# LANGUAGE TypeOperators #-} \
    foo :: Int -> (<+>) Double Bool \
    foo x = y --
    {-# LANGUAGE TypeOperators #-} \
    (<+>) :: Int -> Int -> Int \
    x <+> y = x + y --
    {-# LANGUAGE RecordWildCards #-} \
    record field = Record{..}
    {-# LANGUAGE RecordWildCards #-} \
    record = 1 -- @Note may require `{-# LANGUAGE DisambiguateRecordFields #-}` adding to the top of the file
    {-# LANGUAGE RecordWildCards #-} \
    {-# LANGUAGE DisambiguateRecordFields #-} \
    record = 1 -- @NoNote
    {-# LANGUAGE UnboxedTuples #-} \
    record = 1 --
    {-# LANGUAGE TemplateHaskell #-} \
    foo
    {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-} \
    record = 1 --
    {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-} \
    newtype Foo = Foo Int deriving Data -- {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-} \
    data Foo = Foo Int deriving Data -- {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-} \
    newtype Foo = Foo Int deriving Class -- {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-} \
    data Foo = Foo Int deriving Class --
    {-# LANGUAGE DeriveFunctor #-} \
    data Foo = Foo Int deriving Functor
    {-# LANGUAGE DeriveFunctor #-} \
    newtype Foo = Foo Int deriving Functor
    {-# LANGUAGE GeneralizedNewtypeDeriving #-} \
    newtype Foo = Foo Int deriving Functor
    {-# LANGUAGE GeneralizedNewtypeDeriving #-} \
    newtype Foo = Foo Int deriving Data --
    {-# LANGUAGE DeriveFunctor, GeneralizedNewtypeDeriving, StandaloneDeriving #-} \
    deriving instance Functor Bar
    {-# LANGUAGE DeriveFunctor, GeneralizedNewtypeDeriving, StandaloneDeriving #-} \
    deriving instance Show Bar -- {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE DeriveGeneric, GeneralizedNewtypeDeriving #-} \
    newtype Micro = Micro Int deriving Generic -- {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE DeriveGeneric, TypeFamilies #-} \
    data family Bar a; data instance Bar Foo = Foo deriving Generic
    {-# LANGUAGE GeneralizedNewtypeDeriving #-} \
    instance Class Int where {newtype MyIO a = MyIO a deriving NewClass}
    {-# LANGUAGE UnboxedTuples #-} \
    f :: Int -> (# Int, Int #)
    {-# LANGUAGE UnboxedTuples #-} \
    f :: x -> (x, x); f x = (x, x) --
    {-# LANGUAGE UnboxedTuples #-} \
    f x = case x of (# a, b #) -> a
    {-# LANGUAGE GeneralizedNewtypeDeriving,UnboxedTuples #-} \
    newtype T m a = T (m a) deriving (PrimMonad)
    {-# LANGUAGE InstanceSigs #-} \
    instance Eq a => Eq (T a) where \
      (==) :: T a -> T a -> Bool \
      (==) (T x) (T y) = x==y
    {-# LANGUAGE InstanceSigs #-} \
    instance Eq a => Eq (T a) where \
      (==) (T x) (T y) = x==y --
    {-# LANGUAGE DefaultSignatures #-} \
    class Val a where; val :: a --
    {-# LANGUAGE DefaultSignatures #-} \
    class Val a where; val :: a; default val :: Int
    {-# LANGUAGE TypeApplications #-} \
    foo = id --
    {-# LANGUAGE TypeApplications #-} \
    foo = id @Int
    {-# LANGUAGE TypeApplications #-} \
    x :: Typeable b => TypeRep @Bool b
    {-# LANGUAGE LambdaCase #-} \
    foo = id --
    {-# LANGUAGE LambdaCase #-} \
    foo = \case () -> ()
    {-# LANGUAGE NumDecimals #-} \
    foo = 12.3e2
    {-# LANGUAGE NumDecimals #-} \
    foo = id --
    {-# LANGUAGE NumDecimals #-} \
    foo = 12.345e2 --
    {-# LANGUAGE TupleSections #-} \
    main = map (,1,2) xs
    {-# LANGUAGE TupleSections #-} \
    main = id --
    {-# LANGUAGE OverloadedStrings #-} \
    main = "test"
    {-# LANGUAGE OverloadedStrings #-} \
    main = id --
    {-# LANGUAGE OverloadedLists #-} \
    main = []
    {-# LANGUAGE OverloadedLists #-} \
    main = [1]
    {-# LANGUAGE OverloadedLists #-} \
    main [1] = True
    {-# LANGUAGE OverloadedLists #-} \
    main = id --
    {-# LANGUAGE OverloadedLabels #-} \
    main = #foo
    {-# LANGUAGE OverloadedLabels #-} \
    main = id --
    {-# LANGUAGE DeriveAnyClass #-} \
    main = id --
    {-# LANGUAGE DeriveAnyClass #-} \
    data Foo = Foo deriving Bob
    {-# LANGUAGE DeriveAnyClass #-} \
    data Foo a = Foo a deriving (Eq,Data,Functor) --
    {-# LANGUAGE MagicHash #-} \
    foo# = id
    {-# LANGUAGE MagicHash #-} \
    main = "foo"#
    {-# LANGUAGE MagicHash #-} \
    main = 5#
    {-# LANGUAGE MagicHash #-} \
    main = 'a'#
    {-# LANGUAGE MagicHash #-} \
    main = 5.6#
    {-# LANGUAGE MagicHash #-} \
    foo = id --
    {-# LANGUAGE GeneralizedNewtypeDeriving #-} \
    newtype X = X Int deriving newtype Show
    {-# LANGUAGE EmptyCase #-} \
    main = case () of {}
    {-# LANGUAGE EmptyCase #-} \
    main = case () of x -> x --
    {-# LANGUAGE EmptyCase #-} \
    main = case () of x -> x --
    {-# LANGUAGE PolyKinds, KindSignatures #-} -- {-# LANGUAGE PolyKinds #-}
    {-# LANGUAGE PolyKinds, KindSignatures #-} \
    data Set (cxt :: * -> *) a = Set [a] -- @Note Extension KindSignatures is implied by PolyKinds
    {-# LANGUAGE QuasiQuotes, OverloadedStrings #-} \
    main = putStrLn [f|{T.intercalate "blah" []}|]
    {-# LANGUAGE NamedFieldPuns #-} \
    foo = x{bar}
    {-# LANGUAGE PatternSynonyms #-} \
    module Foo (pattern Bar) where x = 42
    {-# LANGUAGE PatternSynonyms #-} \
    import Foo (pattern Bar); x = 42
    {-# LANGUAGE PatternSynonyms #-} \
    pattern Foo s <- Bar s _ where Foo s = Bar s s
    {-# LANGUAGE PatternSynonyms #-} \
    x = 42 --
    {-# LANGUAGE MultiWayIf #-} \
    x = if | b1 -> v1 | b2 -> v2 | otherwise -> v3
    {-# LANGUAGE MultiWayIf #-} \
    x = if b1 then v1 else if b2 then v2 else v3 --
    static = 42
    {-# LANGUAGE NamedFieldPuns #-} \
    foo Foo{x} = x
    {-# LANGUAGE NamedFieldPuns #-} \
    foo = Foo{x}
    {-# LANGUAGE NamedFieldPuns #-} \
    foo = bar{x}
    {-# LANGUAGE NamedFieldPuns #-} --
    {-# LANGUAGE NumericUnderscores #-} \
    lessThanPi = (< 3.141_592_653_589_793)
    {-# LANGUAGE NumericUnderscores #-} \
    oneMillion = 0xf4__240
    {-# LANGUAGE NumericUnderscores #-} \
    avogadro = 6.022140857e+23 --
    {-# LANGUAGE StaticPointers #-} \
    static = 42 --
    {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE Trustworthy, NamedFieldPuns #-} -- {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE Haskell2010 #-}
    {-# LANGUAGE NoStarIsType, ExplicitNamespaces #-} \
    import GHC.TypeLits(KnownNat, type (+), type (*))
    {-# LANGUAGE LambdaCase, MultiWayIf, NoRebindableSyntax #-} \
    foo = \case True -> 3 -- {-# LANGUAGE LambdaCase, NoRebindableSyntax #-}
    {-# LANGUAGE ImportQualifiedPost #-} \
    import Control.Monad qualified as CM
    {-# LANGUAGE ImportQualifiedPost #-} \
    import qualified Control.Monad as CM hiding (mapM) \
    import Data.Foldable -- @NoRefactor: refactor only works when using GHC 8.10
    {-# LANGUAGE StandaloneKindSignatures #-} \
    type T :: (k -> Type) -> k -> Type \
    data T m a = MkT (m a) (T Maybe (m a))
    {-# LANGUAGE NoMonomorphismRestriction, NamedFieldPuns #-} \
    main = 1 -- @Note Extension NamedFieldPuns is not used
    {-# LANGUAGE FunctionalDependencies #-} \
    class HasField x r a | x r -> a
    {-# LANGUAGE OverloadedRecordDot #-} \
    f x = x.foo
    {-# LANGUAGE OverloadedRecordDot #-} \
    f x = x . foo -- @NoRefactor: refactor requires GHC >= 9.2.1
    {-# LANGUAGE OverloadedRecordDot #-} \
    f = (.foo)
    {-# LANGUAGE OverloadedRecordDot #-} \
    f = (. foo) -- @NoRefactor: refactor requires GHC >= 9.2.1
    {-# LANGUAGE TemplateHaskellQuotes #-} \
    foo = [|| x ||]
    {-# LANGUAGE TemplateHaskell #-} \
    foo = $bar
    {-# LANGUAGE TemplateHaskell #-} \
    foo = $$typedExpressionSplice
    {-# LANGUAGE TypeData # -} \
    type data Nat = Zero | Succ Nat  -- @NoRefactor: refactor requires GHC >= 9.6.1
    {-# LANGUAGE TypeData #-} \
    data T = MkT -- @NoRefactor: refactor requires GHC >= 9.6.1
    </TEST>
    -}

    module Hint.Extensions(extensionsHint) where

    import Hint.Type(ModuHint,rawIdea,Severity(Warning),Note(..),toSSAnc,ghcModule,modComments,firstDeclComments)
    import Extension

    import Data.Generics.Uniplate.DataOnly
    import Control.Monad.Extra
    import Data.Maybe
    import Data.List.Extra
    import Data.Data
    import Refact.Types
    import Data.Set qualified as Set
    import Data.Map qualified as Map

    import GHC.Data.FastString
    import GHC.Types.SrcLoc
    import GHC.Types.SourceText
    import GHC.Hs
    import GHC.Types.Basic
    import GHC.Types.Name.Reader
    import GHC.Types.ForeignCall
    import GHC.Data.Strict qualified
    import GHC.Types.PkgQual

    import GHC.Util
    import GHC.LanguageExtensions.Type

    import Language.Haskell.GhclibParserEx.GHC.Hs.Pat
    import Language.Haskell.GhclibParserEx.GHC.Hs.Expr
    import Language.Haskell.GhclibParserEx.GHC.Hs.Type
    import Language.Haskell.GhclibParserEx.GHC.Hs.Decls
    import Language.Haskell.GhclibParserEx.GHC.Hs.Binds
    import Language.Haskell.GhclibParserEx.GHC.Hs.ImpExp
    import Language.Haskell.GhclibParserEx.GHC.Driver.Session
    import Language.Haskell.GhclibParserEx.GHC.Utils.Outputable
    import Language.Haskell.GhclibParserEx.GHC.Types.Name.Reader

    extensionsHint :: ModuHint
    extensionsHint :: ModuHint
    extensionsHint Scope
    _ ModuleEx
    x =
        [
            Severity
    -> String
    -> SrcSpan
    -> String
    -> Maybe String
    -> [Note]
    -> [Refactoring SrcSpan]
    -> Idea
    rawIdea Severity
    Hint.Type.Warning String
    "Unused LANGUAGE pragma"
            (RealSrcSpan -> Maybe BufSpan -> SrcSpan
    RealSrcSpan (EpaLocation' NoComments -> RealSrcSpan
    forall a. EpaLocation' a -> RealSrcSpan
    epaLocationRealSrcSpan EpaLocation' NoComments
    sl) Maybe BufSpan
    forall a. Maybe a
    GHC.Data.Strict.Nothing)
            (LEpaComment -> String
    comment_ (EpaLocation' NoComments -> [String] -> LEpaComment
    mkLanguagePragmas EpaLocation' NoComments
    sl [String]
    exts))
            (String -> Maybe String
    forall a. a -> Maybe a
    Just String
    newPragma)
            ( [String -> Note
    RequiresExtension (Extension -> String
    forall a. Show a => a -> String
    show Extension
    gone) | (String
    _, Just Extension
    x) <- [(String, Maybe Extension)]
    before [(String, Maybe Extension)]
    -> [(String, Maybe Extension)] -> [(String, Maybe Extension)]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [(String, Maybe Extension)]
    after, Extension
    gone <- [Extension]
    -> Extension -> Map Extension [Extension] -> [Extension]
    forall k a. Ord k => a -> k -> Map k a -> a
    Map.findWithDefault [] Extension
    x Map Extension [Extension]
    disappear] [Note] -> [Note] -> [Note]
    forall a. [a] -> [a] -> [a]
    ++
                [ String -> Note
    Note (String -> Note) -> String -> Note
    forall a b. (a -> b) -> a -> b
    $ String
    "Extension " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    s String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " is " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Extension -> String
    reason Extension
    x
                | (String
    s, Just Extension
    x) <- [(String, Maybe Extension)]
    explainedRemovals])
            [SrcSpan -> String -> Refactoring SrcSpan
    forall a. a -> String -> Refactoring a
    ModifyComment (LEpaComment -> SrcSpan
    forall e. GenLocated (EpaLocation' NoComments) e -> SrcSpan
    toSSAnc (EpaLocation' NoComments -> [String] -> LEpaComment
    mkLanguagePragmas EpaLocation' NoComments
    sl [String]
    exts)) String
    newPragma]
        | (L EpaLocation' NoComments
    sl EpaComment
    _,  [String]
    exts) <-
          -- Comments appearing without an empty line before the first
          -- declaration in a module are now associated with the
          -- declaration not the module so to be safe, look also at
          -- `firstDeclComments x`
          -- (https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9517).
          [(LEpaComment, String)] -> [(LEpaComment, [String])]
    languagePragmas ([(LEpaComment, String)] -> [(LEpaComment, [String])])
    -> [(LEpaComment, String)] -> [(LEpaComment, [String])]
    forall a b. (a -> b) -> a -> b
    $ EpAnnComments -> [(LEpaComment, String)]
    pragmas (ModuleEx -> EpAnnComments
    modComments ModuleEx
    x) [(LEpaComment, String)]
    -> [(LEpaComment, String)] -> [(LEpaComment, String)]
    forall a. [a] -> [a] -> [a]
    ++ EpAnnComments -> [(LEpaComment, String)]
    pragmas (ModuleEx -> EpAnnComments
    firstDeclComments ModuleEx
    x)
        , let before :: [(String, Maybe Extension)]
    before = [(String
    x, String -> Maybe Extension
    readExtension String
    x) | String
    x <- [String]
    exts]
        , let after :: [(String, Maybe Extension)]
    after = ((String, Maybe Extension) -> Bool)
    -> [(String, Maybe Extension)] -> [(String, Maybe Extension)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> (Extension -> Bool) -> Maybe Extension -> Bool
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Bool
    True (Extension -> Set Extension -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Extension
    keep) (Maybe Extension -> Bool)
    -> ((String, Maybe Extension) -> Maybe Extension)
    -> (String, Maybe Extension)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String, Maybe Extension) -> Maybe Extension
    forall a b. (a, b) -> b
    snd) [(String, Maybe Extension)]
    before
        , [(String, Maybe Extension)]
    before [(String, Maybe Extension)] -> [(String, Maybe Extension)] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= [(String, Maybe Extension)]
    after
        , let explainedRemovals :: [(String, Maybe Extension)]
    explainedRemovals
                | [(String, Maybe Extension)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(String, Maybe Extension)]
    after Bool -> Bool -> Bool
    && Bool -> Bool
    not ((Extension -> Bool) -> [Extension] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Extension -> Map Extension Extension -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    `Map.member` Map Extension Extension
    implied) ([Extension] -> Bool) -> [Extension] -> Bool
    forall a b. (a -> b) -> a -> b
    $ ((String, Maybe Extension) -> Maybe Extension)
    -> [(String, Maybe Extension)] -> [Extension]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (String, Maybe Extension) -> Maybe Extension
    forall a b. (a, b) -> b
    snd [(String, Maybe Extension)]
    before) = []
                | Bool
    otherwise = [(String, Maybe Extension)]
    before [(String, Maybe Extension)]
    -> [(String, Maybe Extension)] -> [(String, Maybe Extension)]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [(String, Maybe Extension)]
    after
        , let newPragma :: String
    newPragma =
                if [(String, Maybe Extension)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(String, Maybe Extension)]
    after then String
    "" else LEpaComment -> String
    comment_ (EpaLocation' NoComments -> [String] -> LEpaComment
    mkLanguagePragmas EpaLocation' NoComments
    sl ([String] -> LEpaComment) -> [String] -> LEpaComment
    forall a b. (a -> b) -> a -> b
    $ ((String, Maybe Extension) -> String)
    -> [(String, Maybe Extension)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, Maybe Extension) -> String
    forall a b. (a, b) -> a
    fst [(String, Maybe Extension)]
    after)
        ]
      where
        usedTH :: Bool
        usedTH :: Bool
    usedTH = Extension -> Located (HsModule GhcPs) -> Bool
    used Extension
    TemplateHaskell (ModuleEx -> Located (HsModule GhcPs)
    ghcModule ModuleEx
    x)
                   Bool -> Bool -> Bool
    || Extension -> Located (HsModule GhcPs) -> Bool
    used Extension
    TemplateHaskellQuotes (ModuleEx -> Located (HsModule GhcPs)
    ghcModule ModuleEx
    x)
                   Bool -> Bool -> Bool
    || Extension -> Located (HsModule GhcPs) -> Bool
    used Extension
    QuasiQuotes (ModuleEx -> Located (HsModule GhcPs)
    ghcModule ModuleEx
    x)
          -- If TH or QuasiQuotes is on, can use all other extensions
          -- programmatically.

        -- All the extensions defined to be used.
        extensions :: Set.Set Extension
        extensions :: Set Extension
    extensions = [Extension] -> Set Extension
    forall a. Ord a => [a] -> Set a
    Set.fromList ([Extension] -> Set Extension) -> [Extension] -> Set Extension
    forall a b. (a -> b) -> a -> b
    $
          ((LEpaComment, [String]) -> [Extension])
    -> [(LEpaComment, [String])] -> [Extension]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap
          ((String -> Maybe Extension) -> [String] -> [Extension]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe String -> Maybe Extension
    readExtension ([String] -> [Extension])
    -> ((LEpaComment, [String]) -> [String])
    -> (LEpaComment, [String])
    -> [Extension]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (LEpaComment, [String]) -> [String]
    forall a b. (a, b) -> b
    snd)
          ([(LEpaComment, String)] -> [(LEpaComment, [String])]
    languagePragmas
            (EpAnnComments -> [(LEpaComment, String)]
    pragmas (ModuleEx -> EpAnnComments
    modComments ModuleEx
    x) [(LEpaComment, String)]
    -> [(LEpaComment, String)] -> [(LEpaComment, String)]
    forall a. [a] -> [a] -> [a]
    ++ EpAnnComments -> [(LEpaComment, String)]
    pragmas (ModuleEx -> EpAnnComments
    firstDeclComments ModuleEx
    x)))
          -- Comments appearing without an empty line before the first
          -- declaration in a module are now associated with the
          -- declaration not the module so to be safe, look also at
          -- `firstDeclComments x`
          -- (https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9517).

        -- Those extensions we detect to be useful.
        useful :: Set.Set Extension
        useful :: Set Extension
    useful =
          if Bool
    usedTH
            then (Extension -> Bool) -> Set Extension -> Set Extension
    forall a. (a -> Bool) -> Set a -> Set a
    Set.filter (\case Extension
    TemplateHaskell -> Extension -> Located (HsModule GhcPs) -> Bool
    usedExt Extension
    TemplateHaskell (ModuleEx -> Located (HsModule GhcPs)
    ghcModule ModuleEx
    x); Extension
    _ -> Bool
    True) Set Extension
    extensions
            else (Extension -> Bool) -> Set Extension -> Set Extension
    forall a. (a -> Bool) -> Set a -> Set a
    Set.filter (Extension -> Located (HsModule GhcPs) -> Bool
    `usedExt` ModuleEx -> Located (HsModule GhcPs)
    ghcModule ModuleEx
    x) Set Extension
    extensions
        -- Those extensions which are useful, but implied by other useful
        -- extensions.
        implied :: Map.Map Extension Extension
        implied :: Map Extension Extension
    implied = [(Extension, Extension)] -> Map Extension Extension
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList
            [ (Extension
    e, Extension
    a)
            | Extension
    e <- Set Extension -> [Extension]
    forall a. Set a -> [a]
    Set.toList Set Extension
    useful
            , Extension
    a:[Extension]
    _ <- [(Extension -> Bool) -> [Extension] -> [Extension]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Extension -> Set Extension -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Extension
    useful) ([Extension] -> [Extension]) -> [Extension] -> [Extension]
    forall a b. (a -> b) -> a -> b
    $ Extension -> [Extension]
    extensionImpliedEnabledBy Extension
    e]
            ]
        -- Those we should keep.
        keep :: Set.Set Extension
        keep :: Set Extension
    keep =  Set Extension
    useful Set Extension -> Set Extension -> Set Extension
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.difference` Map Extension Extension -> Set Extension
    forall k a. Map k a -> Set k
    Map.keysSet Map Extension Extension
    implied
        -- The meaning of (a,b) is a used to imply b, but has gone, so
        -- suggest enabling b.
        disappear :: Map.Map Extension [Extension]
        disappear :: Map Extension [Extension]
    disappear =
            ([Extension] -> [Extension] -> [Extension])
    -> [(Extension, [Extension])] -> Map Extension [Extension]
    forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
    Map.fromListWith [Extension] -> [Extension] -> [Extension]
    forall a. [a] -> [a] -> [a]
    (++) ([(Extension, [Extension])] -> Map Extension [Extension])
    -> [(Extension, [Extension])] -> Map Extension [Extension]
    forall a b. (a -> b) -> a -> b
    $
            ((Extension, [Extension]) -> [Extension])
    -> [(Extension, [Extension])] -> [(Extension, [Extension])]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    nubOrdOn (Extension, [Extension]) -> [Extension]
    forall a b. (a, b) -> b
    snd -- Only keep one instance for each of a.
            [ (Extension
    e, [Extension
    a])
            | Extension
    e <- Set Extension -> [Extension]
    forall a. Set a -> [a]
    Set.toList (Set Extension -> [Extension]) -> Set Extension -> [Extension]
    forall a b. (a -> b) -> a -> b
    $ Set Extension
    extensions Set Extension -> Set Extension -> Set Extension
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.difference` Set Extension
    keep
            , Extension
    a <- ([Extension], [Extension]) -> [Extension]
    forall a b. (a, b) -> a
    fst (([Extension], [Extension]) -> [Extension])
    -> ([Extension], [Extension]) -> [Extension]
    forall a b. (a -> b) -> a -> b
    $ Extension -> ([Extension], [Extension])
    extensionImplies Extension
    e
            , Extension
    a Extension -> Set Extension -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.notMember` Set Extension
    useful
            , Bool
    usedTH Bool -> Bool -> Bool
    || Extension -> Located (HsModule GhcPs) -> Bool
    usedExt Extension
    a (ModuleEx -> Located (HsModule GhcPs)
    ghcModule ModuleEx
    x)
            ]
        reason :: Extension -> String
        reason :: Extension -> String
    reason Extension
    x =
          case Extension -> Map Extension Extension -> Maybe Extension
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Extension
    x Map Extension Extension
    implied of
            Just Extension
    a -> String
    "implied by " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Extension -> String
    forall a. Show a => a -> String
    show Extension
    a
            Maybe Extension
    Nothing -> String
    "not used"

    deriveHaskell :: [String]
    deriveHaskell = [String
    "Eq",String
    "Ord",String
    "Enum",String
    "Ix",String
    "Bounded",String
    "Read",String
    "Show"]
    deriveGenerics :: [String]
    deriveGenerics = [String
    "Data",String
    "Typeable",String
    "Generic",String
    "Generic1",String
    "Lift"]
    deriveCategory :: [String]
    deriveCategory = [String
    "Functor",String
    "Foldable",String
    "Traversable"]

    -- | Classes that can't require newtype deriving
    noDeriveNewtype :: [String]
    noDeriveNewtype =
        String -> [String] -> [String]
    forall a. Eq a => a -> [a] -> [a]
    delete String
    "Enum" [String]
    deriveHaskell [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ -- Enum can't always be derived on a newtype
        [String]
    deriveGenerics -- Generics stuff can't newtype derive since it has the ctor in it

    -- | Classes that can appear as stock, and can't appear as anyclass
    deriveStock :: [String]
    deriveStock :: [String]
    deriveStock = [String]
    deriveHaskell [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    deriveGenerics [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    deriveCategory

    usedExt :: Extension -> Located (HsModule GhcPs) -> Bool
    usedExt :: Extension -> Located (HsModule GhcPs) -> Bool
    usedExt Extension
    NumDecimals = (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    isWholeFrac
      -- Only whole number fractions are permitted by NumDecimals
      -- extension.  Anything not-whole raises an error.
    usedExt Extension
    DeriveLift = [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String
    "Lift"]
    usedExt Extension
    DeriveAnyClass = Bool -> Bool
    not (Bool -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([String] -> Bool)
    -> (Located (HsModule GhcPs) -> [String])
    -> Located (HsModule GhcPs)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Derives -> [String]
    derivesAnyclass (Derives -> [String])
    -> (Located (HsModule GhcPs) -> Derives)
    -> Located (HsModule GhcPs)
    -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Located (HsModule GhcPs) -> Derives
    derives
    usedExt Extension
    x = Extension -> Located (HsModule GhcPs) -> Bool
    used Extension
    x

    used :: Extension -> Located (HsModule GhcPs) -> Bool

    used :: Extension -> Located (HsModule GhcPs) -> Bool
    used Extension
    RecursiveDo = (HsDoFlavour -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsDoFlavour -> Bool
    isMDo (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (StmtLR GhcPs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
     -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS StmtLR GhcPs GhcPs (LHsExpr GhcPs) -> Bool
    StmtLR GhcPs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool
    isRecStmt
    used Extension
    ParallelListComp = (StmtLR GhcPs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
     -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS StmtLR GhcPs GhcPs (LHsExpr GhcPs) -> Bool
    StmtLR GhcPs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool
    isParComp
    used Extension
    FunctionalDependencies = FunDep GhcPs -> Located (HsModule GhcPs) -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (FunDep GhcPs
    forall {a}. a
    un :: FunDep GhcPs)
    used Extension
    ImplicitParams = HsIPName -> Located (HsModule GhcPs) -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (HsIPName
    forall {a}. a
    un :: HsIPName)

    used Extension
    TypeApplications = (GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsExpr GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool
    isTypeApp (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (GenLocated SrcSpanAnnA (HsType GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsType GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsType GhcPs) -> Bool
    isKindTyApp

    used Extension
    EmptyDataDecls = (HsDataDefn GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsDataDefn GhcPs -> Bool
    f
      where
        f :: HsDataDefn GhcPs -> Bool
        f :: HsDataDefn GhcPs -> Bool
    f (HsDataDefn XCHsDataDefn GhcPs
    _ Maybe (LHsContext GhcPs)
    _ Maybe (XRec GhcPs CType)
    _ Maybe (LHsType GhcPs)
    _ (DataTypeCons Bool
    _ []) HsDeriving GhcPs
    _) = Bool
    True
        f HsDataDefn GhcPs
    _ = Bool
    False
    used Extension
    TypeData  = (HsDataDefn GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsDataDefn GhcPs -> Bool
    f
      where
        f :: HsDataDefn GhcPs -> Bool
        f :: HsDataDefn GhcPs -> Bool
    f (HsDataDefn XCHsDataDefn GhcPs
    _ Maybe (LHsContext GhcPs)
    _ Maybe (XRec GhcPs CType)
    _ Maybe (LHsType GhcPs)
    _ (DataTypeCons Bool
    True [LConDecl GhcPs]
    _) HsDeriving GhcPs
    _) = Bool
    True
        f HsDataDefn GhcPs
    _ = Bool
    False
    used Extension
    EmptyCase = (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    f
      where
        f :: HsExpr GhcPs -> Bool
        f :: HsExpr GhcPs -> Bool
    f (HsCase XCase GhcPs
    _ LHsExpr GhcPs
    _ (MG XMG GhcPs (LHsExpr GhcPs)
    _ (L SrcSpanAnnLW
    _ []))) = Bool
    True
        f (HsLam XLam GhcPs
    _ HsLamVariant
    LamCase (MG XMG GhcPs (LHsExpr GhcPs)
    _ (L SrcSpanAnnLW
    _ []))) = Bool
    True
        f HsExpr GhcPs
    _ = Bool
    False
    used Extension
    KindSignatures = HsType GhcPs -> Located (HsModule GhcPs) -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (HsType GhcPs
    forall {a}. a
    un :: HsKind GhcPs)
    used Extension
    BangPatterns = (GenLocated SrcSpanAnnA (Pat GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LPat GhcPs -> Bool
    GenLocated SrcSpanAnnA (Pat GhcPs) -> Bool
    isPBangPat (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (HsMatchContext (LocatedN RdrName) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsMatchContext (LocatedN RdrName) -> Bool
    isStrictMatch
    used Extension
    TemplateHaskell = (HsUntypedSplice GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS (Bool -> Bool
    not (Bool -> Bool)
    -> (HsUntypedSplice GhcPs -> Bool) -> HsUntypedSplice GhcPs -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HsUntypedSplice GhcPs -> Bool
    isQuasiQuoteSplice) (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    isTypedSplice
    used Extension
    TemplateHaskellQuotes = (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    f
      where
        f :: HsExpr GhcPs -> Bool
        f :: HsExpr GhcPs -> Bool
    f HsTypedBracket{} = Bool
    True
        f HsUntypedBracket{} = Bool
    True
        f HsExpr GhcPs
    _ = Bool
    False
    used Extension
    ForeignFunctionInterface = CCallConv -> Located (HsModule GhcPs) -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (CCallConv
    forall {a}. a
    un :: CCallConv)
    used Extension
    PatternGuards = (GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS GRHS GhcPs (LHsExpr GhcPs) -> Bool
    GRHS GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool
    f
      where
        f :: GRHS GhcPs (LHsExpr GhcPs) -> Bool
        f :: GRHS GhcPs (LHsExpr GhcPs) -> Bool
    f (GRHS XCGRHS GhcPs (LHsExpr GhcPs)
    _ [GuardLStmt GhcPs]
    xs LHsExpr GhcPs
    _) = [GuardLStmt GhcPs] -> Bool
    g [GuardLStmt GhcPs]
    xs
        g :: [GuardLStmt GhcPs] -> Bool
        g :: [GuardLStmt GhcPs] -> Bool
    g [] = Bool
    False
        g [L SrcSpanAnnA
    _ BodyStmt{}] = Bool
    False
        g [GuardLStmt GhcPs]
    _ = Bool
    True
    used Extension
    StandaloneDeriving = (GenLocated SrcSpanAnnA (HsDecl GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsDecl GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsDecl GhcPs) -> Bool
    isDerivD
    used Extension
    TypeOperators = (HsType GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsType GhcPs -> Bool
    tyOpInSig (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (HsDecl GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsDecl GhcPs -> Bool
    tyOpInDecl
      where
        tyOpInSig :: HsType GhcPs -> Bool
        tyOpInSig :: HsType GhcPs -> Bool
    tyOpInSig = \case
          HsOpTy{} -> Bool
    True; HsType GhcPs
    _ -> Bool
    False

        tyOpInDecl :: HsDecl GhcPs -> Bool
        tyOpInDecl :: HsDecl GhcPs -> Bool
    tyOpInDecl = \case
          (TyClD XTyClD GhcPs
    _ (FamDecl XFamDecl GhcPs
    _ FamilyDecl{LIdP GhcPs
    fdLName :: LIdP GhcPs
    fdLName :: forall pass. FamilyDecl pass -> LIdP pass
    fdLName})) -> LocatedN RdrName -> Bool
    forall {l}. GenLocated l RdrName -> Bool
    isOp LIdP GhcPs
    LocatedN RdrName
    fdLName
          (TyClD XTyClD GhcPs
    _ SynDecl{LIdP GhcPs
    tcdLName :: LIdP GhcPs
    tcdLName :: forall pass. TyClDecl pass -> LIdP pass
    tcdLName}) -> LocatedN RdrName -> Bool
    forall {l}. GenLocated l RdrName -> Bool
    isOp LIdP GhcPs
    LocatedN RdrName
    tcdLName
          (TyClD XTyClD GhcPs
    _ DataDecl{LIdP GhcPs
    tcdLName :: forall pass. TyClDecl pass -> LIdP pass
    tcdLName :: LIdP GhcPs
    tcdLName}) -> LocatedN RdrName -> Bool
    forall {l}. GenLocated l RdrName -> Bool
    isOp LIdP GhcPs
    LocatedN RdrName
    tcdLName
          (TyClD XTyClD GhcPs
    _ ClassDecl{LIdP GhcPs
    tcdLName :: forall pass. TyClDecl pass -> LIdP pass
    tcdLName :: LIdP GhcPs
    tcdLName, [LFamilyDecl GhcPs]
    tcdATs :: [LFamilyDecl GhcPs]
    tcdATs :: forall pass. TyClDecl pass -> [LFamilyDecl pass]
    tcdATs}) -> (LocatedN RdrName -> Bool) -> [LocatedN RdrName] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any LocatedN RdrName -> Bool
    forall {l}. GenLocated l RdrName -> Bool
    isOp (LIdP GhcPs
    LocatedN RdrName
    tcdLName LocatedN RdrName -> [LocatedN RdrName] -> [LocatedN RdrName]
    forall a. a -> [a] -> [a]
    : [FamilyDecl GhcPs -> LIdP GhcPs
    forall pass. FamilyDecl pass -> LIdP pass
    fdLName FamilyDecl GhcPs
    famDecl | L SrcSpanAnnA
    _ FamilyDecl GhcPs
    famDecl <- [LFamilyDecl GhcPs]
    [GenLocated SrcSpanAnnA (FamilyDecl GhcPs)]
    tcdATs])
          HsDecl GhcPs
    _ -> Bool
    False

        isOp :: GenLocated l RdrName -> Bool
    isOp (L l
    _ RdrName
    name) = RdrName -> Bool
    isSymbolRdrName RdrName
    name

    used Extension
    RecordWildCards = (HsRecFields GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsRecFields GhcPs (LHsExpr GhcPs) -> Bool
    HsRecFields GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool
    hasFieldsDotDot (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (HsRecFields GhcPs (GenLocated SrcSpanAnnA (Pat GhcPs)) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsRecFields GhcPs (LPat GhcPs) -> Bool
    HsRecFields GhcPs (GenLocated SrcSpanAnnA (Pat GhcPs)) -> Bool
    hasPFieldsDotDot
    used Extension
    NamedFieldPuns = (GenLocated
       SrcSpanAnnA
       (HsFieldBind
          (GenLocated SrcSpanAnnA (FieldOcc GhcPs))
          (GenLocated SrcSpanAnnA (Pat GhcPs)))
     -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsFieldBind GhcPs (LFieldOcc GhcPs) (LPat GhcPs) -> Bool
    GenLocated
      SrcSpanAnnA
      (HsFieldBind
         (GenLocated SrcSpanAnnA (FieldOcc GhcPs))
         (GenLocated SrcSpanAnnA (Pat GhcPs)))
    -> Bool
    isPFieldPun (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (GenLocated
       SrcSpanAnnA
       (HsFieldBind
          (GenLocated SrcSpanAnnA (FieldOcc GhcPs))
          (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
     -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsFieldBind GhcPs (LFieldOcc GhcPs) (LHsExpr GhcPs) -> Bool
    GenLocated
      SrcSpanAnnA
      (HsFieldBind
         (GenLocated SrcSpanAnnA (FieldOcc GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Bool
    isFieldPun (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (HsFieldBind
       (GenLocated SrcSpanAnnA (FieldOcc GhcPs))
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
     -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsFieldBind (LFieldOcc GhcPs) (LHsExpr GhcPs) -> Bool
    HsFieldBind
      (GenLocated SrcSpanAnnA (FieldOcc GhcPs))
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> Bool
    isFieldPunUpdate
    used Extension
    UnboxedTuples = (HsTupleSort -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsTupleSort -> Bool
    isUnboxedTuple (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (Boxity -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS (Boxity -> Boxity -> Bool
    forall a. Eq a => a -> a -> Bool
    == Boxity
    Unboxed) (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS Maybe (LDerivStrategy GhcPs) -> Bool
    Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)) -> Bool
    isDeriving
      where
          -- detect if there are deriving declarations or data ... deriving stuff
          -- by looking for the deriving strategy both contain (even if its Nothing)
          -- see https://github.com/ndmitchell/hlint/issues/833 for why we care
          isDeriving :: Maybe (LDerivStrategy GhcPs) -> Bool
          isDeriving :: Maybe (LDerivStrategy GhcPs) -> Bool
    isDeriving Maybe (LDerivStrategy GhcPs)
    _ = Bool
    True
    used Extension
    PackageImports = (ImportDecl GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS ImportDecl GhcPs -> Bool
    f
      where
          f :: ImportDecl GhcPs -> Bool
          f :: ImportDecl GhcPs -> Bool
    f ImportDecl{ideclPkgQual :: forall pass. ImportDecl pass -> ImportDeclPkgQual pass
    ideclPkgQual=RawPkgQual StringLiteral
    _} = Bool
    True
          f ImportDecl GhcPs
    _ = Bool
    False
    used Extension
    QuasiQuotes = (GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsExpr GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool
    isQuasiQuoteExpr (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (GenLocated SrcSpanAnnA (HsType GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsType GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsType GhcPs) -> Bool
    isTyQuasiQuote
    used Extension
    ViewPatterns = (GenLocated SrcSpanAnnA (Pat GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LPat GhcPs -> Bool
    GenLocated SrcSpanAnnA (Pat GhcPs) -> Bool
    isPViewPat
    used Extension
    InstanceSigs = (HsDecl GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsDecl GhcPs -> Bool
    f
      where
        f :: HsDecl GhcPs -> Bool
        f :: HsDecl GhcPs -> Bool
    f (InstD XInstD GhcPs
    _ InstDecl GhcPs
    decl) = Sig GhcPs -> InstDecl GhcPs -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (Sig GhcPs
    forall {a}. a
    un :: Sig GhcPs) InstDecl GhcPs
    decl
        f HsDecl GhcPs
    _ = Bool
    False
    used Extension
    DefaultSignatures = (Sig GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS Sig GhcPs -> Bool
    isClsDefSig
    used Extension
    DeriveDataTypeable = [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String
    "Data",String
    "Typeable"]
    used Extension
    DeriveFunctor = [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String
    "Functor"]
    used Extension
    DeriveFoldable = [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String
    "Foldable"]
    used Extension
    DeriveTraversable = [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String
    "Traversable",String
    "Foldable",String
    "Functor"]
    used Extension
    DeriveGeneric = [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String
    "Generic",String
    "Generic1"]
    used Extension
    GeneralizedNewtypeDeriving = Bool -> Bool
    not (Bool -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([String] -> Bool)
    -> (Located (HsModule GhcPs) -> [String])
    -> Located (HsModule GhcPs)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Derives -> [String]
    derivesNewtype' (Derives -> [String])
    -> (Located (HsModule GhcPs) -> Derives)
    -> Located (HsModule GhcPs)
    -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Located (HsModule GhcPs) -> Derives
    derives
    used Extension
    MultiWayIf = (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    isMultiIf
    used Extension
    NumericUnderscores = (OverLitVal -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS OverLitVal -> Bool
    f
      where
        f :: OverLitVal -> Bool
        f :: OverLitVal -> Bool
    f (HsIntegral (IL (SourceText FastString
    t) Bool
    _ Integer
    _)) = Char
    '_' Char -> String -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` FastString -> String
    unpackFS FastString
    t
        f (HsFractional (FL (SourceText FastString
    t) Bool
    _ Rational
    _ Integer
    _ FractionalExponentBase
    _)) = Char
    '_' Char -> String -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` FastString -> String
    unpackFS FastString
    t
        f OverLitVal
    _ = Bool
    False

    used Extension
    LambdaCase = (GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsExpr GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool
    isLCase
    used Extension
    TupleSections = (HsTupArg GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsTupArg GhcPs -> Bool
    isTupleSection
    used Extension
    OverloadedStrings = (HsLit GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsLit GhcPs -> Bool
    isString
    used Extension
    OverloadedLists = (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    isListExpr (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (Pat GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS Pat GhcPs -> Bool
    isListPat
      where
        isListExpr :: HsExpr GhcPs -> Bool
        isListExpr :: HsExpr GhcPs -> Bool
    isListExpr (HsVar XVar GhcPs
    _ LIdP GhcPs
    n) = LocatedN RdrName -> String
    rdrNameStr LIdP GhcPs
    LocatedN RdrName
    n String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == String
    "[]"
        isListExpr ExplicitList{} = Bool
    True
        isListExpr ArithSeq{} = Bool
    True
        isListExpr HsExpr GhcPs
    _ = Bool
    False

        isListPat :: Pat GhcPs -> Bool
        isListPat :: Pat GhcPs -> Bool
    isListPat ListPat{} = Bool
    True
        isListPat Pat GhcPs
    _ = Bool
    False

    used Extension
    OverloadedLabels = (GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS LHsExpr GhcPs -> Bool
    GenLocated SrcSpanAnnA (HsExpr GhcPs) -> Bool
    isOverLabel

    used Extension
    Arrows = (HsExpr GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsExpr GhcPs -> Bool
    isProc
    used Extension
    TransformListComp = (StmtLR GhcPs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs))
     -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS StmtLR GhcPs GhcPs (LHsExpr GhcPs) -> Bool
    StmtLR GhcPs GhcPs (GenLocated SrcSpanAnnA (HsExpr GhcPs)) -> Bool
    isTransStmt
    used Extension
    MagicHash = (RdrName -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS RdrName -> Bool
    f (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (HsLit GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsLit GhcPs -> Bool
    isPrimLiteral
      where
        f :: RdrName -> Bool
        f :: RdrName -> Bool
    f RdrName
    s = String
    "#" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isSuffixOf` RdrName -> String
    occNameStr RdrName
    s
    used Extension
    PatternSynonyms = (HsBind GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS HsBind GhcPs -> Bool
    isPatSynBind (Located (HsModule GhcPs) -> Bool)
    -> (Located (HsModule GhcPs) -> Bool)
    -> Located (HsModule GhcPs)
    -> Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    ||^ (IEWrappedName GhcPs -> Bool) -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS IEWrappedName GhcPs -> Bool
    isPatSynIE
    used Extension
    ImportQualifiedPost = (ImportDeclQualifiedStyle -> Bool)
    -> Located (HsModule GhcPs) -> Bool
    forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS (ImportDeclQualifiedStyle -> ImportDeclQualifiedStyle -> Bool
    forall a. Eq a => a -> a -> Bool
    == ImportDeclQualifiedStyle
    QualifiedPost)
    used Extension
    StandaloneKindSignatures = StandaloneKindSig GhcPs -> Located (HsModule GhcPs) -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (StandaloneKindSig GhcPs
    forall {a}. a
    un :: StandaloneKindSig GhcPs)
    used Extension
    OverloadedRecordDot = DotFieldOcc GhcPs -> Located (HsModule GhcPs) -> Bool
    forall {from} {a}. (Data from, Data a) => a -> from -> Bool
    hasT (DotFieldOcc GhcPs
    forall {a}. a
    un :: DotFieldOcc GhcPs)

    used Extension
    _= Bool -> Located (HsModule GhcPs) -> Bool
    forall a b. a -> b -> a
    const Bool
    True

    hasDerive :: [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive :: [String] -> Located (HsModule GhcPs) -> Bool
    hasDerive [String]
    want = (String -> Bool) -> [String] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (String -> [String] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String]
    want) ([String] -> Bool)
    -> (Located (HsModule GhcPs) -> [String])
    -> Located (HsModule GhcPs)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Derives -> [String]
    derivesStock' (Derives -> [String])
    -> (Located (HsModule GhcPs) -> Derives)
    -> Located (HsModule GhcPs)
    -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Located (HsModule GhcPs) -> Derives
    derives

    -- Derivations can be implemented using any one of 3 strategies, so for each derivation
    -- add it to all the strategies that might plausibly implement it
    data Derives = Derives
        {Derives -> [String]
    derivesStock' :: [String]
        ,Derives -> [String]
    derivesAnyclass :: [String]
        ,Derives -> [String]
    derivesNewtype' :: [String]
        }
    instance Semigroup Derives where
        Derives [String]
    x1 [String]
    x2 [String]
    x3 <> :: Derives -> Derives -> Derives
    <> Derives [String]
    y1 [String]
    y2 [String]
    y3 =
            [String] -> [String] -> [String] -> Derives
    Derives ([String]
    x1 [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    y1) ([String]
    x2 [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    y2) ([String]
    x3 [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    y3)
    instance Monoid Derives where
        mempty :: Derives
    mempty = [String] -> [String] -> [String] -> Derives
    Derives [] [] []
        mappend :: Derives -> Derives -> Derives
    mappend = Derives -> Derives -> Derives
    forall a. Semigroup a => a -> a -> a
    (<>)

    addDerives :: Maybe NewOrData -> Maybe (DerivStrategy GhcPs) -> [String] -> Derives
    addDerives :: Maybe NewOrData
    -> Maybe (DerivStrategy GhcPs) -> [String] -> Derives
    addDerives Maybe NewOrData
    _ (Just DerivStrategy GhcPs
    s) [String]
    xs = case DerivStrategy GhcPs
    s of
        StockStrategy {} -> Derives
    forall a. Monoid a => a
    mempty{derivesStock' = xs}
        AnyclassStrategy {} -> Derives
    forall a. Monoid a => a
    mempty{derivesAnyclass = xs}
        NewtypeStrategy {} -> Derives
    forall a. Monoid a => a
    mempty{derivesNewtype' = xs}
        ViaStrategy {} -> Derives
    forall a. Monoid a => a
    mempty
    addDerives Maybe NewOrData
    nt Maybe (DerivStrategy GhcPs)
    _ [String]
    xs = Derives
    forall a. Monoid a => a
    mempty
        {derivesStock' = stock
        ,derivesAnyclass = other
        ,derivesNewtype' = if maybe True isNewType nt then filter (`notElem` noDeriveNewtype) xs else []}
        where ([String]
    stock, [String]
    other) = (String -> Bool) -> [String] -> ([String], [String])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (String -> [String] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String]
    deriveStock) [String]
    xs

    derives :: Located (HsModule GhcPs) -> Derives
    derives :: Located (HsModule GhcPs) -> Derives
    derives (L SrcSpan
    _ HsModule GhcPs
    m) =  [Derives] -> Derives
    forall a. Monoid a => [a] -> a
    mconcat ([Derives] -> Derives) -> [Derives] -> Derives
    forall a b. (a -> b) -> a -> b
    $ (GenLocated SrcSpanAnnA (HsDecl GhcPs) -> Derives)
    -> [GenLocated SrcSpanAnnA (HsDecl GhcPs)] -> [Derives]
    forall a b. (a -> b) -> [a] -> [b]
    map LHsDecl GhcPs -> Derives
    GenLocated SrcSpanAnnA (HsDecl GhcPs) -> Derives
    decl (HsModule GhcPs -> [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
    forall from to. Biplate from to => from -> [to]
    childrenBi HsModule GhcPs
    m) [Derives] -> [Derives] -> [Derives]
    forall a. [a] -> [a] -> [a]
    ++ (DataFamInstDecl GhcPs -> Derives)
    -> [DataFamInstDecl GhcPs] -> [Derives]
    forall a b. (a -> b) -> [a] -> [b]
    map DataFamInstDecl GhcPs -> Derives
    idecl (HsModule GhcPs -> [DataFamInstDecl GhcPs]
    forall from to. Biplate from to => from -> [to]
    childrenBi HsModule GhcPs
    m)
      where
        idecl :: DataFamInstDecl GhcPs -> Derives
        idecl :: DataFamInstDecl GhcPs -> Derives
    idecl (DataFamInstDecl FamEqn {feqn_rhs :: forall pass rhs. FamEqn pass rhs -> rhs
    feqn_rhs=HsDataDefn {dd_cons :: forall pass. HsDataDefn pass -> DataDefnCons (LConDecl pass)
    dd_cons=DataDefnCons (LConDecl GhcPs)
    data_defn_cons, dd_derivs :: forall pass. HsDataDefn pass -> HsDeriving pass
    dd_derivs=HsDeriving GhcPs
    ds}}) = NewOrData -> HsDeriving GhcPs -> Derives
    g (DataDefnCons (GenLocated SrcSpanAnnA (ConDecl GhcPs)) -> NewOrData
    forall a. DataDefnCons a -> NewOrData
    dataDefnConsNewOrData DataDefnCons (LConDecl GhcPs)
    DataDefnCons (GenLocated SrcSpanAnnA (ConDecl GhcPs))
    data_defn_cons) HsDeriving GhcPs
    ds

        decl :: LHsDecl GhcPs -> Derives
        decl :: LHsDecl GhcPs -> Derives
    decl (L SrcSpanAnnA
    _ (TyClD XTyClD GhcPs
    _ (DataDecl XDataDecl GhcPs
    _ LIdP GhcPs
    _ LHsQTyVars GhcPs
    _ LexicalFixity
    _ HsDataDefn {dd_cons :: forall pass. HsDataDefn pass -> DataDefnCons (LConDecl pass)
    dd_cons=DataDefnCons (LConDecl GhcPs)
    data_defn_cons, dd_derivs :: forall pass. HsDataDefn pass -> HsDeriving pass
    dd_derivs=HsDeriving GhcPs
    ds}))) = NewOrData -> HsDeriving GhcPs -> Derives
    g (DataDefnCons (GenLocated SrcSpanAnnA (ConDecl GhcPs)) -> NewOrData
    forall a. DataDefnCons a -> NewOrData
    dataDefnConsNewOrData DataDefnCons (LConDecl GhcPs)
    DataDefnCons (GenLocated SrcSpanAnnA (ConDecl GhcPs))
    data_defn_cons) HsDeriving GhcPs
    ds -- Data declaration.
        decl (L SrcSpanAnnA
    _ (DerivD XDerivD GhcPs
    _ (DerivDecl XCDerivDecl GhcPs
    _ (HsWC XHsWC GhcPs (LHsSigType GhcPs)
    _ LHsSigType GhcPs
    sig) Maybe (LDerivStrategy GhcPs)
    strategy Maybe (XRec GhcPs OverlapMode)
    _))) = Maybe NewOrData
    -> Maybe (DerivStrategy GhcPs) -> [String] -> Derives
    addDerives Maybe NewOrData
    forall a. Maybe a
    Nothing ((GenLocated EpAnnCO (DerivStrategy GhcPs) -> DerivStrategy GhcPs)
    -> Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    -> Maybe (DerivStrategy GhcPs)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap GenLocated EpAnnCO (DerivStrategy GhcPs) -> DerivStrategy GhcPs
    forall l e. GenLocated l e -> e
    unLoc Maybe (LDerivStrategy GhcPs)
    Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    strategy) [LHsSigType GhcPs -> String
    derivedToStr LHsSigType GhcPs
    sig] -- A deriving declaration.
        decl LHsDecl GhcPs
    _ = Derives
    forall a. Monoid a => a
    mempty

        g :: NewOrData -> [LHsDerivingClause GhcPs] -> Derives
        g :: NewOrData -> HsDeriving GhcPs -> Derives
    g NewOrData
    dn HsDeriving GhcPs
    ds = [Derives] -> Derives
    forall a. Monoid a => [a] -> a
    mconcat [Maybe NewOrData
    -> Maybe (DerivStrategy GhcPs) -> [String] -> Derives
    addDerives (NewOrData -> Maybe NewOrData
    forall a. a -> Maybe a
    Just NewOrData
    dn) ((GenLocated EpAnnCO (DerivStrategy GhcPs) -> DerivStrategy GhcPs)
    -> Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    -> Maybe (DerivStrategy GhcPs)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap GenLocated EpAnnCO (DerivStrategy GhcPs) -> DerivStrategy GhcPs
    forall l e. GenLocated l e -> e
    unLoc Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    strategy) ([String] -> Derives) -> [String] -> Derives
    forall a b. (a -> b) -> a -> b
    $ (GenLocated SrcSpanAnnA (HsSigType GhcPs) -> String)
    -> [GenLocated SrcSpanAnnA (HsSigType GhcPs)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map LHsSigType GhcPs -> String
    GenLocated SrcSpanAnnA (HsSigType GhcPs) -> String
    derivedToStr [GenLocated SrcSpanAnnA (HsSigType GhcPs)]
    tys | (Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    strategy, [GenLocated SrcSpanAnnA (HsSigType GhcPs)]
    tys) <- [(Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)),
      [GenLocated SrcSpanAnnA (HsSigType GhcPs)])]
    stys]
          where
            stys :: [(Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)),
      [GenLocated SrcSpanAnnA (HsSigType GhcPs)])]
    stys =
              [(Maybe (LDerivStrategy GhcPs)
    Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    strategy, [LHsSigType GhcPs
    GenLocated SrcSpanAnnA (HsSigType GhcPs)
    ty]) | L EpAnnCO
    _ (HsDerivingClause XCHsDerivingClause GhcPs
    _ Maybe (LDerivStrategy GhcPs)
    strategy (L SrcSpanAnnC
    _ (DctSingle XDctSingle GhcPs
    _ LHsSigType GhcPs
    ty))) <- HsDeriving GhcPs
    [GenLocated EpAnnCO (HsDerivingClause GhcPs)]
    ds] [(Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)),
      [GenLocated SrcSpanAnnA (HsSigType GhcPs)])]
    -> [(Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)),
         [GenLocated SrcSpanAnnA (HsSigType GhcPs)])]
    -> [(Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs)),
         [GenLocated SrcSpanAnnA (HsSigType GhcPs)])]
    forall a. [a] -> [a] -> [a]
    ++
              [(Maybe (LDerivStrategy GhcPs)
    Maybe (GenLocated EpAnnCO (DerivStrategy GhcPs))
    strategy, [LHsSigType GhcPs]
    [GenLocated SrcSpanAnnA (HsSigType GhcPs)]
    tys ) | L EpAnnCO
    _ (HsDerivingClause XCHsDerivingClause GhcPs
    _ Maybe (LDerivStrategy GhcPs)
    strategy (L SrcSpanAnnC
    _ (DctMulti XDctMulti GhcPs
    _ [LHsSigType GhcPs]
    tys))) <- HsDeriving GhcPs
    [GenLocated EpAnnCO (HsDerivingClause GhcPs)]
    ds]

        derivedToStr :: LHsSigType GhcPs -> String
        derivedToStr :: LHsSigType GhcPs -> String
    derivedToStr (L SrcSpanAnnA
    _ (HsSig XHsSig GhcPs
    _ HsOuterSigTyVarBndrs GhcPs
    _ LHsType GhcPs
    t)) = LHsType GhcPs -> String
    ih LHsType GhcPs
    t
          where
            ih :: LHsType GhcPs -> String
            ih :: LHsType GhcPs -> String
    ih (L SrcSpanAnnA
    _ (HsQualTy XQualTy GhcPs
    _ LHsContext GhcPs
    _ LHsType GhcPs
    a)) = LHsType GhcPs -> String
    ih LHsType GhcPs
    a
            ih (L SrcSpanAnnA
    _ (HsParTy XParTy GhcPs
    _ LHsType GhcPs
    a)) = LHsType GhcPs -> String
    ih LHsType GhcPs
    a
            ih (L SrcSpanAnnA
    _ (HsAppTy XAppTy GhcPs
    _ LHsType GhcPs
    a LHsType GhcPs
    _)) = LHsType GhcPs -> String
    ih LHsType GhcPs
    a
            ih (L SrcSpanAnnA
    _ (HsTyVar XTyVar GhcPs
    _ PromotionFlag
    _ LIdP GhcPs
    a)) = LocatedN RdrName -> String
    forall a. Outputable a => a -> String
    unsafePrettyPrint (LocatedN RdrName -> String) -> LocatedN RdrName -> String
    forall a b. (a -> b) -> a -> b
    $ LocatedN RdrName -> LocatedN RdrName
    unqual LIdP GhcPs
    LocatedN RdrName
    a
            ih (L SrcSpanAnnA
    _ HsType GhcPs
    a) = HsType GhcPs -> String
    forall a. Outputable a => a -> String
    unsafePrettyPrint HsType GhcPs
    a -- I don't anticipate this case is called.

    un :: a
    un = a
    forall a. HasCallStack => a
    undefined

    hasT :: a -> from -> Bool
    hasT a
    t from
    x = Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ [a] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (from -> [a]
    forall from to. Biplate from to => from -> [to]
    universeBi from
    x [a] -> [a] -> [a]
    forall a. a -> a -> a
    `asTypeOf` [a
    t])

    hasS :: (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS :: forall x a. (Data x, Data a) => (a -> Bool) -> x -> Bool
    hasS a -> Bool
    test = (a -> Bool) -> [a] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any a -> Bool
    test ([a] -> Bool) -> (x -> [a]) -> x -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . x -> [a]
    forall from to. Biplate from to => from -> [to]
    universeBi