    {- Language/Haskell/TH/Desugar/Reify.hs

    (c) Richard Eisenberg 2014
    rae@cs.brynmawr.edu

    Allows for reification from a list of declarations, without looking a name
    up in the environment.
    -}

    {-# LANGUAGE CPP, GeneralizedNewtypeDeriving, ScopedTypeVariables #-}

    module Language.Haskell.TH.Desugar.Reify (
      -- * Reification
      reifyWithLocals_maybe, reifyWithLocals, reifyWithWarning, reifyInDecs,

      -- ** Fixity reification
      qReifyFixity, reifyFixity, reifyFixityWithLocals, reifyFixityInDecs,

      -- ** Type reification
      qReifyType, reifyType,
      reifyTypeWithLocals_maybe, reifyTypeWithLocals, reifyTypeInDecs,

      -- * Datatype lookup
      getDataD, dataConNameToCon, dataConNameToDataName,

      -- * Value and type lookup
      lookupValueNameWithLocals, lookupTypeNameWithLocals,
      mkDataNameWithLocals, mkTypeNameWithLocals,
      reifyNameSpace,

      -- * Monad support
      DsMonad(..), DsM, withLocalDeclarations
      ) where

    import Control.Applicative
    import qualified Control.Monad.Fail as Fail
    import Control.Monad.Reader
    import Control.Monad.State
    import Control.Monad.Writer
    import Control.Monad.RWS
    import Control.Monad.Trans.Instances ()
    import qualified Data.Foldable as F
    import Data.Function (on)
    import qualified Data.List as List
    import qualified Data.Map as Map
    import Data.Map (Map)
    import Data.Maybe
    import qualified Data.Set as Set
    import Data.Set (Set)

    import Language.Haskell.TH.Datatype ( freeVariables, freeVariablesWellScoped
                                        , quantifyType, resolveTypeSynonyms )
    import Language.Haskell.TH.Datatype.TyVarBndr
    import Language.Haskell.TH.Instances ()
    import Language.Haskell.TH.Syntax hiding ( lift )

    import Language.Haskell.TH.Desugar.Util as Util

    #if __GLASGOW_HASKELL__ >= 907
    import qualified Language.Haskell.TH as LangExt (Extension(..))
    #endif

    -- | Like @reify@ from Template Haskell, but looks also in any not-yet-typechecked
    -- declarations. To establish this list of not-yet-typechecked declarations,
    -- use 'withLocalDeclarations'. Returns 'Nothing' if reification fails.
    -- Note that no inferred type information is available from local declarations;
    -- bottoms may be used if necessary.
    reifyWithLocals_maybe :: DsMonad q => Name -> q (Maybe Info)
    reifyWithLocals_maybe :: forall (q :: * -> *). DsMonad q => Name -> q (Maybe Info)
    reifyWithLocals_maybe Name
    name = q (Maybe Info) -> q (Maybe Info) -> q (Maybe Info)
    forall a. q a -> q a -> q a
    forall (m :: * -> *) a. Quasi m => m a -> m a -> m a
    qRecover
      (Maybe Info -> q (Maybe Info)
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe Info -> q (Maybe Info))
    -> ([Dec] -> Maybe Info) -> [Dec] -> q (Maybe Info)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> [Dec] -> Maybe Info
    reifyInDecs Name
    name ([Dec] -> q (Maybe Info)) -> q [Dec] -> q (Maybe Info)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< q [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations)
      (Info -> Maybe Info
    forall a. a -> Maybe a
    Just (Info -> Maybe Info) -> q Info -> q (Maybe Info)
    forall a b. (a -> b) -> q a -> q b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Name -> q Info
    forall (m :: * -> *). Quasi m => Name -> m Info
    qReify Name
    name)

    -- | Like 'reifyWithLocals_maybe', but throws an exception upon failure,
    -- warning the user about separating splices.
    reifyWithLocals :: DsMonad q => Name -> q Info
    reifyWithLocals :: forall (q :: * -> *). DsMonad q => Name -> q Info
    reifyWithLocals Name
    name = do
      m_info <- Name -> q (Maybe Info)
    forall (q :: * -> *). DsMonad q => Name -> q (Maybe Info)
    reifyWithLocals_maybe Name
    name
      case m_info of
        Maybe Info
    Nothing -> Name -> q Info
    forall (m :: * -> *) a. MonadFail m => Name -> m a
    reifyFail Name
    name
        Just Info
    i  -> Info -> q Info
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Info
    i

    -- | Reify a declaration, warning the user about splices if the reify fails.
    -- The warning says that reification can fail if you try to reify a type in
    -- the same splice as it is declared.
    reifyWithWarning :: (Quasi q, Fail.MonadFail q) => Name -> q Info
    reifyWithWarning :: forall (q :: * -> *). (Quasi q, MonadFail q) => Name -> q Info
    reifyWithWarning Name
    name = q Info -> q Info -> q Info
    forall a. q a -> q a -> q a
    forall (m :: * -> *) a. Quasi m => m a -> m a -> m a
    qRecover (Name -> q Info
    forall (m :: * -> *) a. MonadFail m => Name -> m a
    reifyFail Name
    name) (Name -> q Info
    forall (m :: * -> *). Quasi m => Name -> m Info
    qReify Name
    name)

    -- | Print out a warning about separating splices and fail.
    reifyFail :: Fail.MonadFail m => Name -> m a
    reifyFail :: forall (m :: * -> *) a. MonadFail m => Name -> m a
    reifyFail Name
    name =
      String -> m a
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    Fail.fail (String -> m a) -> String -> m a
    forall a b. (a -> b) -> a -> b
    $ String
    "Looking up " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Name -> String
    forall a. Show a => a -> String
    show Name
    name) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " in the list of available " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                  String
    "declarations failed.\nThis lookup fails if the declaration " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                  String
    "referenced was made in the same Template\nHaskell splice as the use " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                  String
    "of the declaration. If this is the case, put\nthe reference to " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                  String
    "the declaration in a new splice."

    ---------------------------------
    -- Utilities
    ---------------------------------

    -- | Extract the 'DataFlavor', 'TyVarBndr's and constructors given the 'Name'
    -- of a type.
    getDataD :: DsMonad q
             => String       -- ^ Print this out on failure
             -> Name         -- ^ Name of the datatype (@data@ or @newtype@) of interest
             -> q (DataFlavor, [TyVarBndrVis], [Con])
    getDataD :: forall (q :: * -> *).
    DsMonad q =>
    String -> Name -> q (DataFlavor, [TyVarBndrVis], [Con])
    getDataD String
    err Name
    name = do
      info <- Name -> q Info
    forall (q :: * -> *). DsMonad q => Name -> q Info
    reifyWithLocals Name
    name
      dec <- case info of
               TyConI Dec
    dec -> Dec -> q Dec
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Dec
    dec
               Info
    _ -> q Dec
    forall {a}. q a
    badDeclaration
      case dec of
        DataD Cxt
    _cxt Name
    _name [TyVarBndrVis]
    tvbs Maybe Kind
    mk [Con]
    cons [DerivClause]
    _derivings -> DataFlavor
    -> [TyVarBndrVis]
    -> Maybe Kind
    -> [Con]
    -> q (DataFlavor, [TyVarBndrVis], [Con])
    forall {m :: * -> *} {a} {c}.
    Quasi m =>
    a -> [TyVarBndrVis] -> Maybe Kind -> c -> m (a, [TyVarBndrVis], c)
    go DataFlavor
    Data [TyVarBndrVis]
    tvbs Maybe Kind
    mk [Con]
    cons
        NewtypeD Cxt
    _cxt Name
    _name [TyVarBndrVis]
    tvbs Maybe Kind
    mk Con
    con [DerivClause]
    _derivings -> DataFlavor
    -> [TyVarBndrVis]
    -> Maybe Kind
    -> [Con]
    -> q (DataFlavor, [TyVarBndrVis], [Con])
    forall {m :: * -> *} {a} {c}.
    Quasi m =>
    a -> [TyVarBndrVis] -> Maybe Kind -> c -> m (a, [TyVarBndrVis], c)
    go DataFlavor
    Newtype [TyVarBndrVis]
    tvbs Maybe Kind
    mk [Con
    con]
    #if __GLASGOW_HASKELL__ >= 906
        TypeDataD Name
    _name [TyVarBndrVis]
    tvbs Maybe Kind
    mk [Con]
    cons -> DataFlavor
    -> [TyVarBndrVis]
    -> Maybe Kind
    -> [Con]
    -> q (DataFlavor, [TyVarBndrVis], [Con])
    forall {m :: * -> *} {a} {c}.
    Quasi m =>
    a -> [TyVarBndrVis] -> Maybe Kind -> c -> m (a, [TyVarBndrVis], c)
    go DataFlavor
    Util.TypeData [TyVarBndrVis]
    tvbs Maybe Kind
    mk [Con]
    cons
    #endif
        Dec
    _ -> q (DataFlavor, [TyVarBndrVis], [Con])
    forall {a}. q a
    badDeclaration
      where
        go :: a -> [TyVarBndrVis] -> Maybe Kind -> c -> m (a, [TyVarBndrVis], c)
    go a
    df [TyVarBndrVis]
    tvbs Maybe Kind
    mk c
    cons = do
          let k :: Kind
    k = Kind -> Maybe Kind -> Kind
    forall a. a -> Maybe a -> a
    fromMaybe (Name -> Kind
    ConT Name
    typeKindName) Maybe Kind
    mk
          extra_tvbs <- Kind -> m [TyVarBndrVis]
    forall (q :: * -> *). Quasi q => Kind -> q [TyVarBndrVis]
    mkExtraKindBinders Kind
    k
          let all_tvbs = [TyVarBndrVis]
    tvbs [TyVarBndrVis] -> [TyVarBndrVis] -> [TyVarBndrVis]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndrVis]
    extra_tvbs
          return (df, all_tvbs, cons)

        badDeclaration :: q a
    badDeclaration =
              String -> q a
    forall a. String -> q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> q a) -> String -> q a
    forall a b. (a -> b) -> a -> b
    $ String
    "The name (" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Name -> String
    forall a. Show a => a -> String
    show Name
    name) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    ") refers to something " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                     String
    "other than a datatype. " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    err

    -- | Create new kind variable binder names corresponding to the return kind of
    -- a data type. This is useful when you have a data type like:
    --
    -- @
    -- data Foo :: forall k. k -> Type -> Type where ...
    -- @
    --
    -- But you want to be able to refer to the type @Foo a b@.
    -- 'mkExtraKindBinders' will take the kind @forall k. k -> Type -> Type@,
    -- discover that is has two visible argument kinds, and return as a result
    -- two new kind variable binders @[a :: k, b :: Type]@, where @a@ and @b@
    -- are fresh type variable names.
    --
    -- This expands kind synonyms if necessary.
    mkExtraKindBinders :: forall q. Quasi q => Kind -> q [TyVarBndrVis]
    mkExtraKindBinders :: forall (q :: * -> *). Quasi q => Kind -> q [TyVarBndrVis]
    mkExtraKindBinders Kind
    k = do
      k' <- Q Kind -> q Kind
    forall (m :: * -> *) a. Quasi m => Q a -> m a
    runQ (Q Kind -> q Kind) -> Q Kind -> q Kind
    forall a b. (a -> b) -> a -> b
    $ Kind -> Q Kind
    resolveTypeSynonyms Kind
    k
      let (fun_args, _) = unravelType k'
          vis_fun_args  = FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    fun_args
      mapM mk_tvb vis_fun_args
      where
        mk_tvb :: VisFunArg -> q TyVarBndrVis
        mk_tvb :: VisFunArg -> q TyVarBndrVis
    mk_tvb (VisFADep TyVarBndrUnit
    tvb) = TyVarBndrVis -> q TyVarBndrVis
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TyVarBndrVis -> q TyVarBndrVis) -> TyVarBndrVis -> q TyVarBndrVis
    forall a b. (a -> b) -> a -> b
    $ (() -> BndrVis) -> TyVarBndrUnit -> TyVarBndrVis
    forall flag flag'.
    (flag -> flag') -> TyVarBndr_ flag -> TyVarBndr_ flag'
    mapTVFlag (BndrVis -> () -> BndrVis
    forall a b. a -> b -> a
    const BndrVis
    BndrReq) TyVarBndrUnit
    tvb
        mk_tvb (VisFAAnon Kind
    ki) = do
          name <- String -> q Name
    forall (m :: * -> *). Quasi m => String -> m Name
    qNewName String
    "a"
          pure $ kindedTVFlag name BndrReq ki

    -- | From the name of a data constructor, retrive the datatype definition it
    -- is a part of.
    dataConNameToDataName :: DsMonad q => Name -> q Name
    dataConNameToDataName :: forall (q :: * -> *). DsMonad q => Name -> q Name
    dataConNameToDataName Name
    con_name = do
      info <- Name -> q Info
    forall (q :: * -> *). DsMonad q => Name -> q Info
    reifyWithLocals Name
    con_name
      case info of
        DataConI Name
    _name Kind
    _type Name
    parent_name -> Name -> q Name
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Name
    parent_name
        Info
    _ -> String -> q Name
    forall a. String -> q a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> q Name) -> String -> q Name
    forall a b. (a -> b) -> a -> b
    $ String
    "The name " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Name -> String
    forall a. Show a => a -> String
    show Name
    con_name String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " does not appear to be " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++
                    String
    "a data constructor."

    -- | From the name of a data constructor, retrieve its definition as a @Con@
    dataConNameToCon :: DsMonad q => Name -> q Con
    dataConNameToCon :: forall (q :: * -> *). DsMonad q => Name -> q Con
    dataConNameToCon Name
    con_name = do
      -- we need to get the field ordering from the constructor. We must reify
      -- the constructor to get the tycon, and then reify the tycon to get the `Con`s
      type_name <- Name -> q Name
    forall (q :: * -> *). DsMonad q => Name -> q Name
    dataConNameToDataName Name
    con_name
      (_, _, cons) <- getDataD "This seems to be an error in GHC." type_name
      let m_con = (Con -> Bool) -> [Con] -> Maybe Con
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    List.find ((Name -> Bool) -> [Name] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Name
    con_name Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    ==) ([Name] -> Bool) -> (Con -> [Name]) -> Con -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Con -> [Name]
    get_con_name) [Con]
    cons
      case m_con of
        Just Con
    con -> Con -> q Con
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Con
    con
        Maybe Con
    Nothing -> String -> q Con
    forall (q :: * -> *) a. MonadFail q => String -> q a
    impossible String
    "Datatype does not contain one of its own constructors."

      where
        get_con_name :: Con -> [Name]
    get_con_name (NormalC Name
    name [BangType]
    _)     = [Name
    name]
        get_con_name (RecC Name
    name [VarBangType]
    _)        = [Name
    name]
        get_con_name (InfixC BangType
    _ Name
    name BangType
    _)    = [Name
    name]
        get_con_name (ForallC [TyVarBndr Specificity]
    _ Cxt
    _ Con
    con)    = Con -> [Name]
    get_con_name Con
    con
        get_con_name (GadtC [Name]
    names [BangType]
    _ Kind
    _)    = [Name]
    names
        get_con_name (RecGadtC [Name]
    names [VarBangType]
    _ Kind
    _) = [Name]
    names

    --------------------------------------------------
    -- DsMonad
    --------------------------------------------------

    -- | A 'DsMonad' stores some list of declarations that should be considered
    -- in scope. 'DsM' is the prototypical inhabitant of 'DsMonad'.
    class (Quasi m, Fail.MonadFail m) => DsMonad m where
      -- | Produce a list of local declarations.
      localDeclarations :: m [Dec]

    instance DsMonad Q where
      localDeclarations :: Q [Dec]
    localDeclarations = [Dec] -> Q [Dec]
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
    instance DsMonad IO where
      localDeclarations :: IO [Dec]
    localDeclarations = [Dec] -> IO [Dec]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

    -- | A convenient implementation of the 'DsMonad' class. Use by calling
    -- 'withLocalDeclarations'.
    newtype DsM q a = DsM (ReaderT [Dec] q a)
      deriving ( (forall a b. (a -> b) -> DsM q a -> DsM q b)
    -> (forall a b. a -> DsM q b -> DsM q a) -> Functor (DsM q)
    forall a b. a -> DsM q b -> DsM q a
    forall a b. (a -> b) -> DsM q a -> DsM q b
    forall (q :: * -> *) a b. Functor q => a -> DsM q b -> DsM q a
    forall (q :: * -> *) a b.
    Functor q =>
    (a -> b) -> DsM q a -> DsM q b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall (q :: * -> *) a b.
    Functor q =>
    (a -> b) -> DsM q a -> DsM q b
    fmap :: forall a b. (a -> b) -> DsM q a -> DsM q b
    $c<$ :: forall (q :: * -> *) a b. Functor q => a -> DsM q b -> DsM q a
    <$ :: forall a b. a -> DsM q b -> DsM q a
    Functor, Functor (DsM q)
    Functor (DsM q) =>
    (forall a. a -> DsM q a)
    -> (forall a b. DsM q (a -> b) -> DsM q a -> DsM q b)
    -> (forall a b c. (a -> b -> c) -> DsM q a -> DsM q b -> DsM q c)
    -> (forall a b. DsM q a -> DsM q b -> DsM q b)
    -> (forall a b. DsM q a -> DsM q b -> DsM q a)
    -> Applicative (DsM q)
    forall a. a -> DsM q a
    forall a b. DsM q a -> DsM q b -> DsM q a
    forall a b. DsM q a -> DsM q b -> DsM q b
    forall a b. DsM q (a -> b) -> DsM q a -> DsM q b
    forall a b c. (a -> b -> c) -> DsM q a -> DsM q b -> DsM q c
    forall (f :: * -> *).
    Functor f =>
    (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    forall (q :: * -> *). Applicative q => Functor (DsM q)
    forall (q :: * -> *) a. Applicative q => a -> DsM q a
    forall (q :: * -> *) a b.
    Applicative q =>
    DsM q a -> DsM q b -> DsM q a
    forall (q :: * -> *) a b.
    Applicative q =>
    DsM q a -> DsM q b -> DsM q b
    forall (q :: * -> *) a b.
    Applicative q =>
    DsM q (a -> b) -> DsM q a -> DsM q b
    forall (q :: * -> *) a b c.
    Applicative q =>
    (a -> b -> c) -> DsM q a -> DsM q b -> DsM q c
    $cpure :: forall (q :: * -> *) a. Applicative q => a -> DsM q a
    pure :: forall a. a -> DsM q a
    $c<*> :: forall (q :: * -> *) a b.
    Applicative q =>
    DsM q (a -> b) -> DsM q a -> DsM q b
    <*> :: forall a b. DsM q (a -> b) -> DsM q a -> DsM q b
    $cliftA2 :: forall (q :: * -> *) a b c.
    Applicative q =>
    (a -> b -> c) -> DsM q a -> DsM q b -> DsM q c
    liftA2 :: forall a b c. (a -> b -> c) -> DsM q a -> DsM q b -> DsM q c
    $c*> :: forall (q :: * -> *) a b.
    Applicative q =>
    DsM q a -> DsM q b -> DsM q b
    *> :: forall a b. DsM q a -> DsM q b -> DsM q b
    $c<* :: forall (q :: * -> *) a b.
    Applicative q =>
    DsM q a -> DsM q b -> DsM q a
    <* :: forall a b. DsM q a -> DsM q b -> DsM q a
    Applicative, Applicative (DsM q)
    Applicative (DsM q) =>
    (forall a b. DsM q a -> (a -> DsM q b) -> DsM q b)
    -> (forall a b. DsM q a -> DsM q b -> DsM q b)
    -> (forall a. a -> DsM q a)
    -> Monad (DsM q)
    forall a. a -> DsM q a
    forall a b. DsM q a -> DsM q b -> DsM q b
    forall a b. DsM q a -> (a -> DsM q b) -> DsM q b
    forall (q :: * -> *). Monad q => Applicative (DsM q)
    forall (q :: * -> *) a. Monad q => a -> DsM q a
    forall (q :: * -> *) a b. Monad q => DsM q a -> DsM q b -> DsM q b
    forall (q :: * -> *) a b.
    Monad q =>
    DsM q a -> (a -> DsM q b) -> DsM q b
    forall (m :: * -> *).
    Applicative m =>
    (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall (q :: * -> *) a b.
    Monad q =>
    DsM q a -> (a -> DsM q b) -> DsM q b
    >>= :: forall a b. DsM q a -> (a -> DsM q b) -> DsM q b
    $c>> :: forall (q :: * -> *) a b. Monad q => DsM q a -> DsM q b -> DsM q b
    >> :: forall a b. DsM q a -> DsM q b -> DsM q b
    $creturn :: forall (q :: * -> *) a. Monad q => a -> DsM q a
    return :: forall a. a -> DsM q a
    Monad, (forall (q :: * -> *). Monad q => Monad (DsM q)) =>
    (forall (m :: * -> *) a. Monad m => m a -> DsM m a)
    -> MonadTrans DsM
    forall (q :: * -> *). Monad q => Monad (DsM q)
    forall (m :: * -> *) a. Monad m => m a -> DsM m a
    forall (t :: (* -> *) -> * -> *).
    (forall (m :: * -> *). Monad m => Monad (t m)) =>
    (forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
    $clift :: forall (m :: * -> *) a. Monad m => m a -> DsM m a
    lift :: forall (m :: * -> *) a. Monad m => m a -> DsM m a
    MonadTrans, MonadFail (DsM q)
    MonadIO (DsM q)
    DsM q String
    DsM q [Extension]
    DsM q Loc
    Bool -> String -> DsM q (Maybe Name)
    Bool -> String -> DsM q ()
    String -> DsM q String
    String -> DsM q Name
    String -> DsM q ()
    [Dec] -> DsM q ()
    Q () -> DsM q ()
    Name -> DsM q [Role]
    Name -> DsM q [DecidedStrictness]
    Name -> DsM q (Maybe Fixity)
    Name -> DsM q Kind
    Name -> DsM q Info
    Name -> Cxt -> DsM q [Dec]
    (MonadIO (DsM q), MonadFail (DsM q)) =>
    (String -> DsM q Name)
    -> (Bool -> String -> DsM q ())
    -> (forall a. DsM q a -> DsM q a -> DsM q a)
    -> (Bool -> String -> DsM q (Maybe Name))
    -> (Name -> DsM q Info)
    -> (Name -> DsM q (Maybe Fixity))
    -> (Name -> DsM q Kind)
    -> (Name -> Cxt -> DsM q [Dec])
    -> (Name -> DsM q [Role])
    -> (forall a. Data a => AnnLookup -> DsM q [a])
    -> (Module -> DsM q ModuleInfo)
    -> (Name -> DsM q [DecidedStrictness])
    -> DsM q Loc
    -> (forall a. IO a -> DsM q a)
    -> DsM q String
    -> (String -> DsM q ())
    -> (String -> DsM q String)
    -> ([Dec] -> DsM q ())
    -> (ForeignSrcLang -> String -> DsM q ())
    -> (Q () -> DsM q ())
    -> (String -> DsM q ())
    -> (forall a. Typeable a => DsM q (Maybe a))
    -> (forall a. Typeable a => a -> DsM q ())
    -> (Extension -> DsM q Bool)
    -> DsM q [Extension]
    -> (DocLoc -> String -> DsM q ())
    -> (DocLoc -> DsM q (Maybe String))
    -> Quasi (DsM q)
    ForeignSrcLang -> String -> DsM q ()
    Extension -> DsM q Bool
    DocLoc -> DsM q (Maybe String)
    DocLoc -> String -> DsM q ()
    Module -> DsM q ModuleInfo
    forall a. Data a => AnnLookup -> DsM q [a]
    forall a. Typeable a => DsM q (Maybe a)
    forall a. Typeable a => a -> DsM q ()
    forall a. IO a -> DsM q a
    forall a. DsM q a -> DsM q a -> DsM q a
    forall (m :: * -> *).
    (MonadIO m, MonadFail m) =>
    (String -> m Name)
    -> (Bool -> String -> m ())
    -> (forall a. m a -> m a -> m a)
    -> (Bool -> String -> m (Maybe Name))
    -> (Name -> m Info)
    -> (Name -> m (Maybe Fixity))
    -> (Name -> m Kind)
    -> (Name -> Cxt -> m [Dec])
    -> (Name -> m [Role])
    -> (forall a. Data a => AnnLookup -> m [a])
    -> (Module -> m ModuleInfo)
    -> (Name -> m [DecidedStrictness])
    -> m Loc
    -> (forall a. IO a -> m a)
    -> m String
    -> (String -> m ())
    -> (String -> m String)
    -> ([Dec] -> m ())
    -> (ForeignSrcLang -> String -> m ())
    -> (Q () -> m ())
    -> (String -> m ())
    -> (forall a. Typeable a => m (Maybe a))
    -> (forall a. Typeable a => a -> m ())
    -> (Extension -> m Bool)
    -> m [Extension]
    -> (DocLoc -> String -> m ())
    -> (DocLoc -> m (Maybe String))
    -> Quasi m
    forall (q :: * -> *). Quasi q => MonadFail (DsM q)
    forall (q :: * -> *). Quasi q => MonadIO (DsM q)
    forall (q :: * -> *). Quasi q => DsM q String
    forall (q :: * -> *). Quasi q => DsM q [Extension]
    forall (q :: * -> *). Quasi q => DsM q Loc
    forall (q :: * -> *).
    Quasi q =>
    Bool -> String -> DsM q (Maybe Name)
    forall (q :: * -> *). Quasi q => Bool -> String -> DsM q ()
    forall (q :: * -> *). Quasi q => String -> DsM q String
    forall (q :: * -> *). Quasi q => String -> DsM q Name
    forall (q :: * -> *). Quasi q => String -> DsM q ()
    forall (q :: * -> *). Quasi q => [Dec] -> DsM q ()
    forall (q :: * -> *). Quasi q => Q () -> DsM q ()
    forall (q :: * -> *). Quasi q => Name -> DsM q [Role]
    forall (q :: * -> *). Quasi q => Name -> DsM q [DecidedStrictness]
    forall (q :: * -> *). Quasi q => Name -> DsM q (Maybe Fixity)
    forall (q :: * -> *). Quasi q => Name -> DsM q Kind
    forall (q :: * -> *). Quasi q => Name -> DsM q Info
    forall (q :: * -> *). Quasi q => Name -> Cxt -> DsM q [Dec]
    forall (q :: * -> *).
    Quasi q =>
    ForeignSrcLang -> String -> DsM q ()
    forall (q :: * -> *). Quasi q => Extension -> DsM q Bool
    forall (q :: * -> *). Quasi q => DocLoc -> DsM q (Maybe String)
    forall (q :: * -> *). Quasi q => DocLoc -> String -> DsM q ()
    forall (q :: * -> *). Quasi q => Module -> DsM q ModuleInfo
    forall (q :: * -> *) a. (Quasi q, Data a) => AnnLookup -> DsM q [a]
    forall (q :: * -> *) a. (Quasi q, Typeable a) => DsM q (Maybe a)
    forall (q :: * -> *) a. (Quasi q, Typeable a) => a -> DsM q ()
    forall (q :: * -> *) a. Quasi q => IO a -> DsM q a
    forall (q :: * -> *) a. Quasi q => DsM q a -> DsM q a -> DsM q a
    $cqNewName :: forall (q :: * -> *). Quasi q => String -> DsM q Name
    qNewName :: String -> DsM q Name
    $cqReport :: forall (q :: * -> *). Quasi q => Bool -> String -> DsM q ()
    qReport :: Bool -> String -> DsM q ()
    $cqRecover :: forall (q :: * -> *) a. Quasi q => DsM q a -> DsM q a -> DsM q a
    qRecover :: forall a. DsM q a -> DsM q a -> DsM q a
    $cqLookupName :: forall (q :: * -> *).
    Quasi q =>
    Bool -> String -> DsM q (Maybe Name)
    qLookupName :: Bool -> String -> DsM q (Maybe Name)
    $cqReify :: forall (q :: * -> *). Quasi q => Name -> DsM q Info
    qReify :: Name -> DsM q Info
    $cqReifyFixity :: forall (q :: * -> *). Quasi q => Name -> DsM q (Maybe Fixity)
    qReifyFixity :: Name -> DsM q (Maybe Fixity)
    $cqReifyType :: forall (q :: * -> *). Quasi q => Name -> DsM q Kind
    qReifyType :: Name -> DsM q Kind
    $cqReifyInstances :: forall (q :: * -> *). Quasi q => Name -> Cxt -> DsM q [Dec]
    qReifyInstances :: Name -> Cxt -> DsM q [Dec]
    $cqReifyRoles :: forall (q :: * -> *). Quasi q => Name -> DsM q [Role]
    qReifyRoles :: Name -> DsM q [Role]
    $cqReifyAnnotations :: forall (q :: * -> *) a. (Quasi q, Data a) => AnnLookup -> DsM q [a]
    qReifyAnnotations :: forall a. Data a => AnnLookup -> DsM q [a]
    $cqReifyModule :: forall (q :: * -> *). Quasi q => Module -> DsM q ModuleInfo
    qReifyModule :: Module -> DsM q ModuleInfo
    $cqReifyConStrictness :: forall (q :: * -> *). Quasi q => Name -> DsM q [DecidedStrictness]
    qReifyConStrictness :: Name -> DsM q [DecidedStrictness]
    $cqLocation :: forall (q :: * -> *). Quasi q => DsM q Loc
    qLocation :: DsM q Loc
    $cqRunIO :: forall (q :: * -> *) a. Quasi q => IO a -> DsM q a
    qRunIO :: forall a. IO a -> DsM q a
    $cqGetPackageRoot :: forall (q :: * -> *). Quasi q => DsM q String
    qGetPackageRoot :: DsM q String
    $cqAddDependentFile :: forall (q :: * -> *). Quasi q => String -> DsM q ()
    qAddDependentFile :: String -> DsM q ()
    $cqAddTempFile :: forall (q :: * -> *). Quasi q => String -> DsM q String
    qAddTempFile :: String -> DsM q String
    $cqAddTopDecls :: forall (q :: * -> *). Quasi q => [Dec] -> DsM q ()
    qAddTopDecls :: [Dec] -> DsM q ()
    $cqAddForeignFilePath :: forall (q :: * -> *).
    Quasi q =>
    ForeignSrcLang -> String -> DsM q ()
    qAddForeignFilePath :: ForeignSrcLang -> String -> DsM q ()
    $cqAddModFinalizer :: forall (q :: * -> *). Quasi q => Q () -> DsM q ()
    qAddModFinalizer :: Q () -> DsM q ()
    $cqAddCorePlugin :: forall (q :: * -> *). Quasi q => String -> DsM q ()
    qAddCorePlugin :: String -> DsM q ()
    $cqGetQ :: forall (q :: * -> *) a. (Quasi q, Typeable a) => DsM q (Maybe a)
    qGetQ :: forall a. Typeable a => DsM q (Maybe a)
    $cqPutQ :: forall (q :: * -> *) a. (Quasi q, Typeable a) => a -> DsM q ()
    qPutQ :: forall a. Typeable a => a -> DsM q ()
    $cqIsExtEnabled :: forall (q :: * -> *). Quasi q => Extension -> DsM q Bool
    qIsExtEnabled :: Extension -> DsM q Bool
    $cqExtsEnabled :: forall (q :: * -> *). Quasi q => DsM q [Extension]
    qExtsEnabled :: DsM q [Extension]
    $cqPutDoc :: forall (q :: * -> *). Quasi q => DocLoc -> String -> DsM q ()
    qPutDoc :: DocLoc -> String -> DsM q ()
    $cqGetDoc :: forall (q :: * -> *). Quasi q => DocLoc -> DsM q (Maybe String)
    qGetDoc :: DocLoc -> DsM q (Maybe String)
    Quasi, Monad (DsM q)
    Monad (DsM q) => (forall a. String -> DsM q a) -> MonadFail (DsM q)
    forall a. String -> DsM q a
    forall (m :: * -> *).
    Monad m =>
    (forall a. String -> m a) -> MonadFail m
    forall (q :: * -> *). MonadFail q => Monad (DsM q)
    forall (q :: * -> *) a. MonadFail q => String -> DsM q a
    $cfail :: forall (q :: * -> *) a. MonadFail q => String -> DsM q a
    fail :: forall a. String -> DsM q a
    Fail.MonadFail
    #if __GLASGOW_HASKELL__ >= 803
               , Monad (DsM q)
    Monad (DsM q) => (forall a. IO a -> DsM q a) -> MonadIO (DsM q)
    forall a. IO a -> DsM q a
    forall (m :: * -> *).
    Monad m =>
    (forall a. IO a -> m a) -> MonadIO m
    forall (q :: * -> *). MonadIO q => Monad (DsM q)
    forall (q :: * -> *) a. MonadIO q => IO a -> DsM q a
    $cliftIO :: forall (q :: * -> *) a. MonadIO q => IO a -> DsM q a
    liftIO :: forall a. IO a -> DsM q a
    MonadIO
    #endif
               )

    instance (Quasi q, Fail.MonadFail q) => DsMonad (DsM q) where
      localDeclarations :: DsM q [Dec]
    localDeclarations = ReaderT [Dec] q [Dec] -> DsM q [Dec]
    forall (q :: * -> *) a. ReaderT [Dec] q a -> DsM q a
    DsM ReaderT [Dec] q [Dec]
    forall r (m :: * -> *). MonadReader r m => m r
    ask

    instance DsMonad m => DsMonad (ReaderT r m) where
      localDeclarations :: ReaderT r m [Dec]
    localDeclarations = m [Dec] -> ReaderT r m [Dec]
    forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations

    instance DsMonad m => DsMonad (StateT s m) where
      localDeclarations :: StateT s m [Dec]
    localDeclarations = m [Dec] -> StateT s m [Dec]
    forall (m :: * -> *) a. Monad m => m a -> StateT s m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations

    instance (DsMonad m, Monoid w) => DsMonad (WriterT w m) where
      localDeclarations :: WriterT w m [Dec]
    localDeclarations = m [Dec] -> WriterT w m [Dec]
    forall (m :: * -> *) a. Monad m => m a -> WriterT w m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations

    instance (DsMonad m, Monoid w) => DsMonad (RWST r w s m) where
      localDeclarations :: RWST r w s m [Dec]
    localDeclarations = m [Dec] -> RWST r w s m [Dec]
    forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations

    -- | Add a list of declarations to be considered when reifying local
    -- declarations.
    withLocalDeclarations :: DsMonad q => [Dec] -> DsM q a -> q a
    withLocalDeclarations :: forall (q :: * -> *) a. DsMonad q => [Dec] -> DsM q a -> q a
    withLocalDeclarations [Dec]
    new_decs (DsM ReaderT [Dec] q a
    x) = do
      orig_decs <- q [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations
      runReaderT x (orig_decs ++ new_decs)

    ---------------------------
    -- Reifying local declarations
    ---------------------------

    -- | Look through a list of declarations and possibly return a relevant 'Info'
    reifyInDecs :: Name -> [Dec] -> Maybe Info
    reifyInDecs :: Name -> [Dec] -> Maybe Info
    reifyInDecs Name
    n [Dec]
    decs = (Name, Info) -> Info
    forall a b. (a, b) -> b
    snd ((Name, Info) -> Info) -> Maybe (Name, Info) -> Maybe Info
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` (Dec -> Maybe (Name, Info)) -> [Dec] -> Maybe (Name, Info)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> [Dec] -> Dec -> Maybe (Name, Info)
    reifyInDec Name
    n [Dec]
    decs) [Dec]
    decs

    -- | Look through a list of declarations and possibly return a fixity.
    reifyFixityInDecs :: Name -> [Dec] -> Maybe Fixity
    reifyFixityInDecs :: Name -> [Dec] -> Maybe Fixity
    reifyFixityInDecs Name
    n = (Dec -> Maybe Fixity) -> [Dec] -> Maybe Fixity
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Dec -> Maybe Fixity
    match_fixity
      where
        match_fixity :: Dec -> Maybe Fixity
    match_fixity (InfixD Fixity
    fixity
    #if __GLASGOW_HASKELL__ >= 909
                             NamespaceSpecifier
    _
    #endif
                             Name
    n')               | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
                                               = Fixity -> Maybe Fixity
    forall a. a -> Maybe a
    Just Fixity
    fixity
        match_fixity (ClassD Cxt
    _ Name
    _ [TyVarBndrVis]
    _ [FunDep]
    _ [Dec]
    sub_decs) = (Dec -> Maybe Fixity) -> [Dec] -> Maybe Fixity
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Dec -> Maybe Fixity
    match_fixity [Dec]
    sub_decs
        match_fixity Dec
    _                         = Maybe Fixity
    forall a. Maybe a
    Nothing

    -- | A reified thing along with the name of that thing.
    type Named a = (Name, a)

    reifyInDec :: Name -> [Dec] -> Dec -> Maybe (Named Info)
    reifyInDec :: Name -> [Dec] -> Dec -> Maybe (Name, Info)
    reifyInDec Name
    n [Dec]
    decs (FunD Name
    n' [Clause]
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> [Dec] -> Info
    mkVarI Name
    n [Dec]
    decs)
    reifyInDec Name
    n [Dec]
    decs (ValD Pat
    pat Body
    _ [Dec]
    _)
      | Just Name
    n' <- (Name -> Bool) -> [Name] -> Maybe Name
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    List.find (Name -> Name -> Bool
    nameMatches Name
    n) (OSet Name -> [Name]
    forall a. OSet a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    F.toList (Pat -> OSet Name
    extractBoundNamesPat Pat
    pat))
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> [Dec] -> Info
    mkVarI Name
    n [Dec]
    decs)
    reifyInDec Name
    n [Dec]
    _    dec :: Dec
    dec@(DataD    Cxt
    _ Name
    n' [TyVarBndrVis]
    _ Maybe Kind
    _ [Con]
    _ [DerivClause]
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> Info
    TyConI Dec
    dec)
    reifyInDec Name
    n [Dec]
    _    dec :: Dec
    dec@(NewtypeD Cxt
    _ Name
    n' [TyVarBndrVis]
    _ Maybe Kind
    _ Con
    _ [DerivClause]
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> Info
    TyConI Dec
    dec)
    reifyInDec Name
    n [Dec]
    _    dec :: Dec
    dec@(TySynD Name
    n' [TyVarBndrVis]
    _ Kind
    _)       | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> Info
    TyConI Dec
    dec)
    reifyInDec Name
    n [Dec]
    decs dec :: Dec
    dec@(ClassD Cxt
    _ Name
    n' [TyVarBndrVis]
    _ [FunDep]
    _ [Dec]
    _)   | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> [Dec] -> Info
    ClassI (Dec -> Dec
    quantifyClassDecMethods Dec
    dec) (Name -> [Dec] -> [Dec]
    findInstances Name
    n [Dec]
    decs))
    reifyInDec Name
    n [Dec]
    _    (ForeignD (ImportF Callconv
    _ Safety
    _ String
    _ Name
    n' Kind
    ty)) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> Kind -> Info
    mkVarITy Name
    n Kind
    ty)
    reifyInDec Name
    n [Dec]
    _    (ForeignD (ExportF Callconv
    _ String
    _ Name
    n' Kind
    ty)) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> Kind -> Info
    mkVarITy Name
    n Kind
    ty)
    reifyInDec Name
    n [Dec]
    decs dec :: Dec
    dec@(OpenTypeFamilyD (TypeFamilyHead Name
    n' [TyVarBndrVis]
    _ FamilyResultSig
    _ Maybe InjectivityAnn
    _)) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> [Dec] -> Info
    FamilyI Dec
    dec (Name -> [Dec] -> [Dec]
    findInstances Name
    n [Dec]
    decs))
    reifyInDec Name
    n [Dec]
    decs dec :: Dec
    dec@(DataFamilyD Name
    n' [TyVarBndrVis]
    _ Maybe Kind
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> [Dec] -> Info
    FamilyI Dec
    dec (Name -> [Dec] -> [Dec]
    findInstances Name
    n [Dec]
    decs))
    reifyInDec Name
    n [Dec]
    _    dec :: Dec
    dec@(ClosedTypeFamilyD (TypeFamilyHead Name
    n' [TyVarBndrVis]
    _ FamilyResultSig
    _ Maybe InjectivityAnn
    _) [TySynEqn]
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> [Dec] -> Info
    FamilyI Dec
    dec [])
    #if __GLASGOW_HASKELL__ >= 801
    reifyInDec Name
    n [Dec]
    decs (PatSynD Name
    n' PatSynArgs
    _ PatSynDir
    _ Pat
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> [Dec] -> Info
    mkPatSynI Name
    n [Dec]
    decs)
    #endif
    #if __GLASGOW_HASKELL__ >= 906
    reifyInDec Name
    n [Dec]
    _ dec :: Dec
    dec@(TypeDataD Name
    n' [TyVarBndrVis]
    _ Maybe Kind
    _ [Con]
    _) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Dec -> Info
    TyConI Dec
    dec)
    #endif

    reifyInDec Name
    n [Dec]
    decs (DataD Cxt
    _ Name
    ty_name [TyVarBndrVis]
    tvbs Maybe Kind
    _mk [Con]
    cons [DerivClause]
    _)
      | Just (Name, Info)
    info <- Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Name, Info)
    maybeReifyCon Name
    n [Dec]
    decs Name
    ty_name ((TyVarBndrVis -> TypeArg) -> [TyVarBndrVis] -> [TypeArg]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TypeArg
    tyVarBndrVisToTypeArgWithSig [TyVarBndrVis]
    tvbs) [Con]
    cons
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
    reifyInDec Name
    n [Dec]
    decs (NewtypeD Cxt
    _ Name
    ty_name [TyVarBndrVis]
    tvbs Maybe Kind
    _mk Con
    con [DerivClause]
    _)
      | Just (Name, Info)
    info <- Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Name, Info)
    maybeReifyCon Name
    n [Dec]
    decs Name
    ty_name ((TyVarBndrVis -> TypeArg) -> [TyVarBndrVis] -> [TypeArg]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TypeArg
    tyVarBndrVisToTypeArgWithSig [TyVarBndrVis]
    tvbs) [Con
    con]
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
    reifyInDec Name
    n [Dec]
    _decs (ClassD Cxt
    _ Name
    ty_name [TyVarBndrVis]
    tvbs [FunDep]
    _ [Dec]
    sub_decs)
      | Just (Name
    n', Kind
    ty) <- Name -> [Dec] -> Maybe (Named Kind)
    findType Name
    n [Dec]
    sub_decs
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> Kind -> Name -> Info
    ClassOpI Name
    n (Name -> [TyVarBndrVis] -> Bool -> Kind -> Kind
    quantifyClassMethodType Name
    ty_name [TyVarBndrVis]
    tvbs Bool
    True Kind
    ty) Name
    ty_name)
    reifyInDec Name
    n [Dec]
    decs (ClassD Cxt
    _ Name
    _ [TyVarBndrVis]
    _ [FunDep]
    _ [Dec]
    sub_decs)
      | Just (Name, Info)
    info <- (Dec -> Maybe (Name, Info)) -> [Dec] -> Maybe (Name, Info)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> [Dec] -> Dec -> Maybe (Name, Info)
    reifyInDec Name
    n [Dec]
    decs) [Dec]
    sub_decs
                     -- Important: don't pass (sub_decs ++ decs) to reifyInDec
                     -- above, or else type family defaults can be confused for
                     -- actual instances. See #134.
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
    reifyInDec Name
    n [Dec]
    decs (InstanceD Maybe Overlap
    _ Cxt
    _ Kind
    _ [Dec]
    sub_decs)
      | Just (Name, Info)
    info <- (Dec -> Maybe (Name, Info)) -> [Dec] -> Maybe (Name, Info)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Dec -> Maybe (Name, Info)
    reify_in_instance [Dec]
    sub_decs
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
      where
        reify_in_instance :: Dec -> Maybe (Name, Info)
    reify_in_instance dec :: Dec
    dec@(DataInstD {})    = Name -> [Dec] -> Dec -> Maybe (Name, Info)
    reifyInDec Name
    n ([Dec]
    sub_decs [Dec] -> [Dec] -> [Dec]
    forall a. [a] -> [a] -> [a]
    ++ [Dec]
    decs) Dec
    dec
        reify_in_instance dec :: Dec
    dec@(NewtypeInstD {}) = Name -> [Dec] -> Dec -> Maybe (Name, Info)
    reifyInDec Name
    n ([Dec]
    sub_decs [Dec] -> [Dec] -> [Dec]
    forall a. [a] -> [a] -> [a]
    ++ [Dec]
    decs) Dec
    dec
        reify_in_instance Dec
    _                     = Maybe (Name, Info)
    forall a. Maybe a
    Nothing
    #if __GLASGOW_HASKELL__ >= 801
    reifyInDec Name
    n [Dec]
    decs (PatSynD Name
    pat_syn_name PatSynArgs
    args PatSynDir
    _ Pat
    _)
      | Just (Name
    n', Kind
    full_sel_ty) <- Name -> [Dec] -> Name -> PatSynArgs -> Maybe (Named Kind)
    maybeReifyPatSynRecSelector Name
    n [Dec]
    decs Name
    pat_syn_name PatSynArgs
    args
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> Kind -> Maybe Dec -> Info
    VarI Name
    n Kind
    full_sel_ty Maybe Dec
    forall a. Maybe a
    Nothing)
    #endif
    #if __GLASGOW_HASKELL__ >= 807
    reifyInDec Name
    n [Dec]
    decs (DataInstD Cxt
    _ Maybe [TyVarBndrUnit]
    _ Kind
    lhs Maybe Kind
    _ [Con]
    cons [DerivClause]
    _)
      | (ConT Name
    ty_name, [TypeArg]
    tys) <- Kind -> (Kind, [TypeArg])
    unfoldType Kind
    lhs
      , Just (Name, Info)
    info <- Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Name, Info)
    maybeReifyCon Name
    n [Dec]
    decs Name
    ty_name [TypeArg]
    tys [Con]
    cons
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
    reifyInDec Name
    n [Dec]
    decs (NewtypeInstD Cxt
    _ Maybe [TyVarBndrUnit]
    _ Kind
    lhs Maybe Kind
    _ Con
    con [DerivClause]
    _)
      | (ConT Name
    ty_name, [TypeArg]
    tys) <- Kind -> (Kind, [TypeArg])
    unfoldType Kind
    lhs
      , Just (Name, Info)
    info <- Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Name, Info)
    maybeReifyCon Name
    n [Dec]
    decs Name
    ty_name [TypeArg]
    tys [Con
    con]
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
    #else
    reifyInDec n decs (DataInstD _ ty_name tys _ cons _)
      | Just info <- maybeReifyCon n decs ty_name (map TANormal tys) cons
      = Just info
    reifyInDec n decs (NewtypeInstD _ ty_name tys _ con _)
      | Just info <- maybeReifyCon n decs ty_name (map TANormal tys) [con]
      = Just info
    #endif
    #if __GLASGOW_HASKELL__ >= 906
    reifyInDec Name
    n [Dec]
    decs (TypeDataD Name
    ty_name [TyVarBndrVis]
    tvbs Maybe Kind
    _mk [Con]
    cons)
      | Just (Name, Info)
    info <- Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Name, Info)
    maybeReifyCon Name
    n [Dec]
    decs Name
    ty_name ((TyVarBndrVis -> TypeArg) -> [TyVarBndrVis] -> [TypeArg]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TypeArg
    tyVarBndrVisToTypeArgWithSig [TyVarBndrVis]
    tvbs) [Con]
    cons
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name, Info)
    info
    #endif

    reifyInDec Name
    _ [Dec]
    _ Dec
    _ = Maybe (Name, Info)
    forall a. Maybe a
    Nothing

    maybeReifyCon :: Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Named Info)
    maybeReifyCon :: Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Name, Info)
    maybeReifyCon Name
    n [Dec]
    _decs Name
    ty_name [TypeArg]
    ty_args [Con]
    cons
      | Just (Name
    n', Con
    con) <- Name -> [Con] -> Maybe (Named Con)
    findCon Name
    n [Con]
    cons
        -- See Note [Use unSigType in maybeReifyCon]
      , let full_con_ty :: Kind
    full_con_ty = Kind -> Kind
    unSigType (Kind -> Kind) -> Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ [TyVarBndrUnit] -> Kind -> Con -> Kind
    con_to_type [TyVarBndrUnit]
    h98_tvbs Kind
    h98_res_ty Con
    con
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> Kind -> Name -> Info
    DataConI Name
    n Kind
    full_con_ty Name
    ty_name)

      | Just (Name
    n', RecSelInfo
    rec_sel_info) <- Name -> [Con] -> Maybe (Named RecSelInfo)
    findRecSelector Name
    n [Con]
    cons
      , let ([TyVarBndr Specificity]
    tvbs, Kind
    sel_ty, Kind
    con_res_ty) = RecSelInfo -> ([TyVarBndr Specificity], Kind, Kind)
    extract_rec_sel_info RecSelInfo
    rec_sel_info
            -- See Note [Use unSigType in maybeReifyCon]
            full_sel_ty :: Kind
    full_sel_ty = Kind -> Kind
    unSigType (Kind -> Kind) -> Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    maybeForallT [TyVarBndr Specificity]
    tvbs [] (Kind -> Kind) -> Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ Cxt -> Kind -> Kind
    mkArrows [Kind
    con_res_ty] Kind
    sel_ty
          -- we don't try to ferret out naughty record selectors.
      = (Name, Info) -> Maybe (Name, Info)
    forall a. a -> Maybe a
    Just (Name
    n', Name -> Kind -> Maybe Dec -> Info
    VarI Name
    n Kind
    full_sel_ty Maybe Dec
    forall a. Maybe a
    Nothing)
      where
        extract_rec_sel_info :: RecSelInfo -> ([TyVarBndrSpec], Type, Type)
          -- Returns ( Selector type variable binders
          --         , Record field type
          --         , constructor result type )
        extract_rec_sel_info :: RecSelInfo -> ([TyVarBndr Specificity], Kind, Kind)
    extract_rec_sel_info RecSelInfo
    rec_sel_info =
          case RecSelInfo
    rec_sel_info of
            RecSelH98 Kind
    sel_ty ->
              ( Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec [TyVarBndrUnit]
    h98_tvbs
              , Kind
    sel_ty
              , Kind
    h98_res_ty
              )
            RecSelGADT Maybe [TyVarBndr Specificity]
    mb_con_tvbs Kind
    sel_ty Kind
    con_res_ty ->
              let -- If the GADT constructor type signature explicitly quantifies
                  -- its type variables, make sure to use that same order in the
                  -- record selector's type.
                  con_tvbs' :: [TyVarBndr Specificity]
    con_tvbs' =
                    case Maybe [TyVarBndr Specificity]
    mb_con_tvbs of
                      Just [TyVarBndr Specificity]
    con_tvbs -> [TyVarBndr Specificity]
    con_tvbs
                      Maybe [TyVarBndr Specificity]
    Nothing ->
                        Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec ([TyVarBndrUnit] -> [TyVarBndr Specificity])
    -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall a b. (a -> b) -> a -> b
    $
                        Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped [Kind
    con_res_ty, Kind
    sel_ty] in
              ( [TyVarBndr Specificity]
    con_tvbs'
              , Kind
    sel_ty
              , Kind
    con_res_ty
              )

        h98_tvbs :: [TyVarBndrUnit]
    h98_tvbs   = Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped (Cxt -> [TyVarBndrUnit]) -> Cxt -> [TyVarBndrUnit]
    forall a b. (a -> b) -> a -> b
    $
                     (TypeArg -> Kind) -> [TypeArg] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map TypeArg -> Kind
    probablyWrongUnTypeArg [TypeArg]
    ty_args
        h98_res_ty :: Kind
    h98_res_ty = Kind -> [TypeArg] -> Kind
    applyType (Name -> Kind
    ConT Name
    ty_name) [TypeArg]
    ty_args

    maybeReifyCon Name
    _ [Dec]
    _ Name
    _ [TypeArg]
    _ [Con]
    _ = Maybe (Name, Info)
    forall a. Maybe a
    Nothing

    #if __GLASGOW_HASKELL__ >= 801
    -- | Attempt to reify the type of a pattern synonym record selector @n@.
    -- The algorithm for computing this type works as follows:
    --
    -- 1. Reify the type of the parent pattern synonym. Broadly speaking, this
    --    will look something like:
    --
    --    @
    --    pattern P :: forall <req_tvbs>. req_cxt =>
    --                 forall <prov_tvbs>. prov_cxt =>
    --                 arg_ty_1 -> ... -> arg_ty_k -> res
    --    @
    --
    -- 2. Check if @P@ is a record pattern synonym. If it isn't a record pattern
    --    synonym, return 'Nothing'. If it is a record pattern synonym, it will
    --    have @k@ record selectors @sel_1@, ..., @sel_k@.
    --
    -- 3. Check if @n@ is equal to some @sel_i@. If it isn't equal to any of them,
    --    return @Nothing@. If it is equal to some @sel_i@, then return 'Just'
    --    @sel_i@ paired with the following type:
    --
    --    @
    --    sel_i :: forall <req_tvbs>. req_cxt => res -> arg_ty_i
    --    @
    maybeReifyPatSynRecSelector ::
      Name -> [Dec] -> Name -> PatSynArgs -> Maybe (Named Type)
    maybeReifyPatSynRecSelector :: Name -> [Dec] -> Name -> PatSynArgs -> Maybe (Named Kind)
    maybeReifyPatSynRecSelector Name
    n [Dec]
    decs Name
    pat_syn_name PatSynArgs
    pat_syn_args =
      case PatSynArgs
    pat_syn_args of
        -- Part (2) in the Haddocks
        RecordPatSyn [Name]
    fld_names
          -> (Named Kind -> Maybe (Named Kind))
    -> [Named Kind] -> Maybe (Named Kind)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Named Kind -> Maybe (Named Kind)
    match_pat_syn_rec_sel ([Named Kind] -> Maybe (Named Kind))
    -> [Named Kind] -> Maybe (Named Kind)
    forall a b. (a -> b) -> a -> b
    $
             [Name] -> Cxt -> [Named Kind]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Name]
    fld_names Cxt
    pat_syn_ty_vis_args
        PatSynArgs
    _ -> Maybe (Named Kind)
    forall a. Maybe a
    Nothing
      where
        -- Part (3) in the Haddocks
        match_pat_syn_rec_sel :: (Name, Type) -> Maybe (Named Type)
        match_pat_syn_rec_sel :: Named Kind -> Maybe (Named Kind)
    match_pat_syn_rec_sel (Name
    n', Kind
    field_ty)
          | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
          = Named Kind -> Maybe (Named Kind)
    forall a. a -> Maybe a
    Just ( Name
    n'
                 , -- See Note [Use unSigType in maybeReifyCon]
                   Kind -> Kind
    unSigType (Kind -> Kind) -> Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $
                   [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    maybeForallT [TyVarBndr Specificity]
    pat_syn_ty_tvbs Cxt
    pat_syn_ty_req_cxt (Kind -> Kind) -> Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $
                   Kind
    ArrowT Kind -> Kind -> Kind
    `AppT` Kind
    pat_syn_ty_res Kind -> Kind -> Kind
    `AppT` Kind
    field_ty
                 )
        match_pat_syn_rec_sel Named Kind
    _
          = Maybe (Named Kind)
    forall a. Maybe a
    Nothing

        -- The type of the pattern synonym to which this record selector belongs,
        -- as described in part (1) in the Haddocks.
        pat_syn_ty :: Type
        pat_syn_ty :: Kind
    pat_syn_ty =
          case Name -> [Dec] -> Maybe Kind
    findPatSynType Name
    pat_syn_name [Dec]
    decs of
            Just Kind
    ty -> Kind
    ty
            Maybe Kind
    Nothing -> Name -> Kind
    no_type Name
    n

        pat_syn_ty_args :: FunArgs
        pat_syn_ty_res :: Type
        (FunArgs
    pat_syn_ty_args, Kind
    pat_syn_ty_res) =
          Kind -> (FunArgs, Kind)
    unravelType Kind
    pat_syn_ty

        -- Decompose a pattern synonym type into the constituent parts described in
        -- part (1) in the Haddocks. The Haddocks present an idealized form of
        -- pattern synonym type signature where the required and provided foralls
        -- and contexts are made explicit. In reality, some of these parts may be
        -- omitted, so we have to be careful to handle every combination of
        -- explicit and implicit parts.
        pat_syn_ty_tvbs :: [TyVarBndrSpec]
        pat_syn_ty_req_cxt :: Cxt
        pat_syn_ty_vis_args :: [Type]
        ([TyVarBndr Specificity]
    pat_syn_ty_tvbs, Cxt
    pat_syn_ty_req_cxt, Cxt
    pat_syn_ty_vis_args) =
          case FunArgs
    pat_syn_ty_args of
            -- Both the required foralls and context are explicit.
            --
            -- The provided foralls and context may be explicit or implicit, but it
            -- doesn't really matter, as the type of a pattern synonym record
            -- selector only cares about the required foralls and context.
            -- Similarly for all cases below this one.
            FAForalls (ForallInvis [TyVarBndr Specificity]
    req_tvbs) (FACxt Cxt
    req_cxt FunArgs
    args) ->
              ( [TyVarBndr Specificity]
    req_tvbs
              , Cxt
    req_cxt
              , (VisFunArg -> Maybe Kind) -> [VisFunArg] -> Cxt
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe VisFunArg -> Maybe Kind
    vis_arg_anon_maybe ([VisFunArg] -> Cxt) -> [VisFunArg] -> Cxt
    forall a b. (a -> b) -> a -> b
    $ FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    args
              )

            -- Only the required foralls are explicit. We can assume that there is
            -- no required context due to the case above not matching.
            FAForalls (ForallInvis [TyVarBndr Specificity]
    req_tvbs) FunArgs
    args ->
              ( [TyVarBndr Specificity]
    req_tvbs
              , []
              , (VisFunArg -> Maybe Kind) -> [VisFunArg] -> Cxt
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe VisFunArg -> Maybe Kind
    vis_arg_anon_maybe ([VisFunArg] -> Cxt) -> [VisFunArg] -> Cxt
    forall a b. (a -> b) -> a -> b
    $ FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    args
              )

            -- The required context is explicit, but the required foralls are
            -- implicit. As a result, the order of type variables in the outer
            -- forall in the type of the pattern synonym is determined by the usual
            -- left-to-right scoped sort.
            --
            -- Note that there may be explicit, provided foralls in this case. For
            -- example, consider this example:
            --
            -- @
            -- data T a where
            --   MkT :: b -> T (Maybe b)
            --
            -- pattern X :: Show a => forall b. (a ~ Maybe b) => b -> T a
            -- pattern X{unX} = MkT unX
            -- @
            --
            -- You might worry that the type of @unX@ would need to mention @b@.
            -- But actually, you can't use @unX@ as a top-level record selector in
            -- the first place! If you try to do so, GHC will throw the following
            -- error:
            --
            -- @
            -- Cannot use record selector `unX' as a function due to escaped type variables
            -- @
            --
            -- As a result, we choose not to care about this corner case. We could
            -- imagine trying to detect this sort of thing here and throwing a
            -- similar error message, but detecting which type variables do or do
            -- not escape is tricky in general. (See the Haddocks for
            -- getRecordSelectors in L.H.TH.Desugar for more on this point.) As a
            -- result, we don't even bother trying. Similarly for the case below.
            FACxt Cxt
    req_cxt FunArgs
    args ->
              ( Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec ([TyVarBndrUnit] -> [TyVarBndr Specificity])
    -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall a b. (a -> b) -> a -> b
    $
                Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped [Kind
    pat_syn_ty]
              , Cxt
    req_cxt
              , (VisFunArg -> Maybe Kind) -> [VisFunArg] -> Cxt
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe VisFunArg -> Maybe Kind
    vis_arg_anon_maybe ([VisFunArg] -> Cxt) -> [VisFunArg] -> Cxt
    forall a b. (a -> b) -> a -> b
    $ FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    args
              )

            -- The required foralls are implicit. We can assume that there is no
            -- required context due to the case above not matching.
            FunArgs
    args ->
              ( Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec ([TyVarBndrUnit] -> [TyVarBndr Specificity])
    -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall a b. (a -> b) -> a -> b
    $
                Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped [Kind
    pat_syn_ty]
              , []
              , (VisFunArg -> Maybe Kind) -> [VisFunArg] -> Cxt
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe VisFunArg -> Maybe Kind
    vis_arg_anon_maybe ([VisFunArg] -> Cxt) -> [VisFunArg] -> Cxt
    forall a b. (a -> b) -> a -> b
    $ FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    args
              )

    vis_arg_anon_maybe :: VisFunArg -> Maybe Type
    vis_arg_anon_maybe :: VisFunArg -> Maybe Kind
    vis_arg_anon_maybe (VisFAAnon Kind
    ty) = Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    ty
    vis_arg_anon_maybe (VisFADep{})   = Maybe Kind
    forall a. Maybe a
    Nothing
    #endif

    {-
    Note [Use unSigType in maybeReifyCon]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Make sure to call unSigType on the type of a reified data constructor or
    record selector. Otherwise, if you have this:

      data D (a :: k) = MkD { unD :: Proxy a }

    Then the type of unD will be reified as:

      unD :: forall k (a :: k). D (a :: k) -> Proxy a

    This is contrast to GHC's own reification, which will produce `D a`
    (without the explicit kind signature) as the type of the first argument.
    -}

    -- Reverse-engineer the type of a data constructor.
    con_to_type :: [TyVarBndrUnit] -- The type variables bound by a data type head.
                                   -- Only used for Haskell98-style constructors.
                -> Type            -- The constructor result type.
                                   -- Only used for Haskell98-style constructors.
                -> Con -> Type
    con_to_type :: [TyVarBndrUnit] -> Kind -> Con -> Kind
    con_to_type [TyVarBndrUnit]
    h98_tvbs Kind
    h98_result_ty Con
    con =
      case Con -> (Bool, Kind)
    go Con
    con of
        (Bool
    is_gadt, Kind
    ty) | Bool
    is_gadt   -> Kind
    ty
                      | Bool
    otherwise -> [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    maybeForallT
                                       (Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec [TyVarBndrUnit]
    h98_tvbs)
                                       [] Kind
    ty
      where
        -- Note that we deliberately ignore linear types and use (->) everywhere.
        -- See [Gracefully handling linear types] in L.H.TH.Desugar.Core.
        go :: Con -> (Bool, Type) -- The Bool is True when dealing with a GADT
        go :: Con -> (Bool, Kind)
    go (NormalC Name
    _ [BangType]
    stys)       = (Bool
    False, Cxt -> Kind -> Kind
    mkArrows ((BangType -> Kind) -> [BangType] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map BangType -> Kind
    forall a b. (a, b) -> b
    snd    [BangType]
    stys)  Kind
    h98_result_ty)
        go (RecC Name
    _ [VarBangType]
    vstys)         = (Bool
    False, Cxt -> Kind -> Kind
    mkArrows ((VarBangType -> Kind) -> [VarBangType] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map VarBangType -> Kind
    forall a b c. (a, b, c) -> c
    thdOf3 [VarBangType]
    vstys) Kind
    h98_result_ty)
        go (InfixC BangType
    t1 Name
    _ BangType
    t2)       = (Bool
    False, Cxt -> Kind -> Kind
    mkArrows ((BangType -> Kind) -> [BangType] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map BangType -> Kind
    forall a b. (a, b) -> b
    snd [BangType
    t1, BangType
    t2]) Kind
    h98_result_ty)
        go (ForallC [TyVarBndr Specificity]
    bndrs Cxt
    cxt Con
    c)  = (Kind -> Kind) -> (Bool, Kind) -> (Bool, Kind)
    forall a b c. (a -> b) -> (c, a) -> (c, b)
    liftSnd ([TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT [TyVarBndr Specificity]
    bndrs Cxt
    cxt) (Con -> (Bool, Kind)
    go Con
    c)
        go (GadtC [Name]
    _ [BangType]
    stys Kind
    rty)     = (Bool
    True, Cxt -> Kind -> Kind
    mkArrows ((BangType -> Kind) -> [BangType] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map BangType -> Kind
    forall a b. (a, b) -> b
    snd    [BangType]
    stys)  Kind
    rty)
        go (RecGadtC [Name]
    _ [VarBangType]
    vstys Kind
    rty) = (Bool
    True, Cxt -> Kind -> Kind
    mkArrows ((VarBangType -> Kind) -> [VarBangType] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map VarBangType -> Kind
    forall a b c. (a, b, c) -> c
    thdOf3 [VarBangType]
    vstys) Kind
    rty)

    mkVarI :: Name -> [Dec] -> Info
    mkVarI :: Name -> [Dec] -> Info
    mkVarI Name
    n [Dec]
    decs = Name -> Kind -> Info
    mkVarITy Name
    n (Kind -> (Named Kind -> Kind) -> Maybe (Named Kind) -> Kind
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (Name -> Kind
    no_type Name
    n) Named Kind -> Kind
    forall a b. (a, b) -> b
    snd (Maybe (Named Kind) -> Kind) -> Maybe (Named Kind) -> Kind
    forall a b. (a -> b) -> a -> b
    $ Name -> [Dec] -> Maybe (Named Kind)
    findType Name
    n [Dec]
    decs)

    mkVarITy :: Name -> Type -> Info
    mkVarITy :: Name -> Kind -> Info
    mkVarITy Name
    n Kind
    ty = Name -> Kind -> Maybe Dec -> Info
    VarI Name
    n Kind
    ty Maybe Dec
    forall a. Maybe a
    Nothing

    findType :: Name -> [Dec] -> Maybe (Named Type)
    findType :: Name -> [Dec] -> Maybe (Named Kind)
    findType Name
    n = (Dec -> Maybe (Named Kind)) -> [Dec] -> Maybe (Named Kind)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Dec -> Maybe (Named Kind)
    match_type
      where
        match_type :: Dec -> Maybe (Named Kind)
    match_type (SigD Name
    n' Kind
    ty) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = Named Kind -> Maybe (Named Kind)
    forall a. a -> Maybe a
    Just (Name
    n', Kind
    ty)
        match_type Dec
    _                                 = Maybe (Named Kind)
    forall a. Maybe a
    Nothing

    #if __GLASGOW_HASKELL__ >= 801
    mkPatSynI :: Name -> [Dec] -> Info
    mkPatSynI :: Name -> [Dec] -> Info
    mkPatSynI Name
    n [Dec]
    decs = Name -> Kind -> Info
    PatSynI Name
    n (Kind -> Maybe Kind -> Kind
    forall a. a -> Maybe a -> a
    fromMaybe (Name -> Kind
    no_type Name
    n) (Maybe Kind -> Kind) -> Maybe Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ Name -> [Dec] -> Maybe Kind
    findPatSynType Name
    n [Dec]
    decs)

    findPatSynType :: Name -> [Dec] -> Maybe PatSynType
    findPatSynType :: Name -> [Dec] -> Maybe Kind
    findPatSynType Name
    n = (Dec -> Maybe Kind) -> [Dec] -> Maybe Kind
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Dec -> Maybe Kind
    match_pat_syn_type
      where
        match_pat_syn_type :: Dec -> Maybe Kind
    match_pat_syn_type (PatSynSigD Name
    n' Kind
    psty) | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    psty
        match_pat_syn_type Dec
    _                                         = Maybe Kind
    forall a. Maybe a
    Nothing
    #endif

    no_type :: Name -> Type
    no_type :: Name -> Kind
    no_type Name
    n = String -> Kind
    forall a. HasCallStack => String -> a
    error (String -> Kind) -> String -> Kind
    forall a b. (a -> b) -> a -> b
    $ String
    "No type information found in local declaration for "
                        String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Name -> String
    forall a. Show a => a -> String
    show Name
    n

    findInstances :: Name -> [Dec] -> [Dec]
    findInstances :: Name -> [Dec] -> [Dec]
    findInstances Name
    n = (Dec -> Dec) -> [Dec] -> [Dec]
    forall a b. (a -> b) -> [a] -> [b]
    map Dec -> Dec
    stripInstanceDec ([Dec] -> [Dec]) -> ([Dec] -> [Dec]) -> [Dec] -> [Dec]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Dec -> [Dec]) -> [Dec] -> [Dec]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Dec -> [Dec]
    match_instance
      where
        match_instance :: Dec -> [Dec]
    match_instance d :: Dec
    d@(InstanceD Maybe Overlap
    _ Cxt
    _ Kind
    ty [Dec]
    _)      | ConT Name
    n' <- Kind -> Kind
    ty_head Kind
    ty
                                                   , Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = [Dec
    d]
    #if __GLASGOW_HASKELL__ >= 807
        match_instance (DataInstD Cxt
    ctxt Maybe [TyVarBndrUnit]
    _ Kind
    lhs Maybe Kind
    mk [Con]
    cons [DerivClause]
    derivs)
                                                      | ConT Name
    n' <- Kind -> Kind
    ty_head Kind
    lhs
                                                      , Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = [Dec
    d]
          where
            mtvbs :: Maybe [TyVarBndrUnit]
    mtvbs = Cxt -> Kind -> Maybe Kind -> Maybe [TyVarBndrUnit]
    rejig_data_inst_tvbs Cxt
    ctxt Kind
    lhs Maybe Kind
    mk
            d :: Dec
    d = Cxt
    -> Maybe [TyVarBndrUnit]
    -> Kind
    -> Maybe Kind
    -> [Con]
    -> [DerivClause]
    -> Dec
    DataInstD Cxt
    ctxt Maybe [TyVarBndrUnit]
    mtvbs Kind
    lhs Maybe Kind
    mk [Con]
    cons [DerivClause]
    derivs
        match_instance (NewtypeInstD Cxt
    ctxt Maybe [TyVarBndrUnit]
    _ Kind
    lhs Maybe Kind
    mk Con
    con [DerivClause]
    derivs)
                                                      | ConT Name
    n' <- Kind -> Kind
    ty_head Kind
    lhs
                                                      , Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = [Dec
    d]
          where
            mtvbs :: Maybe [TyVarBndrUnit]
    mtvbs = Cxt -> Kind -> Maybe Kind -> Maybe [TyVarBndrUnit]
    rejig_data_inst_tvbs Cxt
    ctxt Kind
    lhs Maybe Kind
    mk
            d :: Dec
    d = Cxt
    -> Maybe [TyVarBndrUnit]
    -> Kind
    -> Maybe Kind
    -> Con
    -> [DerivClause]
    -> Dec
    NewtypeInstD Cxt
    ctxt Maybe [TyVarBndrUnit]
    mtvbs Kind
    lhs Maybe Kind
    mk Con
    con [DerivClause]
    derivs
    #else
        match_instance d@(DataInstD _ n' _ _ _ _)    | n `nameMatches` n' = [d]
        match_instance d@(NewtypeInstD _ n' _ _ _ _) | n `nameMatches` n' = [d]
    #endif
    #if __GLASGOW_HASKELL__ >= 807
        match_instance (TySynInstD (TySynEqn Maybe [TyVarBndrUnit]
    _ Kind
    lhs Kind
    rhs))
                                                   | ConT Name
    n' <- Kind -> Kind
    ty_head Kind
    lhs
                                                   , Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = [Dec
    d]
          where
            mtvbs :: Maybe [TyVarBndrUnit]
    mtvbs = Cxt -> Maybe [TyVarBndrUnit]
    rejig_tvbs [Kind
    lhs, Kind
    rhs]
            d :: Dec
    d = TySynEqn -> Dec
    TySynInstD (Maybe [TyVarBndrUnit] -> Kind -> Kind -> TySynEqn
    TySynEqn Maybe [TyVarBndrUnit]
    mtvbs Kind
    lhs Kind
    rhs)
    #else
        match_instance d@(TySynInstD n' _)         | n `nameMatches` n' = [d]
    #endif

        match_instance (InstanceD Maybe Overlap
    _ Cxt
    _ Kind
    _ [Dec]
    decs)
                                            = (Dec -> [Dec]) -> [Dec] -> [Dec]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Dec -> [Dec]
    match_instance [Dec]
    decs
        match_instance Dec
    _                    = []

    #if __GLASGOW_HASKELL__ >= 807
        -- See Note [Rejigging reified type family equations variable binders]
        -- for why this is necessary.
        rejig_tvbs :: [Type] -> Maybe [TyVarBndrUnit]
        rejig_tvbs :: Cxt -> Maybe [TyVarBndrUnit]
    rejig_tvbs Cxt
    ts =
          let tvbs :: [TyVarBndrUnit]
    tvbs = Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped Cxt
    ts
          in if [TyVarBndrUnit] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TyVarBndrUnit]
    tvbs
             then Maybe [TyVarBndrUnit]
    forall a. Maybe a
    Nothing
             else [TyVarBndrUnit] -> Maybe [TyVarBndrUnit]
    forall a. a -> Maybe a
    Just [TyVarBndrUnit]
    tvbs

        rejig_data_inst_tvbs :: Cxt -> Type -> Maybe Kind -> Maybe [TyVarBndrUnit]
        rejig_data_inst_tvbs :: Cxt -> Kind -> Maybe Kind -> Maybe [TyVarBndrUnit]
    rejig_data_inst_tvbs Cxt
    cxt Kind
    lhs Maybe Kind
    mk =
          Cxt -> Maybe [TyVarBndrUnit]
    rejig_tvbs (Cxt -> Maybe [TyVarBndrUnit]) -> Cxt -> Maybe [TyVarBndrUnit]
    forall a b. (a -> b) -> a -> b
    $ Cxt
    cxt Cxt -> Cxt -> Cxt
    forall a. [a] -> [a] -> [a]
    ++ [Kind
    lhs] Cxt -> Cxt -> Cxt
    forall a. [a] -> [a] -> [a]
    ++ Maybe Kind -> Cxt
    forall a. Maybe a -> [a]
    maybeToList Maybe Kind
    mk
    #endif

        ty_head :: Kind -> Kind
    ty_head = (Kind, [TypeArg]) -> Kind
    forall a b. (a, b) -> a
    fst ((Kind, [TypeArg]) -> Kind)
    -> (Kind -> (Kind, [TypeArg])) -> Kind -> Kind
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> (Kind, [TypeArg])
    unfoldType

    {-
    Note [Rejigging reified type family equations variable binders]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    When reifying a type family instance (on GHC 8.8 or later), which quantified
    type variables do you use? This might seem like a strange question to ask since
    these instances already come equipped with a field of type `Maybe [TyVarBndr]`,
    but it's not always the case that you want to use exactly that field. Here is
    an example to better explain it:

      class C a where
        type T b a
      instance C (Maybe a) where
        type forall b. T b (Maybe a) = a

    If the above instance were quoted, it would give you `Just [PlainTV b]`. But if
    you were to reify ''T (and therefore retrieve the instance for T), you wouldn't
    want to use that as your list of type variable binders! This is because
    reifiying any type family always presents the information as though the type
    family were top-level. Therefore, reifying T (in GHC, at least) would yield:

      type family T b a
      type instance forall b a. T b (Maybe a) = a

    Note that we quantify over `b` *and* `a` here, not just `b`. To emulate this
    GHC quirk, whenever we reify any type family instance, we just ignore the field
    of type `Maybe [TyVarBndr]` and quantify over the instance afresh. It's a bit
    tedious, but it gets the job done. (This is accomplished by the rejig_tvbs
    function.)
    -}

    -- Consider the following class declaration:
    --
    --   [d| class C a where
    --         method :: a -> b -> a |]
    --
    -- When reifying C locally, quantifyClassDecMethods serves two purposes:
    --
    -- 1. It quantifies the class method's local type variables. To illustrate this
    --    point, this is how GHC would reify C:
    --
    --      class C a where
    --        method :: forall b. a -> b -> a
    --
    --    Notice the presence of the explicit `forall b.`. quantifyClassDecMethods
    --    performs this explicit quantification if necessary (as in the case in the
    --    local C declaration, where `b` is implicitly quantified.)
    -- 2. It emulates a quirk in the way old versions of GHC would reify class
    --    declarations (Trac #15551). On versions of GHC older than 8.8, it would
    --    reify C like so:
    --
    --      class C a where
    --        method :: forall a. C a => forall b. a -> b -> a
    --
    --    Notice how GHC has added the (totally extraneous) `forall a. C a =>`
    --    part! This is weird, but our primary goal in this module is to mimic
    --    GHC's reification, so we play the part by adding the `forall`/class
    --    context to each class method in quantifyClassDecMethods.
    --
    --    Since Trac #15551 was fixed in GHC 8.8, this function doesn't perform
    --    this step on 8.7 or later.
    quantifyClassDecMethods :: Dec -> Dec
    quantifyClassDecMethods :: Dec -> Dec
    quantifyClassDecMethods (ClassD Cxt
    cxt Name
    cls_name [TyVarBndrVis]
    cls_tvbs [FunDep]
    fds [Dec]
    sub_decs)
      = Cxt -> Name -> [TyVarBndrVis] -> [FunDep] -> [Dec] -> Dec
    ClassD Cxt
    cxt Name
    cls_name [TyVarBndrVis]
    cls_tvbs [FunDep]
    fds [Dec]
    sub_decs'
      where
        sub_decs' :: [Dec]
    sub_decs' = (Dec -> Maybe Dec) -> [Dec] -> [Dec]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe Dec -> Maybe Dec
    go [Dec]
    sub_decs
        go :: Dec -> Maybe Dec
    go (SigD Name
    n Kind
    ty) =
          Dec -> Maybe Dec
    forall a. a -> Maybe a
    Just (Dec -> Maybe Dec) -> Dec -> Maybe Dec
    forall a b. (a -> b) -> a -> b
    $ Name -> Kind -> Dec
    SigD Name
    n
               (Kind -> Dec) -> Kind -> Dec
    forall a b. (a -> b) -> a -> b
    $ Name -> [TyVarBndrVis] -> Bool -> Kind -> Kind
    quantifyClassMethodType Name
    cls_name [TyVarBndrVis]
    cls_tvbs Bool
    prepend_cls Kind
    ty
        go d :: Dec
    d@(TySynInstD {})      = Dec -> Maybe Dec
    forall a. a -> Maybe a
    Just Dec
    d
        go d :: Dec
    d@(OpenTypeFamilyD {}) = Dec -> Maybe Dec
    forall a. a -> Maybe a
    Just Dec
    d
        go d :: Dec
    d@(DataFamilyD {})     = Dec -> Maybe Dec
    forall a. a -> Maybe a
    Just Dec
    d
        go Dec
    _           = Maybe Dec
    forall a. Maybe a
    Nothing

        -- See (2) in the comments for quantifyClassDecMethods.
        prepend_cls :: Bool
    #if __GLASGOW_HASKELL__ >= 807
        prepend_cls :: Bool
    prepend_cls = Bool
    False
    #else
        prepend_cls = True
    #endif
    quantifyClassDecMethods Dec
    dec = Dec
    dec

    -- Add explicit quantification to a class method's type if necessary. In this
    -- example:
    --
    --   [d| class C a where
    --         method :: a -> b -> a |]
    --
    -- If one invokes `quantifyClassMethodType C [a] prepend (a -> b -> a)`, then
    -- the output will be:
    --
    -- 1. `forall a. C a => forall b. a -> b -> a` (if `prepend` is True)
    -- 2.                  `forall b. a -> b -> a` (if `prepend` is False)
    --
    -- Whether you want `prepend` to be True or False depends on the situation.
    -- When reifying an entire type class, like C, one does not need to prepend a
    -- class context to each of the bundled method types (see the comments for
    -- quantifyClassDecMethods), so False is appropriate. When one is only reifying
    -- a single class method, like `method`, then one needs the class context to
    -- appear in the reified type, so `True` is appropriate.
    quantifyClassMethodType
      :: Name           -- ^ The class name.
      -> [TyVarBndrVis] -- ^ The class's type variable binders.
      -> Bool           -- ^ If 'True', prepend a class predicate.
      -> Type           -- ^ The method type.
      -> Type
    quantifyClassMethodType :: Name -> [TyVarBndrVis] -> Bool -> Kind -> Kind
    quantifyClassMethodType Name
    cls_name [TyVarBndrVis]
    cls_tvbs Bool
    prepend Kind
    meth_ty =
      Kind -> Kind
    add_cls_cxt Kind
    quantified_meth_ty
      where
        add_cls_cxt :: Type -> Type
        add_cls_cxt :: Kind -> Kind
    add_cls_cxt
          | Bool
    prepend   = [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT (Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec [TyVarBndrUnit]
    all_cls_tvbs) Cxt
    cls_cxt
          | Bool
    otherwise = Kind -> Kind
    forall a. a -> a
    id

        cls_cxt :: Cxt
        cls_cxt :: Cxt
    cls_cxt = [Kind -> [TypeArg] -> Kind
    applyType (Name -> Kind
    ConT Name
    cls_name) ((TyVarBndrVis -> TypeArg) -> [TyVarBndrVis] -> [TypeArg]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TypeArg
    tyVarBndrVisToTypeArg [TyVarBndrVis]
    cls_tvbs)]

        quantified_meth_ty :: Type
        quantified_meth_ty :: Kind
    quantified_meth_ty
          | [TyVarBndr Specificity] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TyVarBndr Specificity]
    meth_tvbs
          = Kind
    meth_ty
          | ForallT [TyVarBndr Specificity]
    meth_tvbs' Cxt
    meth_ctxt Kind
    meth_tau <- Kind
    meth_ty
          = [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT ([TyVarBndr Specificity]
    meth_tvbs [TyVarBndr Specificity]
    -> [TyVarBndr Specificity] -> [TyVarBndr Specificity]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndr Specificity]
    meth_tvbs') Cxt
    meth_ctxt Kind
    meth_tau
          | Bool
    otherwise
          = [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT [TyVarBndr Specificity]
    meth_tvbs [] Kind
    meth_ty

        meth_tvbs :: [TyVarBndrSpec]
        meth_tvbs :: [TyVarBndr Specificity]
    meth_tvbs = Specificity -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec ([TyVarBndrUnit] -> [TyVarBndr Specificity])
    -> [TyVarBndrUnit] -> [TyVarBndr Specificity]
    forall a b. (a -> b) -> a -> b
    $
                    (TyVarBndrUnit -> TyVarBndrUnit -> Bool)
    -> [TyVarBndrUnit] -> [TyVarBndrUnit] -> [TyVarBndrUnit]
    forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
    List.deleteFirstsBy (Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) (Name -> Name -> Bool)
    -> (TyVarBndrUnit -> Name)
    -> TyVarBndrUnit
    -> TyVarBndrUnit
    -> Bool
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` TyVarBndrUnit -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName)
                      (Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped [Kind
    meth_ty]) [TyVarBndrUnit]
    all_cls_tvbs

        -- Explicitly quantify any kind variables bound by the class, if any.
        all_cls_tvbs :: [TyVarBndrUnit]
        all_cls_tvbs :: [TyVarBndrUnit]
    all_cls_tvbs = Cxt -> [TyVarBndrUnit]
    freeVariablesWellScoped (Cxt -> [TyVarBndrUnit]) -> Cxt -> [TyVarBndrUnit]
    forall a b. (a -> b) -> a -> b
    $ (TyVarBndrVis -> Kind) -> [TyVarBndrVis] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> Kind
    forall flag. TyVarBndr_ flag -> Kind
    tvbToTypeWithSig [TyVarBndrVis]
    cls_tvbs

    stripInstanceDec :: Dec -> Dec
    stripInstanceDec :: Dec -> Dec
    stripInstanceDec (InstanceD Maybe Overlap
    over Cxt
    cxt Kind
    ty [Dec]
    _) = Maybe Overlap -> Cxt -> Kind -> [Dec] -> Dec
    InstanceD Maybe Overlap
    over Cxt
    cxt Kind
    ty []
    stripInstanceDec Dec
    dec                       = Dec
    dec

    mkArrows :: [Type] -> Type -> Type
    mkArrows :: Cxt -> Kind -> Kind
    mkArrows []     Kind
    res_ty = Kind
    res_ty
    mkArrows (Kind
    t:Cxt
    ts) Kind
    res_ty = Kind -> Kind -> Kind
    AppT (Kind -> Kind -> Kind
    AppT Kind
    ArrowT Kind
    t) (Kind -> Kind) -> Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ Cxt -> Kind -> Kind
    mkArrows Cxt
    ts Kind
    res_ty

    maybeForallT :: [TyVarBndrSpec] -> Cxt -> Type -> Type
    maybeForallT :: [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    maybeForallT [TyVarBndr Specificity]
    tvbs Cxt
    cxt Kind
    ty
      | [TyVarBndr Specificity] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [TyVarBndr Specificity]
    tvbs Bool -> Bool -> Bool
    && Cxt -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Cxt
    cxt        = Kind
    ty
      | ForallT [TyVarBndr Specificity]
    tvbs2 Cxt
    cxt2 Kind
    ty2 <- Kind
    ty = [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT ([TyVarBndr Specificity]
    tvbs [TyVarBndr Specificity]
    -> [TyVarBndr Specificity] -> [TyVarBndr Specificity]
    forall a. [a] -> [a] -> [a]
    ++ [TyVarBndr Specificity]
    tvbs2) (Cxt
    cxt Cxt -> Cxt -> Cxt
    forall a. [a] -> [a] -> [a]
    ++ Cxt
    cxt2) Kind
    ty2
      | Bool
    otherwise                    = [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT [TyVarBndr Specificity]
    tvbs Cxt
    cxt Kind
    ty

    findCon :: Name -> [Con] -> Maybe (Named Con)
    findCon :: Name -> [Con] -> Maybe (Named Con)
    findCon Name
    n = (Con -> Maybe (Named Con)) -> [Con] -> Maybe (Named Con)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch Con -> Maybe (Named Con)
    match_con
      where
        match_con :: Con -> Maybe (Named Con)
        match_con :: Con -> Maybe (Named Con)
    match_con Con
    con =
          case Con
    con of
            NormalC Name
    n' [BangType]
    _  | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' -> Named Con -> Maybe (Named Con)
    forall a. a -> Maybe a
    Just (Name
    n', Con
    con)
            RecC Name
    n' [VarBangType]
    _     | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' -> Named Con -> Maybe (Named Con)
    forall a. a -> Maybe a
    Just (Name
    n', Con
    con)
            InfixC BangType
    _ Name
    n' BangType
    _ | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' -> Named Con -> Maybe (Named Con)
    forall a. a -> Maybe a
    Just (Name
    n', Con
    con)
            ForallC [TyVarBndr Specificity]
    _ Cxt
    _ Con
    c -> case Con -> Maybe (Named Con)
    match_con Con
    c of
                               Just (Name
    n', Con
    _) -> Named Con -> Maybe (Named Con)
    forall a. a -> Maybe a
    Just (Name
    n', Con
    con)
                               Maybe (Named Con)
    Nothing      -> Maybe (Named Con)
    forall a. Maybe a
    Nothing
            GadtC [Name]
    nms [BangType]
    _ Kind
    _    -> Con -> [Name] -> Maybe (Named Con)
    gadt_case Con
    con [Name]
    nms
            RecGadtC [Name]
    nms [VarBangType]
    _ Kind
    _ -> Con -> [Name] -> Maybe (Named Con)
    gadt_case Con
    con [Name]
    nms
            Con
    _                -> Maybe (Named Con)
    forall a. Maybe a
    Nothing

        gadt_case :: Con -> [Name] -> Maybe (Named Con)
        gadt_case :: Con -> [Name] -> Maybe (Named Con)
    gadt_case Con
    con [Name]
    nms = case (Name -> Bool) -> [Name] -> Maybe Name
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    List.find (Name
    n Name -> Name -> Bool
    `nameMatches`) [Name]
    nms of
                              Just Name
    n' -> Named Con -> Maybe (Named Con)
    forall a. a -> Maybe a
    Just (Name
    n', Con
    con)
                              Maybe Name
    Nothing -> Maybe (Named Con)
    forall a. Maybe a
    Nothing

    data RecSelInfo
      = RecSelH98  Type -- The record field's type
      | RecSelGADT (Maybe [TyVarBndrSpec])
                        -- If the data constructor explicitly quantifies its type
                        -- variables with a forall, this will be Just. Otherwise,
                        -- this will be Nothing.
                   Type -- The record field's type
                   Type -- The GADT return type

    findRecSelector :: Name -> [Con] -> Maybe (Named RecSelInfo)
    findRecSelector :: Name -> [Con] -> Maybe (Named RecSelInfo)
    findRecSelector Name
    n = (Con -> Maybe (Named RecSelInfo))
    -> [Con] -> Maybe (Named RecSelInfo)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Maybe [TyVarBndr Specificity] -> Con -> Maybe (Named RecSelInfo)
    match_con Maybe [TyVarBndr Specificity]
    forall a. Maybe a
    Nothing)
      where
        match_con :: Maybe [TyVarBndrSpec] -> Con -> Maybe (Named RecSelInfo)
        match_con :: Maybe [TyVarBndr Specificity] -> Con -> Maybe (Named RecSelInfo)
    match_con Maybe [TyVarBndr Specificity]
    mb_tvbs Con
    con =
          case Con
    con of
            RecC Name
    _ [VarBangType]
    vstys ->
              (Named Kind -> Named RecSelInfo)
    -> Maybe (Named Kind) -> Maybe (Named RecSelInfo)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((Kind -> RecSelInfo) -> Named Kind -> Named RecSelInfo
    forall a b c. (a -> b) -> (c, a) -> (c, b)
    liftSnd Kind -> RecSelInfo
    RecSelH98) (Maybe (Named Kind) -> Maybe (Named RecSelInfo))
    -> Maybe (Named Kind) -> Maybe (Named RecSelInfo)
    forall a b. (a -> b) -> a -> b
    $
              (VarBangType -> Maybe (Named Kind))
    -> [VarBangType] -> Maybe (Named Kind)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch VarBangType -> Maybe (Named Kind)
    forall {b} {b}. (Name, b, b) -> Maybe (Name, b)
    match_rec_sel [VarBangType]
    vstys
            RecGadtC [Name]
    _ [VarBangType]
    vstys Kind
    ret_ty ->
              (Named Kind -> Named RecSelInfo)
    -> Maybe (Named Kind) -> Maybe (Named RecSelInfo)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((Kind -> RecSelInfo) -> Named Kind -> Named RecSelInfo
    forall a b c. (a -> b) -> (c, a) -> (c, b)
    liftSnd (\Kind
    field_ty ->
                Maybe [TyVarBndr Specificity] -> Kind -> Kind -> RecSelInfo
    RecSelGADT (([TyVarBndr Specificity] -> [TyVarBndr Specificity])
    -> Maybe [TyVarBndr Specificity] -> Maybe [TyVarBndr Specificity]
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Kind -> [TyVarBndr Specificity] -> [TyVarBndr Specificity]
    filter_ret_tvs Kind
    ret_ty) Maybe [TyVarBndr Specificity]
    mb_tvbs) Kind
    field_ty Kind
    ret_ty)) (Maybe (Named Kind) -> Maybe (Named RecSelInfo))
    -> Maybe (Named Kind) -> Maybe (Named RecSelInfo)
    forall a b. (a -> b) -> a -> b
    $
              (VarBangType -> Maybe (Named Kind))
    -> [VarBangType] -> Maybe (Named Kind)
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch VarBangType -> Maybe (Named Kind)
    forall {b} {b}. (Name, b, b) -> Maybe (Name, b)
    match_rec_sel [VarBangType]
    vstys
            ForallC [TyVarBndr Specificity]
    tvbs Cxt
    _ Con
    c ->
              -- This is the only recursive case, and it is also the place where
              -- the type variable binders are determined (hence the use of Just
              -- below). Note that GHC forbids nested foralls in GADT constructor
              -- type signatures, so it is guaranteed that if a type variable in
              -- the rest of the type signature appears free, then its binding site
              -- can be found in one of these binders found in this case.
              Maybe [TyVarBndr Specificity] -> Con -> Maybe (Named RecSelInfo)
    match_con ([TyVarBndr Specificity] -> Maybe [TyVarBndr Specificity]
    forall a. a -> Maybe a
    Just [TyVarBndr Specificity]
    tvbs) Con
    c
            Con
    _ -> Maybe (Named RecSelInfo)
    forall a. Maybe a
    Nothing

        match_rec_sel :: (Name, b, b) -> Maybe (Name, b)
    match_rec_sel (Name
    n', b
    _, b
    sel_ty)
          | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = (Name, b) -> Maybe (Name, b)
    forall a. a -> Maybe a
    Just (Name
    n', b
    sel_ty)
        match_rec_sel (Name, b, b)
    _        = Maybe (Name, b)
    forall a. Maybe a
    Nothing

        -- There may be type variables in the type of a GADT constructor that do
        -- not appear in the type of a record selector. For example, consider:
        --
        --   data G a where
        --     MkG :: forall a b. { x :: a, y :: b } -> G a
        --
        -- The type of `x` will only quantify `a` and not `b`:
        --
        --   x :: forall a. G a -> a
        --
        -- Accordingly, we must filter out any type variables in the GADT
        -- constructor type that do not appear free in the return type. Note that
        -- this implies that we cannot support reifying the type of `y`, as `b`
        -- does not appear free in `G a`. This does not bother us, however, as we
        -- make no attempt to support naughty record selectors. (See the Haddocks
        -- for getRecordSelectors in L.H.TH.Desugar for more on this point.)
        --
        -- This mirrors the implementation of mkOneRecordSelector in GHC:
        -- https://gitlab.haskell.org/ghc/ghc/-/blob/37cfe3c0f4fb16189bbe3bb735f758cd6e3d9157/compiler/GHC/Tc/TyCl/Utils.hs#L908-909
        filter_ret_tvs :: Type -> [TyVarBndrSpec] -> [TyVarBndrSpec]
        filter_ret_tvs :: Kind -> [TyVarBndr Specificity] -> [TyVarBndr Specificity]
    filter_ret_tvs Kind
    ret_ty =
          (TyVarBndr Specificity -> Bool)
    -> [TyVarBndr Specificity] -> [TyVarBndr Specificity]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\TyVarBndr Specificity
    tvb -> TyVarBndr Specificity -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndr Specificity
    tvb Name -> Set Name -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Name
    ret_fvs)
          where
            ret_fvs :: Set Name
    ret_fvs = [Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList ([Name] -> Set Name) -> [Name] -> Set Name
    forall a b. (a -> b) -> a -> b
    $ Cxt -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables [Kind
    ret_ty]

    ---------------------------------
    -- Reifying fixities
    ---------------------------------

    -- | Like 'reifyWithLocals_maybe', but for fixities. Note that a return value
    -- of @Nothing@ might mean that the name is not in scope, or it might mean
    -- that the name has no assigned fixity. (Use 'reifyWithLocals_maybe' if
    -- you really need to tell the difference.)
    reifyFixityWithLocals :: DsMonad q => Name -> q (Maybe Fixity)
    reifyFixityWithLocals :: forall (q :: * -> *). DsMonad q => Name -> q (Maybe Fixity)
    reifyFixityWithLocals Name
    name = q (Maybe Fixity) -> q (Maybe Fixity) -> q (Maybe Fixity)
    forall a. q a -> q a -> q a
    forall (m :: * -> *) a. Quasi m => m a -> m a -> m a
    qRecover
      (Maybe Fixity -> q (Maybe Fixity)
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe Fixity -> q (Maybe Fixity))
    -> ([Dec] -> Maybe Fixity) -> [Dec] -> q (Maybe Fixity)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> [Dec] -> Maybe Fixity
    reifyFixityInDecs Name
    name ([Dec] -> q (Maybe Fixity)) -> q [Dec] -> q (Maybe Fixity)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< q [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations)
      (Name -> q (Maybe Fixity)
    forall (m :: * -> *). Quasi m => Name -> m (Maybe Fixity)
    qReifyFixity Name
    name)

    --------------------------------------
    -- Reifying types
    --------------------------------------
    --
    -- This section allows GHC <8.9 to call reifyFixity

    #if __GLASGOW_HASKELL__ < 809
    qReifyType :: forall m. Quasi m => Name -> m Type
    qReifyType name = do
      info <- qReify name
      case infoType info <|> info_kind info of
        Just t  -> return t
        Nothing -> fail $ "Could not reify the full type of " ++ nameBase name
      where
        info_kind :: Info -> Maybe Kind
        info_kind info = do
          dec <- case info of
                   ClassI d _  -> Just d
                   TyConI d    -> Just d
                   FamilyI d _ -> Just d
                   _           -> Nothing
          match_cusk name dec

    {- | @reifyType nm@ attempts to find the type or kind of @nm@. For example,
    @reifyType 'not@   returns @Bool -> Bool@, and
    @reifyType ''Bool@ returns @Type@.
    This works even if there's no explicit signature and the type or kind is inferred.
    -}
    reifyType :: Name -> Q Type
    reifyType = qReifyType
    #endif

    -- | Like 'reifyTypeWithLocals_maybe', but throws an exception upon failure,
    -- warning the user about separating splices.
    reifyTypeWithLocals :: DsMonad q => Name -> q Type
    reifyTypeWithLocals :: forall (q :: * -> *). DsMonad q => Name -> q Kind
    reifyTypeWithLocals Name
    name = do
      m_info <- Name -> q (Maybe Kind)
    forall (q :: * -> *). DsMonad q => Name -> q (Maybe Kind)
    reifyTypeWithLocals_maybe Name
    name
      case m_info of
        Maybe Kind
    Nothing -> Name -> q Kind
    forall (m :: * -> *) a. MonadFail m => Name -> m a
    reifyFail Name
    name
        Just Kind
    i  -> Kind -> q Kind
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Kind
    i

    -- | Like 'reifyWithLocals_maybe' but for types and kinds. Note that a return
    -- value of @Nothing@ might mean that the name is not in scope, or it might
    -- mean that the full type of the name cannot be determined. (Use
    -- 'reifyWithLocals_maybe' if you really need to tell the difference.)
    reifyTypeWithLocals_maybe :: DsMonad q => Name -> q (Maybe Type)
    reifyTypeWithLocals_maybe :: forall (q :: * -> *). DsMonad q => Name -> q (Maybe Kind)
    reifyTypeWithLocals_maybe Name
    name = do
    #if __GLASGOW_HASKELL__ >= 809
      cusks <- Extension -> q Bool
    forall (m :: * -> *). Quasi m => Extension -> m Bool
    qIsExtEnabled Extension
    CUSKs
    #else
      -- On earlier GHCs, the behavior of -XCUSKs was the norm.
      let cusks = True
    #endif
      qRecover (return . reifyTypeInDecs cusks name =<< localDeclarations)
               (Just `fmap` qReifyType name)

    -- | Look through a list of declarations and return its full type, if
    -- available.
    reifyTypeInDecs :: Bool -> Name -> [Dec] -> Maybe Type
    reifyTypeInDecs :: Bool -> Name -> [Dec] -> Maybe Kind
    reifyTypeInDecs Bool
    cusks Name
    name [Dec]
    decs =
      (Name -> [Dec] -> Maybe Info
    reifyInDecs Name
    name [Dec]
    decs Maybe Info -> (Info -> Maybe Kind) -> Maybe Kind
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Info -> Maybe Kind
    infoType) Maybe Kind -> Maybe Kind -> Maybe Kind
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Bool -> Name -> [Dec] -> Maybe Kind
    findKind Bool
    cusks Name
    name [Dec]
    decs

    -- Extract the type information (if any) contained in an Info.
    infoType :: Info -> Maybe Type
    infoType :: Info -> Maybe Kind
    infoType Info
    info =
      case Info
    info of
        ClassOpI Name
    _ Kind
    t Name
    _ -> Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    t
        DataConI Name
    _ Kind
    t Name
    _ -> Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    t
        VarI Name
    _ Kind
    t Maybe Dec
    _     -> Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    t
        TyVarI Name
    _ Kind
    t     -> Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    t
    #if __GLASGOW_HASKELL__ >= 802
        PatSynI Name
    _ Kind
    t    -> Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    t
    #endif
        Info
    _              -> Maybe Kind
    forall a. Maybe a
    Nothing

    -- Like findType, but instead searching for kind signatures.
    -- This mostly searches through `KiSigD`s, but if the -XCUSKs extension is
    -- enabled, this also retrieves kinds for declarations with CUSKs.
    findKind :: Bool -- Is -XCUSKs enabled?
             -> Name -> [Dec] -> Maybe Kind
    findKind :: Bool -> Name -> [Dec] -> Maybe Kind
    findKind Bool
    cusks Name
    name [Dec]
    decls =
          (Dec -> Maybe Kind) -> [Dec] -> Maybe Kind
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> [Dec] -> Dec -> Maybe Kind
    match_kind_sig Name
    name [Dec]
    decls) [Dec]
    decls
      Maybe Kind -> Maybe Kind -> Maybe Kind
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Bool -> Maybe Kind -> Maybe Kind
    forall (f :: * -> *) a. Alternative f => Bool -> f a -> f a
    whenAlt Bool
    cusks ((Dec -> Maybe Kind) -> [Dec] -> Maybe Kind
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> Dec -> Maybe Kind
    match_cusk Name
    name) [Dec]
    decls)

    -- Look for a declaration's kind by searching for its standalone kind
    -- signature, if available.
    match_kind_sig :: Name -> [Dec] -> Dec -> Maybe Kind
    match_kind_sig :: Name -> [Dec] -> Dec -> Maybe Kind
    match_kind_sig Name
    n [Dec]
    decs (ClassD Cxt
    _ Name
    n' [TyVarBndrVis]
    tvbs [FunDep]
    _ [Dec]
    sub_decs)
      -- If a class has a standalone kind signature, then we can determine the
      -- full kind of its associated types in 99% of cases.
      -- See Note [The limitations of standalone kind signatures] for what
      -- happens in the other 1% of cases.
      | Just Kind
    ki <- (Dec -> Maybe Kind) -> [Dec] -> Maybe Kind
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> Dec -> Maybe Kind
    find_kind_sig Name
    n') [Dec]
    decs
      , let (FunArgs
    arg_kis, Kind
    _res_ki) = Kind -> (FunArgs, Kind)
    unravelType Kind
    ki
            mb_vis_arg_kis :: [Maybe Kind]
    mb_vis_arg_kis     = (VisFunArg -> Maybe Kind) -> [VisFunArg] -> [Maybe Kind]
    forall a b. (a -> b) -> [a] -> [b]
    map VisFunArg -> Maybe Kind
    vis_arg_kind_maybe ([VisFunArg] -> [Maybe Kind]) -> [VisFunArg] -> [Maybe Kind]
    forall a b. (a -> b) -> a -> b
    $ FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    arg_kis
            cls_tvb_kind_map :: Map Name Kind
    cls_tvb_kind_map   =
              [Named Kind] -> Map Name Kind
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [ (TyVarBndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndrVis
    tvb, Kind
    tvb_kind)
                           | (TyVarBndrVis
    tvb, Maybe Kind
    mb_vis_arg_ki) <- [TyVarBndrVis] -> [Maybe Kind] -> [(TyVarBndrVis, Maybe Kind)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [TyVarBndrVis]
    tvbs [Maybe Kind]
    mb_vis_arg_kis
                           , Just Kind
    tvb_kind <- [Maybe Kind
    mb_vis_arg_ki Maybe Kind -> Maybe Kind -> Maybe Kind
    forall a. Maybe a -> Maybe a -> Maybe a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> TyVarBndrVis -> Maybe Kind
    forall flag. TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe TyVarBndrVis
    tvb]
                           ]
      = (Dec -> Maybe Kind) -> [Dec] -> Maybe Kind
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> Map Name Kind -> Dec -> Maybe Kind
    find_assoc_type_kind Name
    n Map Name Kind
    cls_tvb_kind_map) [Dec]
    sub_decs
    match_kind_sig Name
    n [Dec]
    _ Dec
    dec = Name -> Dec -> Maybe Kind
    find_kind_sig Name
    n Dec
    dec

    find_kind_sig :: Name -> Dec -> Maybe Kind
    #if __GLASGOW_HASKELL__ >= 809
    find_kind_sig :: Name -> Dec -> Maybe Kind
    find_kind_sig Name
    n (KiSigD Name
    n' Kind
    ki)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n' = Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    ki
    #endif
    find_kind_sig Name
    _ Dec
    _ = Maybe Kind
    forall a. Maybe a
    Nothing

    -- Compute a declaration's kind by retrieving its CUSK, if it has one.
    -- This is only done when -XCUSKs is enabled, or on older GHCs where
    -- CUSKs were the only means of specifying this information.
    match_cusk :: Name -> Dec -> Maybe Kind
    match_cusk :: Name -> Dec -> Maybe Kind
    match_cusk Name
    n (DataD Cxt
    _ Name
    n' [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki [Con]
    _ [DerivClause]
    _)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    datatype_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki
    match_cusk Name
    n (NewtypeD Cxt
    _ Name
    n' [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki Con
    _ [DerivClause]
    _)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    datatype_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki
    match_cusk Name
    n (DataFamilyD Name
    n' [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    open_ty_fam_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki
    match_cusk Name
    n (OpenTypeFamilyD (TypeFamilyHead Name
    n' [TyVarBndrVis]
    tvbs FamilyResultSig
    res_sig Maybe InjectivityAnn
    _))
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    open_ty_fam_kind [TyVarBndrVis]
    tvbs (FamilyResultSig -> Maybe Kind
    res_sig_to_kind FamilyResultSig
    res_sig)
    match_cusk Name
    n (ClosedTypeFamilyD (TypeFamilyHead Name
    n' [TyVarBndrVis]
    tvbs FamilyResultSig
    res_sig Maybe InjectivityAnn
    _) [TySynEqn]
    _)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    closed_ty_fam_kind [TyVarBndrVis]
    tvbs (FamilyResultSig -> Maybe Kind
    res_sig_to_kind FamilyResultSig
    res_sig)
    match_cusk Name
    n (TySynD Name
    n' [TyVarBndrVis]
    tvbs Kind
    rhs)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Kind -> Maybe Kind
    ty_syn_kind [TyVarBndrVis]
    tvbs Kind
    rhs
    match_cusk Name
    n (ClassD Cxt
    _ Name
    n' [TyVarBndrVis]
    tvbs [FunDep]
    _ [Dec]
    sub_decs)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind
    class_kind [TyVarBndrVis]
    tvbs
      | -- An associated type family can only have a CUSK if its parent class
        -- also has a CUSK.
        (TyVarBndrVis -> Bool) -> [TyVarBndrVis] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all TyVarBndrVis -> Bool
    forall flag. TyVarBndr_ flag -> Bool
    tvb_is_kinded [TyVarBndrVis]
    tvbs
      , let cls_tvb_kind_map :: Map Name Kind
    cls_tvb_kind_map = [Named Kind] -> Map Name Kind
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [ (TyVarBndrVis -> Name
    forall flag. TyVarBndr_ flag -> Name
    tvName TyVarBndrVis
    tvb, Kind
    tvb_kind)
                                            | TyVarBndrVis
    tvb <- [TyVarBndrVis]
    tvbs
                                            , Just Kind
    tvb_kind <- [TyVarBndrVis -> Maybe Kind
    forall flag. TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe TyVarBndrVis
    tvb]
                                            ]
      = (Dec -> Maybe Kind) -> [Dec] -> Maybe Kind
    forall a b. (a -> Maybe b) -> [a] -> Maybe b
    firstMatch (Name -> Map Name Kind -> Dec -> Maybe Kind
    find_assoc_type_kind Name
    n Map Name Kind
    cls_tvb_kind_map) [Dec]
    sub_decs
    #if __GLASGOW_HASKELL__ >= 906
    match_cusk Name
    n (TypeDataD Name
    n' [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki [Con]
    _)
      | Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
      = [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    datatype_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki
    #endif
    match_cusk Name
    _ Dec
    _ = Maybe Kind
    forall a. Maybe a
    Nothing

    -- Uncover the kind of an associated type family. There is an invariant
    -- that this function should only ever be called when the kind of the
    -- parent class is known (i.e., if it has a standalone kind signature or a
    -- CUSK). Despite this, it is possible for this function to return Nothing.
    -- See Note [The limitations of standalone kind signatures].
    find_assoc_type_kind :: Name -> Map Name Kind -> Dec -> Maybe Kind
    find_assoc_type_kind :: Name -> Map Name Kind -> Dec -> Maybe Kind
    find_assoc_type_kind Name
    n Map Name Kind
    cls_tvb_kind_map Dec
    sub_dec =
      case Dec
    sub_dec of
        DataFamilyD Name
    n' [TyVarBndrVis]
    tf_tvbs Maybe Kind
    m_ki
          |  Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
          -> [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind ((TyVarBndrVis -> TyVarBndrVis) -> [TyVarBndrVis] -> [TyVarBndrVis]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TyVarBndrVis
    ascribe_tf_tvb_kind [TyVarBndrVis]
    tf_tvbs) (Maybe Kind -> Kind
    default_res_ki Maybe Kind
    m_ki)
        OpenTypeFamilyD (TypeFamilyHead Name
    n' [TyVarBndrVis]
    tf_tvbs FamilyResultSig
    res_sig Maybe InjectivityAnn
    _)
          |  Name
    n Name -> Name -> Bool
    `nameMatches` Name
    n'
          -> [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind ((TyVarBndrVis -> TyVarBndrVis) -> [TyVarBndrVis] -> [TyVarBndrVis]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TyVarBndrVis
    ascribe_tf_tvb_kind [TyVarBndrVis]
    tf_tvbs)
                        (Maybe Kind -> Kind
    default_res_ki (Maybe Kind -> Kind) -> Maybe Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ FamilyResultSig -> Maybe Kind
    res_sig_to_kind FamilyResultSig
    res_sig)
        Dec
    _ -> Maybe Kind
    forall a. Maybe a
    Nothing
      where
        ascribe_tf_tvb_kind :: TyVarBndrVis -> TyVarBndrVis
        ascribe_tf_tvb_kind :: TyVarBndrVis -> TyVarBndrVis
    ascribe_tf_tvb_kind TyVarBndrVis
    tvb =
          (Name -> BndrVis -> TyVarBndrVis)
    -> (Name -> BndrVis -> Kind -> TyVarBndrVis)
    -> TyVarBndrVis
    -> TyVarBndrVis
    forall flag r.
    (Name -> flag -> r)
    -> (Name -> flag -> Kind -> r) -> TyVarBndr_ flag -> r
    elimTVFlag
            (\Name
    tvn BndrVis
    flag -> Name -> BndrVis -> Kind -> TyVarBndrVis
    forall flag. Name -> flag -> Kind -> TyVarBndr_ flag
    kindedTVFlag Name
    tvn BndrVis
    flag (Kind -> TyVarBndrVis) -> Kind -> TyVarBndrVis
    forall a b. (a -> b) -> a -> b
    $ Kind -> Maybe Kind -> Kind
    forall a. a -> Maybe a -> a
    fromMaybe Kind
    StarT (Maybe Kind -> Kind) -> Maybe Kind -> Kind
    forall a b. (a -> b) -> a -> b
    $ Name -> Map Name Kind -> Maybe Kind
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Name
    tvn Map Name Kind
    cls_tvb_kind_map)
            (\Name
    _ BndrVis
    _ Kind
    _ -> TyVarBndrVis
    tvb)
            TyVarBndrVis
    tvb

    -- Data types have CUSKs when:
    --
    -- 1. All of their type variables have explicit kinds.
    -- 2. All kind variables in the result kind are explicitly quantified.
    datatype_kind :: [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    datatype_kind :: [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    datatype_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki =
      Bool -> Maybe Kind -> Maybe Kind
    forall (f :: * -> *) a. Alternative f => Bool -> f a -> f a
    whenAlt ((TyVarBndrVis -> Bool) -> [TyVarBndrVis] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all TyVarBndrVis -> Bool
    forall flag. TyVarBndr_ flag -> Bool
    tvb_is_kinded [TyVarBndrVis]
    tvbs Bool -> Bool -> Bool
    && Bool
    ki_fvs_are_bound) (Maybe Kind -> Maybe Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> a -> b
    $
      [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind [TyVarBndrVis]
    tvbs (Maybe Kind -> Kind
    default_res_ki Maybe Kind
    m_ki)
      where
        ki_fvs_are_bound :: Bool
        ki_fvs_are_bound :: Bool
    ki_fvs_are_bound =
          let ki_fvs :: Set Name
    ki_fvs   = [Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList ([Name] -> Set Name) -> [Name] -> Set Name
    forall a b. (a -> b) -> a -> b
    $ (Kind -> [Name]) -> Maybe Kind -> [Name]
    forall m a. Monoid m => (a -> m) -> Maybe a -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap Kind -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Maybe Kind
    m_ki
              tvb_vars :: Set Name
    tvb_vars = [Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList ([Name] -> Set Name) -> [Name] -> Set Name
    forall a b. (a -> b) -> a -> b
    $ Cxt -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables (Cxt -> [Name]) -> Cxt -> [Name]
    forall a b. (a -> b) -> a -> b
    $ (TyVarBndrVis -> Kind) -> [TyVarBndrVis] -> Cxt
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> Kind
    forall flag. TyVarBndr_ flag -> Kind
    tvbToTypeWithSig [TyVarBndrVis]
    tvbs
          in Set Name
    ki_fvs Set Name -> Set Name -> Bool
    forall a. Ord a => Set a -> Set a -> Bool
    `Set.isSubsetOf` Set Name
    tvb_vars

    -- Classes have CUSKs when all of their type variables have explicit kinds.
    class_kind :: [TyVarBndrVis] -> Maybe Kind
    class_kind :: [TyVarBndrVis] -> Maybe Kind
    class_kind [TyVarBndrVis]
    tvbs = Bool -> Maybe Kind -> Maybe Kind
    forall (f :: * -> *) a. Alternative f => Bool -> f a -> f a
    whenAlt ((TyVarBndrVis -> Bool) -> [TyVarBndrVis] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all TyVarBndrVis -> Bool
    forall flag. TyVarBndr_ flag -> Bool
    tvb_is_kinded [TyVarBndrVis]
    tvbs) (Maybe Kind -> Maybe Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> a -> b
    $
                      [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind [TyVarBndrVis]
    tvbs Kind
    ConstraintT

    -- Open type families and data families always have CUSKs. Type variables
    -- without explicit kinds default to Type, as does the return kind if it
    -- is not specified.
    open_ty_fam_kind :: [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    open_ty_fam_kind :: [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    open_ty_fam_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki =
      [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind ((TyVarBndrVis -> TyVarBndrVis) -> [TyVarBndrVis] -> [TyVarBndrVis]
    forall a b. (a -> b) -> [a] -> [b]
    map TyVarBndrVis -> TyVarBndrVis
    forall flag. TyVarBndr_ flag -> TyVarBndr_ flag
    default_tvb [TyVarBndrVis]
    tvbs) (Maybe Kind -> Kind
    default_res_ki Maybe Kind
    m_ki)

    -- Closed type families have CUSKs when:
    --
    -- 1. All of their type variables have explicit kinds.
    -- 2. An explicit return kind is supplied.
    closed_ty_fam_kind :: [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    closed_ty_fam_kind :: [TyVarBndrVis] -> Maybe Kind -> Maybe Kind
    closed_ty_fam_kind [TyVarBndrVis]
    tvbs Maybe Kind
    m_ki =
      case Maybe Kind
    m_ki of
        Just Kind
    ki -> Bool -> Maybe Kind -> Maybe Kind
    forall (f :: * -> *) a. Alternative f => Bool -> f a -> f a
    whenAlt ((TyVarBndrVis -> Bool) -> [TyVarBndrVis] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all TyVarBndrVis -> Bool
    forall flag. TyVarBndr_ flag -> Bool
    tvb_is_kinded [TyVarBndrVis]
    tvbs) (Maybe Kind -> Maybe Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> a -> b
    $
                   [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind [TyVarBndrVis]
    tvbs Kind
    ki
        Maybe Kind
    Nothing -> Maybe Kind
    forall a. Maybe a
    Nothing

    -- Type synonyms have CUSKs when:
    --
    -- 1. All of their type variables have explicit kinds.
    -- 2. The right-hand-side type is annotated with an explicit kind.
    ty_syn_kind :: [TyVarBndrVis] -> Type -> Maybe Kind
    ty_syn_kind :: [TyVarBndrVis] -> Kind -> Maybe Kind
    ty_syn_kind [TyVarBndrVis]
    tvbs Kind
    rhs =
      case Kind
    rhs of
        SigT Kind
    _ Kind
    ki -> Bool -> Maybe Kind -> Maybe Kind
    forall (f :: * -> *) a. Alternative f => Bool -> f a -> f a
    whenAlt ((TyVarBndrVis -> Bool) -> [TyVarBndrVis] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all TyVarBndrVis -> Bool
    forall flag. TyVarBndr_ flag -> Bool
    tvb_is_kinded [TyVarBndrVis]
    tvbs) (Maybe Kind -> Maybe Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> a -> b
    $
                     [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind [TyVarBndrVis]
    tvbs Kind
    ki
        Kind
    _         -> Maybe Kind
    forall a. Maybe a
    Nothing

    -- Attempt to construct the full kind of a type-level declaration from its
    -- type variable binders and return kind. Do note that the result type of
    -- this function is `Maybe Kind` because there are situations where even
    -- this amount of information is not sufficient to determine the full kind.
    -- See Note [The limitations of standalone kind signatures].
    build_kind :: [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind :: [TyVarBndrVis] -> Kind -> Maybe Kind
    build_kind [TyVarBndrVis]
    arg_kinds Kind
    res_kind =
      (Kind -> Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Kind -> Kind
    quantifyType (Maybe Kind -> Maybe Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> a -> b
    $ (Maybe Kind, Set Name) -> Maybe Kind
    forall a b. (a, b) -> a
    fst ((Maybe Kind, Set Name) -> Maybe Kind)
    -> (Maybe Kind, Set Name) -> Maybe Kind
    forall a b. (a -> b) -> a -> b
    $
      (TyVarBndrVis -> (Maybe Kind, Set Name) -> (Maybe Kind, Set Name))
    -> (Maybe Kind, Set Name)
    -> [TyVarBndrVis]
    -> (Maybe Kind, Set Name)
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr TyVarBndrVis -> (Maybe Kind, Set Name) -> (Maybe Kind, Set Name)
    go (Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    res_kind, [Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList (Kind -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Kind
    res_kind)) [TyVarBndrVis]
    arg_kinds
      where
        go :: TyVarBndrVis -> (Maybe Kind, Set Name) -> (Maybe Kind, Set Name)
        go :: TyVarBndrVis -> (Maybe Kind, Set Name) -> (Maybe Kind, Set Name)
    go TyVarBndrVis
    tvb (Maybe Kind
    res, Set Name
    res_fvs) =
          (Name -> (Maybe Kind, Set Name))
    -> (Name -> Kind -> (Maybe Kind, Set Name))
    -> TyVarBndrVis
    -> (Maybe Kind, Set Name)
    forall r flag.
    (Name -> r) -> (Name -> Kind -> r) -> TyVarBndr_ flag -> r
    elimTV (\Name
    n ->
                   ( if Name
    n Name -> Set Name -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Name
    res_fvs
                     then TyVarBndrVis -> Maybe Kind -> Maybe Kind
    forall_ TyVarBndrVis
    tvb Maybe Kind
    res
                     else Maybe Kind
    forall a. Maybe a
    Nothing -- We have a type variable binder without an
                                  -- explicit kind that is not used dependently, so
                                  -- we cannot build a kind from it. This is the
                                  -- only case where we return Nothing.
                   , Set Name
    res_fvs
                   ))
                 (\Name
    n Kind
    k ->
                   ( if Name
    n Name -> Set Name -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set Name
    res_fvs
                     then TyVarBndrVis -> Maybe Kind -> Maybe Kind
    forall_ TyVarBndrVis
    tvb Maybe Kind
    res
                     else (Kind -> Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Kind
    ArrowT Kind -> Kind -> Kind
    `AppT` Kind
    k Kind -> Kind -> Kind
    `AppT`) Maybe Kind
    res
                   , [Name] -> Set Name
    forall a. Ord a => [a] -> Set a
    Set.fromList (Kind -> [Name]
    forall a. TypeSubstitution a => a -> [Name]
    freeVariables Kind
    k) Set Name -> Set Name -> Set Name
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.union` Set Name
    res_fvs
                   ))
                 TyVarBndrVis
    tvb

        forall_ :: TyVarBndrVis -> Maybe Kind -> Maybe Kind
    #if __GLASGOW_HASKELL__ >= 809
        forall_ :: TyVarBndrVis -> Maybe Kind -> Maybe Kind
    forall_ TyVarBndrVis
    tvb Maybe Kind
    m_ki = (Kind -> Kind) -> Maybe Kind -> Maybe Kind
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Kind -> Kind
    forallT Maybe Kind
    m_ki
          where
            bndrVis :: BndrVis
            bndrVis :: BndrVis
    bndrVis = (Name -> BndrVis -> BndrVis)
    -> (Name -> BndrVis -> Kind -> BndrVis) -> TyVarBndrVis -> BndrVis
    forall flag r.
    (Name -> flag -> r)
    -> (Name -> flag -> Kind -> r) -> TyVarBndr_ flag -> r
    elimTVFlag (\Name
    _ BndrVis
    flag -> BndrVis
    flag) (\Name
    _ BndrVis
    flag Kind
    _ -> BndrVis
    flag) TyVarBndrVis
    tvb
            forallT :: Kind -> Kind
            forallT :: Kind -> Kind
    forallT = case BndrVis
    bndrVis of
              BndrVis
    BndrReq   -> [TyVarBndrUnit] -> Kind -> Kind
    ForallVisT (() -> [TyVarBndrVis] -> [TyVarBndrUnit]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags () [TyVarBndrVis
    tvb])
              BndrVis
    BndrInvis -> [TyVarBndr Specificity] -> Cxt -> Kind -> Kind
    ForallT (Specificity -> [TyVarBndrVis] -> [TyVarBndr Specificity]
    forall newFlag oldFlag.
    newFlag -> [TyVarBndr_ oldFlag] -> [TyVarBndr_ newFlag]
    changeTVFlags Specificity
    SpecifiedSpec [TyVarBndrVis
    tvb]) []
          -- One downside of this approach is that we generate kinds like this:
          --
          --   forall a -> forall b -> forall c -> (a, b, c)
          --
          -- Instead of this more compact kind:
          --
          --   forall a b c -> (a, b, c)
          --
          -- Thankfully, the difference is only cosmetic.
    #else
        forall_ _   _    = Nothing
    #endif

    tvb_is_kinded :: TyVarBndr_ flag -> Bool
    tvb_is_kinded :: forall flag. TyVarBndr_ flag -> Bool
    tvb_is_kinded = Maybe Kind -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe Kind -> Bool)
    -> (TyVarBndr_ flag -> Maybe Kind) -> TyVarBndr_ flag -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TyVarBndr_ flag -> Maybe Kind
    forall flag. TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe

    tvb_kind_maybe :: TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe :: forall flag. TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe = (Name -> Maybe Kind)
    -> (Name -> Kind -> Maybe Kind) -> TyVarBndr_ flag -> Maybe Kind
    forall r flag.
    (Name -> r) -> (Name -> Kind -> r) -> TyVarBndr_ flag -> r
    elimTV (\Name
    _ -> Maybe Kind
    forall a. Maybe a
    Nothing) (\Name
    _ Kind
    k -> Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    k)

    vis_arg_kind_maybe :: VisFunArg -> Maybe Kind
    vis_arg_kind_maybe :: VisFunArg -> Maybe Kind
    vis_arg_kind_maybe (VisFADep TyVarBndrUnit
    tvb) = TyVarBndrUnit -> Maybe Kind
    forall flag. TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe TyVarBndrUnit
    tvb
    vis_arg_kind_maybe (VisFAAnon Kind
    k)  = Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    k

    default_tvb :: TyVarBndr_ flag -> TyVarBndr_ flag
    default_tvb :: forall flag. TyVarBndr_ flag -> TyVarBndr_ flag
    default_tvb TyVarBndr_ flag
    tvb = (Name -> flag -> TyVarBndr_ flag)
    -> (Name -> flag -> Kind -> TyVarBndr_ flag)
    -> TyVarBndr_ flag
    -> TyVarBndr_ flag
    forall flag r.
    (Name -> flag -> r)
    -> (Name -> flag -> Kind -> r) -> TyVarBndr_ flag -> r
    elimTVFlag (\Name
    n flag
    flag -> Name -> flag -> Kind -> TyVarBndr_ flag
    forall flag. Name -> flag -> Kind -> TyVarBndr_ flag
    kindedTVFlag Name
    n flag
    flag Kind
    StarT) (\Name
    _ flag
    _ Kind
    _ -> TyVarBndr_ flag
    tvb) TyVarBndr_ flag
    tvb

    default_res_ki :: Maybe Kind -> Kind
    default_res_ki :: Maybe Kind -> Kind
    default_res_ki = Kind -> Maybe Kind -> Kind
    forall a. a -> Maybe a -> a
    fromMaybe Kind
    StarT

    res_sig_to_kind :: FamilyResultSig -> Maybe Kind
    res_sig_to_kind :: FamilyResultSig -> Maybe Kind
    res_sig_to_kind FamilyResultSig
    NoSig          = Maybe Kind
    forall a. Maybe a
    Nothing
    res_sig_to_kind (KindSig Kind
    k)    = Kind -> Maybe Kind
    forall a. a -> Maybe a
    Just Kind
    k
    res_sig_to_kind (TyVarSig TyVarBndrUnit
    tvb) = TyVarBndrUnit -> Maybe Kind
    forall flag. TyVarBndr_ flag -> Maybe Kind
    tvb_kind_maybe TyVarBndrUnit
    tvb

    whenAlt :: Alternative f => Bool -> f a -> f a
    whenAlt :: forall (f :: * -> *) a. Alternative f => Bool -> f a -> f a
    whenAlt Bool
    b f a
    fa = if Bool
    b then f a
    fa else f a
    forall a. f a
    forall (f :: * -> *) a. Alternative f => f a
    empty

    {-
    Note [The limitations of standalone kind signatures]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    A current limitation of StandaloneKindSignatures is that they cannot be applied
    to associated type families. This can have some surprising consequences.
    Consider the following code, taken from
    https://gitlab.haskell.org/ghc/ghc/issues/17072#note_221324:

      type C :: forall a -> a -> Constraint
      class C a b where
        type T a :: Type

    The parent class C has a standalone kind signature, so GHC treats its
    associated types as if they had CUSKs. Can th-desugar figure out the kind
    that GHC gives to T?

    Unfortunately, the answer is "not easily". This is because `type T a` says
    nothing about the kind of `a`, so th-desugar's only other option is to inspect
    the kind signature for C. Even this is for naught, as the `forall a -> ...`
    part doesn't state the kind of `a` either! The only way to know that the kind
    of `a` should be Type is to infer that from the rest of the kind
    (`a -> Constraint`), but this gets perilously close to requiring full kind
    inference, which is rather unwieldy in Template Haskell.

    In cases like T, we simply give up and return Nothing when trying to reify
    its kind. It's not ideal, but them's the breaks when you try to extract kinds
    from syntax. There is a rather simple workaround available: just write
    `type C :: forall (a :: Type) -> a -> Constraint` instead.
    -}

    --------------------------------------
    -- Looking up name value and type names
    --------------------------------------

    -- | Like 'lookupValueName' from Template Haskell, but looks also in 'Names' of
    -- not-yet-typechecked declarations. To establish this list of not-yet-typechecked
    -- declarations, use 'withLocalDeclarations'. Returns 'Nothing' if no value
    -- with the same name can be found.
    lookupValueNameWithLocals :: DsMonad q => String -> q (Maybe Name)
    lookupValueNameWithLocals :: forall (q :: * -> *). DsMonad q => String -> q (Maybe Name)
    lookupValueNameWithLocals = Bool -> String -> q (Maybe Name)
    forall (q :: * -> *). DsMonad q => Bool -> String -> q (Maybe Name)
    lookupNameWithLocals Bool
    False

    -- | Like 'lookupTypeName' from Template Haskell, but looks also in 'Names' of
    -- not-yet-typechecked declarations. To establish this list of not-yet-typechecked
    -- declarations, use 'withLocalDeclarations'. Returns 'Nothing' if no type
    -- with the same name can be found.
    lookupTypeNameWithLocals :: DsMonad q => String -> q (Maybe Name)
    lookupTypeNameWithLocals :: forall (q :: * -> *). DsMonad q => String -> q (Maybe Name)
    lookupTypeNameWithLocals = Bool -> String -> q (Maybe Name)
    forall (q :: * -> *). DsMonad q => Bool -> String -> q (Maybe Name)
    lookupNameWithLocals Bool
    True

    lookupNameWithLocals :: forall q. DsMonad q => Bool -> String -> q (Maybe Name)
    lookupNameWithLocals :: forall (q :: * -> *). DsMonad q => Bool -> String -> q (Maybe Name)
    lookupNameWithLocals Bool
    ns String
    s = do
        mb_name <- Bool -> String -> q (Maybe Name)
    forall (m :: * -> *). Quasi m => Bool -> String -> m (Maybe Name)
    qLookupName Bool
    ns String
    s
        case mb_name of
          j_name :: Maybe Name
    j_name@(Just{}) -> Maybe Name -> q (Maybe Name)
    forall a. a -> q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Name
    j_name
          Maybe Name
    Nothing         -> q (Maybe Name)
    consult_locals
      where
        built_name :: Name
    built_name = String -> Name
    mkName String
    s

        consult_locals :: q (Maybe Name)
    consult_locals = do
          decs <- q [Dec]
    forall (m :: * -> *). DsMonad m => m [Dec]
    localDeclarations
          let mb_infos = (Dec -> Maybe (Name, Info)) -> [Dec] -> [Maybe (Name, Info)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Name -> [Dec] -> Dec -> Maybe (Name, Info)
    reifyInDec Name
    built_name [Dec]
    decs) [Dec]
    decs
              infos = [Maybe (Name, Info)] -> [(Name, Info)]
    forall a. [Maybe a] -> [a]
    catMaybes [Maybe (Name, Info)]
    mb_infos
          firstMatchM (if ns then find_type_name
                             else find_value_name) infos

        -- These functions work over Named Infos so we can avoid performing
        -- tiresome pattern-matching to retrieve the name associated with each Info.
        find_type_name, find_value_name :: Named Info -> q (Maybe Name)
        find_type_name :: (Name, Info) -> q (Maybe Name)
    find_type_name (Name
    n, Info
    info) = do
          name_space <- Info -> q NameSpace
    forall (q :: * -> *). DsMonad q => Info -> q NameSpace
    lookupInfoNameSpace Info
    info
          pure $ case name_space of
            NameSpace
    TcClsName -> Name -> Maybe Name
    forall a. a -> Maybe a
    Just Name
    n
            NameSpace
    VarName   -> Maybe Name
    forall a. Maybe a
    Nothing
            NameSpace
    DataName  -> Maybe Name
    forall a. Maybe a
    Nothing
    #if __GLASGOW_HASKELL__ >= 907
            FldName{} -> Maybe Name
    forall a. Maybe a
    Nothing
    #endif

        find_value_name :: (Name, Info) -> q (Maybe Name)
    find_value_name (Name
    n, Info
    info) = do
          name_space <- Info -> q NameSpace
    forall (q :: * -> *). DsMonad q => Info -> q NameSpace
    lookupInfoNameSpace Info
    info
          case name_space of
            NameSpace
    VarName   -> Maybe Name -> q (Maybe Name)
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe Name -> q (Maybe Name)) -> Maybe Name -> q (Maybe Name)
    forall a b. (a -> b) -> a -> b
    $ Name -> Maybe Name
    forall a. a -> Maybe a
    Just Name
    n
            NameSpace
    DataName  -> Maybe Name -> q (Maybe Name)
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe Name -> q (Maybe Name)) -> Maybe Name -> q (Maybe Name)
    forall a b. (a -> b) -> a -> b
    $ Name -> Maybe Name
    forall a. a -> Maybe a
    Just Name
    n
            NameSpace
    TcClsName -> Maybe Name -> q (Maybe Name)
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe Name
    forall a. Maybe a
    Nothing
    #if __GLASGOW_HASKELL__ >= 907
            FldName{} -> do
              fieldSels <- Extension -> q Bool
    forall (m :: * -> *). Quasi m => Extension -> m Bool
    qIsExtEnabled Extension
    LangExt.FieldSelectors
              pure $ if fieldSels then Just n else Nothing
    #endif

    -- | Like TH's @lookupValueName@, but if this name is not bound, then we assume
    -- it is declared in the current module.
    --
    -- Unlike 'mkDataName', this also consults the local declarations in scope when
    -- determining if the name is currently bound.
    mkDataNameWithLocals :: DsMonad q => String -> q Name
    mkDataNameWithLocals :: forall (q :: * -> *). DsMonad q => String -> q Name
    mkDataNameWithLocals = (String -> q (Maybe Name))
    -> (String -> String -> String -> Name) -> String -> q Name
    forall (q :: * -> *).
    Quasi q =>
    (String -> q (Maybe Name))
    -> (String -> String -> String -> Name) -> String -> q Name
    mkNameWith String -> q (Maybe Name)
    forall (q :: * -> *). DsMonad q => String -> q (Maybe Name)
    lookupValueNameWithLocals String -> String -> String -> Name
    mkNameG_d

    -- | Like TH's @lookupTypeName@, but if this name is not bound, then we assume
    -- it is declared in the current module.
    --
    -- Unlike 'mkTypeName', this also consults the local declarations in scope when
    -- determining if the name is currently bound.
    mkTypeNameWithLocals :: DsMonad q => String -> q Name
    mkTypeNameWithLocals :: forall (q :: * -> *). DsMonad q => String -> q Name
    mkTypeNameWithLocals = (String -> q (Maybe Name))
    -> (String -> String -> String -> Name) -> String -> q Name
    forall (q :: * -> *).
    Quasi q =>
    (String -> q (Maybe Name))
    -> (String -> String -> String -> Name) -> String -> q Name
    mkNameWith String -> q (Maybe Name)
    forall (q :: * -> *). DsMonad q => String -> q (Maybe Name)
    lookupTypeNameWithLocals String -> String -> String -> Name
    mkNameG_tc

    -- | Determines a `Name`'s 'NameSpace'. If the 'NameSpace' is attached to
    -- the 'Name' itself (i.e., it is unambiguous), then that 'NameSpace' is
    -- immediately returned. Otherwise, reification is used to lookup up the
    -- 'NameSpace' (consulting local declarations if necessary).
    --
    -- Note that if a 'Name' lives in two different 'NameSpaces' (which can
    -- genuinely happen--for instance, @'mkName' \"==\"@, where @==@ is both
    -- a function and a type family), then this function will simply return
    -- whichever 'NameSpace' is discovered first via reification. If you wish
    -- to find a 'Name' in a particular 'NameSpace', use the
    -- 'lookupValueNameWithLocals' or 'lookupTypeNameWithLocals' functions.
    reifyNameSpace :: DsMonad q => Name -> q (Maybe NameSpace)
    reifyNameSpace :: forall (q :: * -> *). DsMonad q => Name -> q (Maybe NameSpace)
    reifyNameSpace n :: Name
    n@(Name OccName
    _ NameFlavour
    nf) =
      case NameFlavour
    nf of
        -- NameGs are simple, as they have a NameSpace attached.
        NameG NameSpace
    ns PkgName
    _ ModName
    _ -> Maybe NameSpace -> q (Maybe NameSpace)
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe NameSpace -> q (Maybe NameSpace))
    -> Maybe NameSpace -> q (Maybe NameSpace)
    forall a b. (a -> b) -> a -> b
    $ NameSpace -> Maybe NameSpace
    forall a. a -> Maybe a
    Just NameSpace
    ns

        -- For other names, we must use reification to determine what NameSpace
        -- it lives in (if any).
        NameFlavour
    _ -> do mb_info <- Name -> q (Maybe Info)
    forall (q :: * -> *). DsMonad q => Name -> q (Maybe Info)
    reifyWithLocals_maybe Name
    n
                traverse lookupInfoNameSpace mb_info

    -- | Look up a name's 'NameSpace' from its 'Info'.
    lookupInfoNameSpace :: DsMonad q => Info -> q NameSpace
    lookupInfoNameSpace :: forall (q :: * -> *). DsMonad q => Info -> q NameSpace
    lookupInfoNameSpace Info
    info =
      case Info
    info of
        ClassI{}     -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    TcClsName
        TyConI{}     -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    TcClsName
        FamilyI{}    -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    TcClsName
        PrimTyConI{} -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    TcClsName
        TyVarI{}     -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    TcClsName

        ClassOpI{}   -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    VarName
    #if __GLASGOW_HASKELL__ >= 907
        -- A VarI might correspond to a top-level value (i.e., a VarName) or a
        -- record field (i.e., a FldName). The only way to distinguish them is to
        -- check if the VarI's Name and Type correspond to a data type with a
        -- corresponding record field Name.
        VarI Name
    n Kind
    ty Maybe Dec
    _  -> do
          -- First, check to see if `ty` is of the form `D -> T`, where `D` is
          -- headed by a data type. We can safely ignore `forall`s here by using
          -- `filterVisFunArgs`, as we only care about the first visible argument.
          let (FunArgs
    ty_args, Kind
    _ty_res) = Kind -> (FunArgs, Kind)
    unravelType Kind
    ty
              ty_vis_args :: [VisFunArg]
    ty_vis_args = FunArgs -> [VisFunArg]
    filterVisFunArgs FunArgs
    ty_args
          case [VisFunArg]
    ty_vis_args of
            [VisFAAnon Kind
    ty_anon_arg]
              | (ConT Name
    parent_name, [TypeArg]
    _) <- Kind -> (Kind, [TypeArg])
    unfoldType Kind
    ty_anon_arg
              -> -- If we find the data type constructor `parent_name`, then check
                 -- if one of the data constructors for `parent_name` contains a
                 -- record field named `n`.
                 do mb_parent_info <- Name -> q (Maybe Info)
    forall (q :: * -> *). DsMonad q => Name -> q (Maybe Info)
    reifyWithLocals_maybe Name
    parent_name
                    pure $ case mb_parent_info of
                      Just (TyConI (DataD Cxt
    _cxt Name
    _name [TyVarBndrVis]
    _tvbs Maybe Kind
    _mk [Con]
    cons [DerivClause]
    _derivings))
                        |  Maybe (Named RecSelInfo) -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe (Named RecSelInfo) -> Bool)
    -> Maybe (Named RecSelInfo) -> Bool
    forall a b. (a -> b) -> a -> b
    $ Name -> [Con] -> Maybe (Named RecSelInfo)
    findRecSelector Name
    n [Con]
    cons
                        -> String -> NameSpace
    FldName (String -> NameSpace) -> String -> NameSpace
    forall a b. (a -> b) -> a -> b
    $ Name -> String
    nameBase Name
    parent_name
                      Just (TyConI (NewtypeD Cxt
    _cxt Name
    _name [TyVarBndrVis]
    _tvbs Maybe Kind
    _mk Con
    con [DerivClause]
    _derivings))
                        |  Maybe (Named RecSelInfo) -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe (Named RecSelInfo) -> Bool)
    -> Maybe (Named RecSelInfo) -> Bool
    forall a b. (a -> b) -> a -> b
    $ Name -> [Con] -> Maybe (Named RecSelInfo)
    findRecSelector Name
    n [Con
    con]
                        -> String -> NameSpace
    FldName (String -> NameSpace) -> String -> NameSpace
    forall a b. (a -> b) -> a -> b
    $ Name -> String
    nameBase Name
    parent_name
                      Maybe Info
    _ -> NameSpace
    VarName
            [VisFunArg]
    _ -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    VarName
    #else
        VarI{}       -> pure VarName
    #endif

        DataConI Name
    _dc_name Kind
    _dc_ty Name
    parent_name -> do
          -- DataConI usually refers to a value-level Name, but it could also refer
          -- to a type-level 'Name' if the data constructor corresponds to a
          -- @type data@ declaration. In order to know for sure, we must perform
          -- some additional reification.
          mb_parent_info <- Name -> q (Maybe Info)
    forall (q :: * -> *). DsMonad q => Name -> q (Maybe Info)
    reifyWithLocals_maybe Name
    parent_name
          pure $ case mb_parent_info of
    #if __GLASGOW_HASKELL__ >= 906
            Just (TyConI (TypeDataD {}))
              -> NameSpace
    TcClsName
    #endif
            Maybe Info
    _ -> NameSpace
    DataName
    #if __GLASGOW_HASKELL__ >= 801
        PatSynI{}    -> NameSpace -> q NameSpace
    forall a. a -> q a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure NameSpace
    DataName
    #endif