    {-
    (c) The University of Glasgow 2006
    (c) The GRASP/AQUA Project, Glasgow University, 1992-1998

    \section{@Vars@: Variables}
    -}

    {-# LANGUAGE CPP, FlexibleContexts, MultiWayIf, FlexibleInstances, DeriveDataTypeable,
                 PatternSynonyms, BangPatterns #-}
    {-# OPTIONS_GHC -Wno-incomplete-uni-patterns   #-}
    {-# OPTIONS_GHC -Wno-incomplete-record-updates #-}

    -- |
    -- #name_types#
    -- GHC uses several kinds of name internally:
    --
    -- * 'GHC.Types.Name.Occurrence.OccName': see "GHC.Types.Name.Occurrence#name_types"
    --
    -- * 'GHC.Types.Name.Reader.RdrName': see "GHC.Types.Name.Reader#name_types"
    --
    -- * 'GHC.Types.Name.Name': see "GHC.Types.Name#name_types"
    --
    -- * 'GHC.Types.Id.Id': see "GHC.Types.Id#name_types"
    --
    -- * 'GHC.Types.Var.Var' is a synonym for the 'GHC.Types.Id.Id' type but it may additionally
    --   potentially contain type variables, which have a 'GHC.Core.TyCo.Rep.Kind'
    --   rather than a 'GHC.Core.TyCo.Rep.Type' and only contain some extra
    --   details during typechecking.
    --
    --   These 'Var' names may either be global or local, see "GHC.Types.Var#globalvslocal"
    --
    -- #globalvslocal#
    -- Global 'Id's and 'Var's are those that are imported or correspond
    --    to a data constructor, primitive operation, or record selectors.
    -- Local 'Id's and 'Var's are those bound within an expression
    --    (e.g. by a lambda) or at the top level of the module being compiled.

    module GHC.Types.Var (
            -- * The main data type and synonyms
            Var, CoVar, Id, NcId, DictId, DFunId, EvVar, EqVar, EvId, IpId, JoinId,
            TyVar, TcTyVar, TypeVar, KindVar, TKVar, TyCoVar,

            -- * In and Out variants
            InVar,  InCoVar,  InId,  InTyVar,
            OutVar, OutCoVar, OutId, OutTyVar,

            -- ** Taking 'Var's apart
            varName, varUnique, varType,
            varMult, varMultMaybe,

            -- ** Modifying 'Var's
            setVarName, setVarUnique, setVarType,
            updateVarType, updateVarTypeM,

            -- ** Constructing, taking apart, modifying 'Id's
            mkGlobalVar, mkLocalVar, mkExportedLocalVar, mkCoVar,
            idInfo, idDetails,
            lazySetIdInfo, setIdDetails, globaliseId,
            setIdExported, setIdNotExported, setIdMult,
            updateIdTypeButNotMult,
            updateIdTypeAndMult, updateIdTypeAndMultM,

            -- ** Predicates
            isId, isTyVar, isTcTyVar,
            isLocalVar, isLocalId, isCoVar, isNonCoVarId, isTyCoVar,
            isGlobalId, isExportedId,
            mustHaveLocalBinding,

            -- * ArgFlags
            ArgFlag(Invisible,Required,Specified,Inferred),
            isVisibleArgFlag, isInvisibleArgFlag, sameVis,
            AnonArgFlag(..), Specificity(..),

            -- * TyVar's
            VarBndr(..), TyCoVarBinder, TyVarBinder, InvisTVBinder, ReqTVBinder,
            binderVar, binderVars, binderArgFlag, binderType,
            mkTyCoVarBinder, mkTyCoVarBinders,
            mkTyVarBinder, mkTyVarBinders,
            isTyVarBinder, tyVarSpecToBinder, tyVarSpecToBinders,
            mapVarBndr, mapVarBndrs, lookupVarBndr,

            -- ** Constructing TyVar's
            mkTyVar, mkTcTyVar,

            -- ** Taking 'TyVar's apart
            tyVarName, tyVarKind, tcTyVarDetails, setTcTyVarDetails,

            -- ** Modifying 'TyVar's
            setTyVarName, setTyVarUnique, setTyVarKind, updateTyVarKind,
            updateTyVarKindM,

            nonDetCmpVar

        ) where

    #include "HsVersions.h"

    import GHC.Prelude

    import {-# SOURCE #-}   GHC.Core.TyCo.Rep( Type, Kind, Mult )
    import {-# SOURCE #-}   GHC.Core.TyCo.Ppr( pprKind )
    import {-# SOURCE #-}   GHC.Tc.Utils.TcType( TcTyVarDetails, pprTcTyVarDetails, vanillaSkolemTv )
    import {-# SOURCE #-}   GHC.Types.Id.Info( IdDetails, IdInfo, coVarDetails, isCoVarDetails,
                                               vanillaIdInfo, pprIdDetails )
    import {-# SOURCE #-}   GHC.Builtin.Types ( manyDataConTy )
    import GHC.Types.Name hiding (varName)
    import GHC.Types.Unique ( Uniquable, Unique, getKey, getUnique
                            , mkUniqueGrimily, nonDetCmpUnique )
    import GHC.Utils.Misc
    import GHC.Utils.Binary
    import GHC.Utils.Outputable

    import Data.Data

    {-
    ************************************************************************
    *                                                                      *
                         Synonyms
    *                                                                      *
    ************************************************************************
    -- These synonyms are here and not in Id because otherwise we need a very
    -- large number of SOURCE imports of "GHC.Types.Id" :-(
    -}

    -- | Identifier
    type Id    = Var       -- A term-level identifier
                           --  predicate: isId

    -- | Coercion Variable
    type CoVar = Id        -- See Note [Evidence: EvIds and CoVars]
                           --   predicate: isCoVar

    -- |
    type NcId  = Id        -- A term-level (value) variable that is
                           -- /not/ an (unlifted) coercion
                           --    predicate: isNonCoVarId

    -- | Type or kind Variable
    type TyVar   = Var     -- Type *or* kind variable (historical)

    -- | Type or Kind Variable
    type TKVar   = Var     -- Type *or* kind variable (historical)

    -- | Type variable that might be a metavariable
    type TcTyVar = Var

    -- | Type Variable
    type TypeVar = Var     -- Definitely a type variable

    -- | Kind Variable
    type KindVar = Var     -- Definitely a kind variable
                           -- See Note [Kind and type variables]

    -- See Note [Evidence: EvIds and CoVars]
    -- | Evidence Identifier
    type EvId   = Id        -- Term-level evidence: DictId, IpId, or EqVar

    -- | Evidence Variable
    type EvVar  = EvId      -- ...historical name for EvId

    -- | Dictionary Function Identifier
    type DFunId = Id        -- A dictionary function

    -- | Dictionary Identifier
    type DictId = EvId      -- A dictionary variable

    -- | Implicit parameter Identifier
    type IpId   = EvId      -- A term-level implicit parameter

    -- | Equality Variable
    type EqVar  = EvId      -- Boxed equality evidence
    type JoinId = Id        -- A join variable

    -- | Type or Coercion Variable
    type TyCoVar = Id       -- Type, *or* coercion variable
                            --   predicate: isTyCoVar

    {- Many passes apply a substitution, and it's very handy to have type
       synonyms to remind us whether or not the substitution has been applied -}

    type InVar      = Var
    type InTyVar    = TyVar
    type InCoVar    = CoVar
    type InId       = Id
    type OutVar     = Var
    type OutTyVar   = TyVar
    type OutCoVar   = CoVar
    type OutId      = Id

    {- Note [Evidence: EvIds and CoVars]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    * An EvId (evidence Id) is a term-level evidence variable
      (dictionary, implicit parameter, or equality). Could be boxed or unboxed.

    * DictId, IpId, and EqVar are synonyms when we know what kind of
      evidence we are talking about.  For example, an EqVar has type (t1 ~ t2).

    * A CoVar is always an un-lifted coercion, of type (t1 ~# t2) or (t1 ~R# t2)

    Note [Kind and type variables]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Before kind polymorphism, TyVar were used to mean type variables. Now
    they are used to mean kind *or* type variables. KindVar is used when we
    know for sure that it is a kind variable. In future, we might want to
    go over the whole compiler code to use:
       - TKVar   to mean kind or type variables
       - TypeVar to mean         type variables only
       - KindVar to mean kind         variables

    ************************************************************************
    *                                                                      *
    \subsection{The main data type declarations}
    *                                                                      *
    ************************************************************************

    Every @Var@ has a @Unique@, to uniquify it and for fast comparison, a
    @Type@, and an @IdInfo@ (non-essential info about it, e.g.,
    strictness).  The essential info about different kinds of @Vars@ is
    in its @VarDetails@.
    -}

    -- | Variable
    --
    -- Essentially a typed 'Name', that may also contain some additional information
    -- about the 'Var' and its use sites.
    data Var
      = TyVar {  -- Type and kind variables
                 -- see Note [Kind and type variables]
            Var -> Name
    varName    :: !Name,
            Var -> Int
    realUnique :: {-# UNPACK #-} !Int,
                                         -- ^ Key for fast comparison
                                         -- Identical to the Unique in the name,
                                         -- cached here for speed
            Var -> Mult
    varType    :: Kind           -- ^ The type or kind of the 'Var' in question
     }

      | TcTyVar {                           -- Used only during type inference
                                            -- Used for kind variables during
                                            -- inference, as well
            varName        :: !Name,
            realUnique     :: {-# UNPACK #-} !Int,
            varType        :: Kind,
            Var -> TcTyVarDetails
    tc_tv_details  :: TcTyVarDetails
      }

      | Id {
            varName    :: !Name,
            realUnique :: {-# UNPACK #-} !Int,
            varType    :: Type,
            Var -> Mult
    varMult    :: Mult,             -- See Note [Multiplicity of let binders]
            Var -> IdScope
    idScope    :: IdScope,
            Var -> IdDetails
    id_details :: IdDetails,        -- Stable, doesn't change
            Var -> IdInfo
    id_info    :: IdInfo }          -- Unstable, updated by simplifier

    -- | Identifier Scope
    data IdScope    -- See Note [GlobalId/LocalId]
      = GlobalId
      | LocalId ExportFlag

    data ExportFlag   -- See Note [ExportFlag on binders]
      = NotExported   -- ^ Not exported: may be discarded as dead code.
      | Exported      -- ^ Exported: kept alive

    {- Note [ExportFlag on binders]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    An ExportFlag of "Exported" on a top-level binder says "keep this
    binding alive; do not drop it as dead code".  This transitively
    keeps alive all the other top-level bindings that this binding refers
    to.  This property is persisted all the way down the pipeline, so that
    the binding will be compiled all the way to object code, and its
    symbols will appear in the linker symbol table.

    However, note that this use of "exported" is quite different to the
    export list on a Haskell module.  Setting the ExportFlag on an Id does
    /not/ mean that if you import the module (in Haskell source code) you
    will see this Id.  Of course, things that appear in the export list
    of the source Haskell module do indeed have their ExportFlag set.
    But many other things, such as dictionary functions, are kept alive
    by having their ExportFlag set, even though they are not exported
    in the source-code sense.

    We should probably use a different term for ExportFlag, like
    KeepAlive.

    Note [GlobalId/LocalId]
    ~~~~~~~~~~~~~~~~~~~~~~~
    A GlobalId is
      * always a constant (top-level)
      * imported, or data constructor, or primop, or record selector
      * has a Unique that is globally unique across the whole
        GHC invocation (a single invocation may compile multiple modules)
      * never treated as a candidate by the free-variable finder;
            it's a constant!

    A LocalId is
      * bound within an expression (lambda, case, local let(rec))
      * or defined at top level in the module being compiled
      * always treated as a candidate by the free-variable finder

    After CoreTidy, top-level LocalIds are turned into GlobalIds

    Note [Multiplicity of let binders]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In Core, let-binders' multiplicity is always completely determined by syntax:
    a recursive let will always have multiplicity Many (it's a prerequisite for
    being recursive), and non-recursive let doesn't have a conventional multiplicity,
    instead they act, for the purpose of multiplicity, as an alias for their
    right-hand side.

    Therefore, the `varMult` field of identifier is only used by binders in lambda
    and case expressions. In a let expression the `varMult` field holds an
    arbitrary value which will (and must!) be ignored.
    -}

    instance Outputable Var where
      ppr :: Var -> SDoc
    ppr Var
    var = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
    forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
    sdocOption SDocContext -> Bool
    sdocSuppressVarKinds ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
    forall a b. (a -> b) -> a -> b
    $ \Bool
    supp_var_kinds ->
                (Bool -> SDoc) -> SDoc
    getPprDebug ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
    forall a b. (a -> b) -> a -> b
    $ \Bool
    debug ->
                (PprStyle -> SDoc) -> SDoc
    getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
    forall a b. (a -> b) -> a -> b
    $ \PprStyle
    sty ->
                let
                  ppr_var :: SDoc
    ppr_var = case Var
    var of
                      (TyVar {})
                         | Bool
    debug
                         -> SDoc -> SDoc
    brackets (String -> SDoc
    text String
    "tv")

                      (TcTyVar {tc_tv_details :: Var -> TcTyVarDetails
    tc_tv_details = TcTyVarDetails
    d})
                         | PprStyle -> Bool
    dumpStyle PprStyle
    sty Bool -> Bool -> Bool
    || Bool
    debug
                         -> SDoc -> SDoc
    brackets (TcTyVarDetails -> SDoc
    pprTcTyVarDetails TcTyVarDetails
    d)

                      (Id { idScope :: Var -> IdScope
    idScope = IdScope
    s, id_details :: Var -> IdDetails
    id_details = IdDetails
    d })
                         | Bool
    debug
                         -> SDoc -> SDoc
    brackets (IdScope -> SDoc
    ppr_id_scope IdScope
    s SDoc -> SDoc -> SDoc
    <> IdDetails -> SDoc
    pprIdDetails IdDetails
    d)

                      Var
    _  -> SDoc
    empty
                in if
                   |  Bool
    debug Bool -> Bool -> Bool
    && (Bool -> Bool
    not Bool
    supp_var_kinds)
                     -> SDoc -> SDoc
    parens (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Var -> Name
    varName Var
    var) SDoc -> SDoc -> SDoc
    <+> Maybe Mult -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Var -> Maybe Mult
    varMultMaybe Var
    var)
                                                  SDoc -> SDoc -> SDoc
    <+> SDoc
    ppr_var SDoc -> SDoc -> SDoc
    <+>
                              SDoc
    dcolon SDoc -> SDoc -> SDoc
    <+> Mult -> SDoc
    pprKind (Var -> Mult
    tyVarKind Var
    var))
                   |  Bool
    otherwise
                     -> Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Var -> Name
    varName Var
    var) SDoc -> SDoc -> SDoc
    <> SDoc
    ppr_var

    ppr_id_scope :: IdScope -> SDoc
    ppr_id_scope :: IdScope -> SDoc
    ppr_id_scope IdScope
    GlobalId              = String -> SDoc
    text String
    "gid"
    ppr_id_scope (LocalId ExportFlag
    Exported)    = String -> SDoc
    text String
    "lidx"
    ppr_id_scope (LocalId ExportFlag
    NotExported) = String -> SDoc
    text String
    "lid"

    instance NamedThing Var where
      getName :: Var -> Name
    getName = Var -> Name
    varName

    instance Uniquable Var where
      getUnique :: Var -> Unique
    getUnique = Var -> Unique
    varUnique

    instance Eq Var where
        Var
    a == :: Var -> Var -> Bool
    == Var
    b = Var -> Int
    realUnique Var
    a Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Var -> Int
    realUnique Var
    b

    instance Ord Var where
        Var
    a <= :: Var -> Var -> Bool
    <= Var
    b = Var -> Int
    realUnique Var
    a Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Var -> Int
    realUnique Var
    b
        Var
    a < :: Var -> Var -> Bool
    <  Var
    b = Var -> Int
    realUnique Var
    a Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <  Var -> Int
    realUnique Var
    b
        Var
    a >= :: Var -> Var -> Bool
    >= Var
    b = Var -> Int
    realUnique Var
    a Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Var -> Int
    realUnique Var
    b
        Var
    a > :: Var -> Var -> Bool
    >  Var
    b = Var -> Int
    realUnique Var
    a Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >  Var -> Int
    realUnique Var
    b
        Var
    a compare :: Var -> Var -> Ordering
    `compare` Var
    b = Var
    a Var -> Var -> Ordering
    `nonDetCmpVar` Var
    b

    -- | Compare Vars by their Uniques.
    -- This is what Ord Var does, provided here to make it explicit at the
    -- call-site that it can introduce non-determinism.
    -- See Note [Unique Determinism]
    nonDetCmpVar :: Var -> Var -> Ordering
    nonDetCmpVar :: Var -> Var -> Ordering
    nonDetCmpVar Var
    a Var
    b = Var -> Unique
    varUnique Var
    a Unique -> Unique -> Ordering
    `nonDetCmpUnique` Var -> Unique
    varUnique Var
    b

    instance Data Var where
      -- don't traverse?
      toConstr :: Var -> Constr
    toConstr Var
    _   = String -> Constr
    abstractConstr String
    "Var"
      gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Var
    gunfold forall b r. Data b => c (b -> r) -> c r
    _ forall r. r -> c r
    _  = String -> Constr -> c Var
    forall a. HasCallStack => String -> a
    error String
    "gunfold"
      dataTypeOf :: Var -> DataType
    dataTypeOf Var
    _ = String -> DataType
    mkNoRepType String
    "Var"

    instance HasOccName Var where
      occName :: Var -> OccName
    occName = Name -> OccName
    nameOccName (Name -> OccName) -> (Var -> Name) -> Var -> OccName
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Var -> Name
    varName

    varUnique :: Var -> Unique
    varUnique :: Var -> Unique
    varUnique Var
    var = Int -> Unique
    mkUniqueGrimily (Var -> Int
    realUnique Var
    var)

    varMultMaybe :: Id -> Maybe Mult
    varMultMaybe :: Var -> Maybe Mult
    varMultMaybe (Id { varMult :: Var -> Mult
    varMult = Mult
    mult }) = Mult -> Maybe Mult
    forall a. a -> Maybe a
    Just Mult
    mult
    varMultMaybe Var
    _ = Maybe Mult
    forall a. Maybe a
    Nothing

    setVarUnique :: Var -> Unique -> Var
    setVarUnique :: Var -> Unique -> Var
    setVarUnique Var
    var Unique
    uniq
      = Var
    var { realUnique :: Int
    realUnique = Unique -> Int
    getKey Unique
    uniq,
              varName :: Name
    varName = Name -> Unique -> Name
    setNameUnique (Var -> Name
    varName Var
    var) Unique
    uniq }

    setVarName :: Var -> Name -> Var
    setVarName :: Var -> Name -> Var
    setVarName Var
    var Name
    new_name
      = Var
    var { realUnique :: Int
    realUnique = Unique -> Int
    getKey (Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique Name
    new_name),
              varName :: Name
    varName = Name
    new_name }

    setVarType :: Var -> Type -> Var
    setVarType :: Var -> Mult -> Var
    setVarType Var
    id Mult
    ty = Var
    id { varType :: Mult
    varType = Mult
    ty }

    -- | Update a 'Var's type. Does not update the /multiplicity/
    -- stored in an 'Id', if any. Because of the possibility for
    -- abuse, ASSERTs that there is no multiplicity to update.
    updateVarType :: (Type -> Type) -> Var -> Var
    updateVarType :: (Mult -> Mult) -> Var -> Var
    updateVarType Mult -> Mult
    upd Var
    var
      | Bool
    debugIsOn
      = case Var
    var of
          Id { id_details :: Var -> IdDetails
    id_details = IdDetails
    details } -> ASSERT( isCoVarDetails details )
                                         Var
    result
          Var
    _ -> Var
    result
      | Bool
    otherwise
      = Var
    result
      where
        result :: Var
    result = Var
    var { varType :: Mult
    varType = Mult -> Mult
    upd (Var -> Mult
    varType Var
    var) }

    -- | Update a 'Var's type monadically. Does not update the /multiplicity/
    -- stored in an 'Id', if any. Because of the possibility for
    -- abuse, ASSERTs that there is no multiplicity to update.
    updateVarTypeM :: Monad m => (Type -> m Type) -> Var -> m Var
    updateVarTypeM :: forall (m :: * -> *). Monad m => (Mult -> m Mult) -> Var -> m Var
    updateVarTypeM Mult -> m Mult
    upd Var
    var
      | Bool
    debugIsOn
      = case Var
    var of
          Id { id_details :: Var -> IdDetails
    id_details = IdDetails
    details } -> ASSERT( isCoVarDetails details )
                                         m Var
    result
          Var
    _ -> m Var
    result
      | Bool
    otherwise
      = m Var
    result
      where
        result :: m Var
    result = do { Mult
    ty' <- Mult -> m Mult
    upd (Var -> Mult
    varType Var
    var)
                    ; Var -> m Var
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Var
    var { varType :: Mult
    varType = Mult
    ty' }) }

    {- *********************************************************************
    *                                                                      *
    *                   ArgFlag
    *                                                                      *
    ********************************************************************* -}

    -- | Argument Flag
    --
    -- Is something required to appear in source Haskell ('Required'),
    -- permitted by request ('Specified') (visible type application), or
    -- prohibited entirely from appearing in source Haskell ('Inferred')?
    -- See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in "GHC.Core.TyCo.Rep"
    data ArgFlag = Invisible Specificity
                 | Required
      deriving (ArgFlag -> ArgFlag -> Bool
    (ArgFlag -> ArgFlag -> Bool)
    -> (ArgFlag -> ArgFlag -> Bool) -> Eq ArgFlag
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: ArgFlag -> ArgFlag -> Bool
    $c/= :: ArgFlag -> ArgFlag -> Bool
    == :: ArgFlag -> ArgFlag -> Bool
    $c== :: ArgFlag -> ArgFlag -> Bool
    Eq, Eq ArgFlag
    Eq ArgFlag
    -> (ArgFlag -> ArgFlag -> Ordering)
    -> (ArgFlag -> ArgFlag -> Bool)
    -> (ArgFlag -> ArgFlag -> Bool)
    -> (ArgFlag -> ArgFlag -> Bool)
    -> (ArgFlag -> ArgFlag -> Bool)
    -> (ArgFlag -> ArgFlag -> ArgFlag)
    -> (ArgFlag -> ArgFlag -> ArgFlag)
    -> Ord ArgFlag
    ArgFlag -> ArgFlag -> Bool
    ArgFlag -> ArgFlag -> Ordering
    ArgFlag -> ArgFlag -> ArgFlag
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: ArgFlag -> ArgFlag -> ArgFlag
    $cmin :: ArgFlag -> ArgFlag -> ArgFlag
    max :: ArgFlag -> ArgFlag -> ArgFlag
    $cmax :: ArgFlag -> ArgFlag -> ArgFlag
    >= :: ArgFlag -> ArgFlag -> Bool
    $c>= :: ArgFlag -> ArgFlag -> Bool
    > :: ArgFlag -> ArgFlag -> Bool
    $c> :: ArgFlag -> ArgFlag -> Bool
    <= :: ArgFlag -> ArgFlag -> Bool
    $c<= :: ArgFlag -> ArgFlag -> Bool
    < :: ArgFlag -> ArgFlag -> Bool
    $c< :: ArgFlag -> ArgFlag -> Bool
    compare :: ArgFlag -> ArgFlag -> Ordering
    $ccompare :: ArgFlag -> ArgFlag -> Ordering
    Ord, Typeable ArgFlag
    Typeable ArgFlag
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> ArgFlag -> c ArgFlag)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c ArgFlag)
    -> (ArgFlag -> Constr)
    -> (ArgFlag -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c ArgFlag))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ArgFlag))
    -> ((forall b. Data b => b -> b) -> ArgFlag -> ArgFlag)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r)
    -> (forall u. (forall d. Data d => d -> u) -> ArgFlag -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> ArgFlag -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag)
    -> Data ArgFlag
    ArgFlag -> DataType
    ArgFlag -> Constr
    (forall b. Data b => b -> b) -> ArgFlag -> ArgFlag
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> ArgFlag -> u
    forall u. (forall d. Data d => d -> u) -> ArgFlag -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ArgFlag
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ArgFlag -> c ArgFlag
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ArgFlag)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ArgFlag)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ArgFlag -> m ArgFlag
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ArgFlag -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ArgFlag -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> ArgFlag -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> ArgFlag -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ArgFlag -> r
    gmapT :: (forall b. Data b => b -> b) -> ArgFlag -> ArgFlag
    $cgmapT :: (forall b. Data b => b -> b) -> ArgFlag -> ArgFlag
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ArgFlag)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ArgFlag)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ArgFlag)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ArgFlag)
    dataTypeOf :: ArgFlag -> DataType
    $cdataTypeOf :: ArgFlag -> DataType
    toConstr :: ArgFlag -> Constr
    $ctoConstr :: ArgFlag -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ArgFlag
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ArgFlag
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ArgFlag -> c ArgFlag
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ArgFlag -> c ArgFlag
    Data)
      -- (<) on ArgFlag means "is less visible than"

    -- | Whether an 'Invisible' argument may appear in source Haskell.
    data Specificity = InferredSpec
                       -- ^ the argument may not appear in source Haskell, it is
                       -- only inferred.
                     | SpecifiedSpec
                       -- ^ the argument may appear in source Haskell, but isn't
                       -- required.
      deriving (Specificity -> Specificity -> Bool
    (Specificity -> Specificity -> Bool)
    -> (Specificity -> Specificity -> Bool) -> Eq Specificity
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Specificity -> Specificity -> Bool
    $c/= :: Specificity -> Specificity -> Bool
    == :: Specificity -> Specificity -> Bool
    $c== :: Specificity -> Specificity -> Bool
    Eq, Eq Specificity
    Eq Specificity
    -> (Specificity -> Specificity -> Ordering)
    -> (Specificity -> Specificity -> Bool)
    -> (Specificity -> Specificity -> Bool)
    -> (Specificity -> Specificity -> Bool)
    -> (Specificity -> Specificity -> Bool)
    -> (Specificity -> Specificity -> Specificity)
    -> (Specificity -> Specificity -> Specificity)
    -> Ord Specificity
    Specificity -> Specificity -> Bool
    Specificity -> Specificity -> Ordering
    Specificity -> Specificity -> Specificity
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: Specificity -> Specificity -> Specificity
    $cmin :: Specificity -> Specificity -> Specificity
    max :: Specificity -> Specificity -> Specificity
    $cmax :: Specificity -> Specificity -> Specificity
    >= :: Specificity -> Specificity -> Bool
    $c>= :: Specificity -> Specificity -> Bool
    > :: Specificity -> Specificity -> Bool
    $c> :: Specificity -> Specificity -> Bool
    <= :: Specificity -> Specificity -> Bool
    $c<= :: Specificity -> Specificity -> Bool
    < :: Specificity -> Specificity -> Bool
    $c< :: Specificity -> Specificity -> Bool
    compare :: Specificity -> Specificity -> Ordering
    $ccompare :: Specificity -> Specificity -> Ordering
    Ord, Typeable Specificity
    Typeable Specificity
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> Specificity -> c Specificity)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Specificity)
    -> (Specificity -> Constr)
    -> (Specificity -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Specificity))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c Specificity))
    -> ((forall b. Data b => b -> b) -> Specificity -> Specificity)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Specificity -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Specificity -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Specificity -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Specificity -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Specificity -> m Specificity)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Specificity -> m Specificity)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Specificity -> m Specificity)
    -> Data Specificity
    Specificity -> DataType
    Specificity -> Constr
    (forall b. Data b => b -> b) -> Specificity -> Specificity
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Specificity -> u
    forall u. (forall d. Data d => d -> u) -> Specificity -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Specificity -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Specificity -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Specificity
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Specificity -> c Specificity
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Specificity)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Specificity)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Specificity -> m Specificity
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Specificity -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Specificity -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Specificity -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Specificity -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Specificity -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Specificity -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Specificity -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Specificity -> r
    gmapT :: (forall b. Data b => b -> b) -> Specificity -> Specificity
    $cgmapT :: (forall b. Data b => b -> b) -> Specificity -> Specificity
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Specificity)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Specificity)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Specificity)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Specificity)
    dataTypeOf :: Specificity -> DataType
    $cdataTypeOf :: Specificity -> DataType
    toConstr :: Specificity -> Constr
    $ctoConstr :: Specificity -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Specificity
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Specificity
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Specificity -> c Specificity
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Specificity -> c Specificity
    Data)

    pattern Inferred, Specified :: ArgFlag
    pattern $mInferred :: forall {r}. ArgFlag -> (Void# -> r) -> (Void# -> r) -> r
    $bInferred :: ArgFlag
    Inferred  = Invisible InferredSpec
    pattern $mSpecified :: forall {r}. ArgFlag -> (Void# -> r) -> (Void# -> r) -> r
    $bSpecified :: ArgFlag
    Specified = Invisible SpecifiedSpec

    {-# COMPLETE Required, Specified, Inferred #-}

    -- | Does this 'ArgFlag' classify an argument that is written in Haskell?
    isVisibleArgFlag :: ArgFlag -> Bool
    isVisibleArgFlag :: ArgFlag -> Bool
    isVisibleArgFlag ArgFlag
    Required = Bool
    True
    isVisibleArgFlag ArgFlag
    _        = Bool
    False

    -- | Does this 'ArgFlag' classify an argument that is not written in Haskell?
    isInvisibleArgFlag :: ArgFlag -> Bool
    isInvisibleArgFlag :: ArgFlag -> Bool
    isInvisibleArgFlag = Bool -> Bool
    not (Bool -> Bool) -> (ArgFlag -> Bool) -> ArgFlag -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ArgFlag -> Bool
    isVisibleArgFlag

    -- | Do these denote the same level of visibility? 'Required'
    -- arguments are visible, others are not. So this function
    -- equates 'Specified' and 'Inferred'. Used for printing.
    sameVis :: ArgFlag -> ArgFlag -> Bool
    sameVis :: ArgFlag -> ArgFlag -> Bool
    sameVis ArgFlag
    Required      ArgFlag
    Required      = Bool
    True
    sameVis (Invisible Specificity
    _) (Invisible Specificity
    _) = Bool
    True
    sameVis ArgFlag
    _             ArgFlag
    _             = Bool
    False

    instance Outputable ArgFlag where
      ppr :: ArgFlag -> SDoc
    ppr ArgFlag
    Required  = String -> SDoc
    text String
    "[req]"
      ppr ArgFlag
    Specified = String -> SDoc
    text String
    "[spec]"
      ppr ArgFlag
    Inferred  = String -> SDoc
    text String
    "[infrd]"

    instance Binary Specificity where
      put_ :: BinHandle -> Specificity -> IO ()
    put_ BinHandle
    bh Specificity
    SpecifiedSpec = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    0
      put_ BinHandle
    bh Specificity
    InferredSpec  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1

      get :: BinHandle -> IO Specificity
    get BinHandle
    bh = do
        Word8
    h <- BinHandle -> IO Word8
    getByte BinHandle
    bh
        case Word8
    h of
          Word8
    0 -> Specificity -> IO Specificity
    forall (m :: * -> *) a. Monad m => a -> m a
    return Specificity
    SpecifiedSpec
          Word8
    _ -> Specificity -> IO Specificity
    forall (m :: * -> *) a. Monad m => a -> m a
    return Specificity
    InferredSpec

    instance Binary ArgFlag where
      put_ :: BinHandle -> ArgFlag -> IO ()
    put_ BinHandle
    bh ArgFlag
    Required  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    0
      put_ BinHandle
    bh ArgFlag
    Specified = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1
      put_ BinHandle
    bh ArgFlag
    Inferred  = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    2

      get :: BinHandle -> IO ArgFlag
    get BinHandle
    bh = do
        Word8
    h <- BinHandle -> IO Word8
    getByte BinHandle
    bh
        case Word8
    h of
          Word8
    0 -> ArgFlag -> IO ArgFlag
    forall (m :: * -> *) a. Monad m => a -> m a
    return ArgFlag
    Required
          Word8
    1 -> ArgFlag -> IO ArgFlag
    forall (m :: * -> *) a. Monad m => a -> m a
    return ArgFlag
    Specified
          Word8
    _ -> ArgFlag -> IO ArgFlag
    forall (m :: * -> *) a. Monad m => a -> m a
    return ArgFlag
    Inferred

    -- | The non-dependent version of 'ArgFlag'.
    -- See Note [AnonArgFlag]
    -- Appears here partly so that it's together with its friends ArgFlag
    -- and ForallVisFlag, but also because it is used in IfaceType, rather
    -- early in the compilation chain
    data AnonArgFlag
      = VisArg    -- ^ Used for @(->)@: an ordinary non-dependent arrow.
                  --   The argument is visible in source code.
      | InvisArg  -- ^ Used for @(=>)@: a non-dependent predicate arrow.
                  --   The argument is invisible in source code.
      deriving (AnonArgFlag -> AnonArgFlag -> Bool
    (AnonArgFlag -> AnonArgFlag -> Bool)
    -> (AnonArgFlag -> AnonArgFlag -> Bool) -> Eq AnonArgFlag
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: AnonArgFlag -> AnonArgFlag -> Bool
    $c/= :: AnonArgFlag -> AnonArgFlag -> Bool
    == :: AnonArgFlag -> AnonArgFlag -> Bool
    $c== :: AnonArgFlag -> AnonArgFlag -> Bool
    Eq, Eq AnonArgFlag
    Eq AnonArgFlag
    -> (AnonArgFlag -> AnonArgFlag -> Ordering)
    -> (AnonArgFlag -> AnonArgFlag -> Bool)
    -> (AnonArgFlag -> AnonArgFlag -> Bool)
    -> (AnonArgFlag -> AnonArgFlag -> Bool)
    -> (AnonArgFlag -> AnonArgFlag -> Bool)
    -> (AnonArgFlag -> AnonArgFlag -> AnonArgFlag)
    -> (AnonArgFlag -> AnonArgFlag -> AnonArgFlag)
    -> Ord AnonArgFlag
    AnonArgFlag -> AnonArgFlag -> Bool
    AnonArgFlag -> AnonArgFlag -> Ordering
    AnonArgFlag -> AnonArgFlag -> AnonArgFlag
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: AnonArgFlag -> AnonArgFlag -> AnonArgFlag
    $cmin :: AnonArgFlag -> AnonArgFlag -> AnonArgFlag
    max :: AnonArgFlag -> AnonArgFlag -> AnonArgFlag
    $cmax :: AnonArgFlag -> AnonArgFlag -> AnonArgFlag
    >= :: AnonArgFlag -> AnonArgFlag -> Bool
    $c>= :: AnonArgFlag -> AnonArgFlag -> Bool
    > :: AnonArgFlag -> AnonArgFlag -> Bool
    $c> :: AnonArgFlag -> AnonArgFlag -> Bool
    <= :: AnonArgFlag -> AnonArgFlag -> Bool
    $c<= :: AnonArgFlag -> AnonArgFlag -> Bool
    < :: AnonArgFlag -> AnonArgFlag -> Bool
    $c< :: AnonArgFlag -> AnonArgFlag -> Bool
    compare :: AnonArgFlag -> AnonArgFlag -> Ordering
    $ccompare :: AnonArgFlag -> AnonArgFlag -> Ordering
    Ord, Typeable AnonArgFlag
    Typeable AnonArgFlag
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> AnonArgFlag -> c AnonArgFlag)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c AnonArgFlag)
    -> (AnonArgFlag -> Constr)
    -> (AnonArgFlag -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c AnonArgFlag))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c AnonArgFlag))
    -> ((forall b. Data b => b -> b) -> AnonArgFlag -> AnonArgFlag)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r)
    -> (forall u. (forall d. Data d => d -> u) -> AnonArgFlag -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> AnonArgFlag -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag)
    -> Data AnonArgFlag
    AnonArgFlag -> DataType
    AnonArgFlag -> Constr
    (forall b. Data b => b -> b) -> AnonArgFlag -> AnonArgFlag
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> AnonArgFlag -> u
    forall u. (forall d. Data d => d -> u) -> AnonArgFlag -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AnonArgFlag
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnonArgFlag -> c AnonArgFlag
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AnonArgFlag)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c AnonArgFlag)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AnonArgFlag -> m AnonArgFlag
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AnonArgFlag -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AnonArgFlag -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> AnonArgFlag -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> AnonArgFlag -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnonArgFlag -> r
    gmapT :: (forall b. Data b => b -> b) -> AnonArgFlag -> AnonArgFlag
    $cgmapT :: (forall b. Data b => b -> b) -> AnonArgFlag -> AnonArgFlag
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c AnonArgFlag)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c AnonArgFlag)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AnonArgFlag)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AnonArgFlag)
    dataTypeOf :: AnonArgFlag -> DataType
    $cdataTypeOf :: AnonArgFlag -> DataType
    toConstr :: AnonArgFlag -> Constr
    $ctoConstr :: AnonArgFlag -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AnonArgFlag
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AnonArgFlag
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnonArgFlag -> c AnonArgFlag
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnonArgFlag -> c AnonArgFlag
    Data)

    instance Outputable AnonArgFlag where
      ppr :: AnonArgFlag -> SDoc
    ppr AnonArgFlag
    VisArg   = String -> SDoc
    text String
    "[vis]"
      ppr AnonArgFlag
    InvisArg = String -> SDoc
    text String
    "[invis]"

    instance Binary AnonArgFlag where
      put_ :: BinHandle -> AnonArgFlag -> IO ()
    put_ BinHandle
    bh AnonArgFlag
    VisArg   = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    0
      put_ BinHandle
    bh AnonArgFlag
    InvisArg = BinHandle -> Word8 -> IO ()
    putByte BinHandle
    bh Word8
    1

      get :: BinHandle -> IO AnonArgFlag
    get BinHandle
    bh = do
        Word8
    h <- BinHandle -> IO Word8
    getByte BinHandle
    bh
        case Word8
    h of
          Word8
    0 -> AnonArgFlag -> IO AnonArgFlag
    forall (m :: * -> *) a. Monad m => a -> m a
    return AnonArgFlag
    VisArg
          Word8
    _ -> AnonArgFlag -> IO AnonArgFlag
    forall (m :: * -> *) a. Monad m => a -> m a
    return AnonArgFlag
    InvisArg

    {- Note [AnonArgFlag]
    ~~~~~~~~~~~~~~~~~~~~~
    AnonArgFlag is used principally in the FunTy constructor of Type.
      FunTy VisArg   t1 t2   means   t1 -> t2
      FunTy InvisArg t1 t2   means   t1 => t2

    However, the AnonArgFlag in a FunTy is just redundant, cached
    information.  In (FunTy { ft_af = af, ft_arg = t1, ft_res = t2 })
      * if (isPredTy t1 = True)  then af = InvisArg
      * if (isPredTy t1 = False) then af = VisArg
    where isPredTy is defined in GHC.Core.Type, and sees if t1's
    kind is Constraint.  See GHC.Core.TyCo.Rep
    Note [Types for coercions, predicates, and evidence]

    GHC.Core.Utils.mkFunctionType :: Mult -> Type -> Type -> Type
    uses isPredTy to decide the AnonArgFlag for the FunTy.

    The term (Lam b e), and coercion (FunCo co1 co2) don't carry
    AnonArgFlags; instead they use mkFunctionType when we want to
    get their types; see mkLamType and coercionLKind/RKind resp.
    This is just an engineering choice; we could cache here too
    if we wanted.

    Why bother with all this? After all, we are in Core, where (=>) and
    (->) behave the same.  We maintain this distinction throughout Core so
    that we can cheaply and conveniently determine
    * How to print a type
    * How to split up a type: tcSplitSigmaTy
    * How to specialise it (over type classes; GHC.Core.Opt.Specialise)

    For the specialisation point, consider
    (\ (d :: Ord a). blah).  We want to give it type
               (Ord a => blah_ty)
    with a fat arrow; that is, using mkInvisFunTy, not mkVisFunTy.
    Why?  Because the /specialiser/ treats dictionary arguments specially.
    Suppose we do w/w on 'foo', thus (#11272, #6056)
       foo :: Ord a => Int -> blah
       foo a d x = case x of I# x' -> $wfoo @a d x'

       $wfoo :: Ord a => Int# -> blah

    Now, at a call we see (foo @Int dOrdInt).  The specialiser will
    specialise this to $sfoo, where
       $sfoo :: Int -> blah
       $sfoo x = case x of I# x' -> $wfoo @Int dOrdInt x'

    Now we /must/ also specialise $wfoo!  But it wasn't user-written,
    and has a type built with mkLamTypes.

    Conclusion: the easiest thing is to make mkLamType build
                (c => ty)
    when the argument is a predicate type.  See GHC.Core.TyCo.Rep
    Note [Types for coercions, predicates, and evidence]
    -}

    {- *********************************************************************
    *                                                                      *
    *                   VarBndr, TyCoVarBinder
    *                                                                      *
    ********************************************************************* -}

    -- Variable Binder
    --
    -- VarBndr is polymorphic in both var and visibility fields.
    -- Currently there are nine different uses of 'VarBndr':
    --   * Var.TyVarBinder               = VarBndr TyVar ArgFlag
    --   * Var.TyCoVarBinder             = VarBndr TyCoVar ArgFlag
    --   * Var.InvisTVBinder             = VarBndr TyVar Specificity
    --   * Var.ReqTVBinder               = VarBndr TyVar ()
    --   * TyCon.TyConBinder             = VarBndr TyVar TyConBndrVis
    --   * TyCon.TyConTyCoBinder         = VarBndr TyCoVar TyConBndrVis
    --   * IfaceType.IfaceForAllBndr     = VarBndr IfaceBndr ArgFlag
    --   * IfaceType.IfaceTyConBinder    = VarBndr IfaceBndr TyConBndrVis
    --   * IfaceType.IfaceForAllSpecBndr = VarBndr IfaceBndr Specificity
    data VarBndr var argf = Bndr var argf
      deriving( Typeable (VarBndr var argf)
    Typeable (VarBndr var argf)
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g)
        -> VarBndr var argf
        -> c (VarBndr var argf))
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (VarBndr var argf))
    -> (VarBndr var argf -> Constr)
    -> (VarBndr var argf -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf)))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (VarBndr var argf)))
    -> ((forall b. Data b => b -> b)
        -> VarBndr var argf -> VarBndr var argf)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> VarBndr var argf -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> VarBndr var argf -> m (VarBndr var argf))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> VarBndr var argf -> m (VarBndr var argf))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> VarBndr var argf -> m (VarBndr var argf))
    -> Data (VarBndr var argf)
    VarBndr var argf -> DataType
    VarBndr var argf -> Constr
    (forall b. Data b => b -> b)
    -> VarBndr var argf -> VarBndr var argf
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u
    forall u. (forall d. Data d => d -> u) -> VarBndr var argf -> [u]
    forall {var} {argf}.
    (Data var, Data argf) =>
    Typeable (VarBndr var argf)
    forall var argf.
    (Data var, Data argf) =>
    VarBndr var argf -> DataType
    forall var argf.
    (Data var, Data argf) =>
    VarBndr var argf -> Constr
    forall var argf.
    (Data var, Data argf) =>
    (forall b. Data b => b -> b)
    -> VarBndr var argf -> VarBndr var argf
    forall var argf u.
    (Data var, Data argf) =>
    Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u
    forall var argf u.
    (Data var, Data argf) =>
    (forall d. Data d => d -> u) -> VarBndr var argf -> [u]
    forall var argf r r'.
    (Data var, Data argf) =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    forall var argf r r'.
    (Data var, Data argf) =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    forall var argf (m :: * -> *).
    (Data var, Data argf, Monad m) =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    forall var argf (m :: * -> *).
    (Data var, Data argf, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    forall var argf (c :: * -> *).
    (Data var, Data argf) =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (VarBndr var argf)
    forall var argf (c :: * -> *).
    (Data var, Data argf) =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> VarBndr var argf -> c (VarBndr var argf)
    forall var argf (t :: * -> *) (c :: * -> *).
    (Data var, Data argf, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf))
    forall var argf (t :: * -> * -> *) (c :: * -> *).
    (Data var, Data argf, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (VarBndr var argf))
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (VarBndr var argf)
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> VarBndr var argf -> c (VarBndr var argf)
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf))
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (VarBndr var argf))
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    $cgmapMo :: forall var argf (m :: * -> *).
    (Data var, Data argf, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    $cgmapMp :: forall var argf (m :: * -> *).
    (Data var, Data argf, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    $cgmapM :: forall var argf (m :: * -> *).
    (Data var, Data argf, Monad m) =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf)
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u
    $cgmapQi :: forall var argf u.
    (Data var, Data argf) =>
    Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> VarBndr var argf -> [u]
    $cgmapQ :: forall var argf u.
    (Data var, Data argf) =>
    (forall d. Data d => d -> u) -> VarBndr var argf -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    $cgmapQr :: forall var argf r r'.
    (Data var, Data argf) =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    $cgmapQl :: forall var argf r r'.
    (Data var, Data argf) =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
    gmapT :: (forall b. Data b => b -> b)
    -> VarBndr var argf -> VarBndr var argf
    $cgmapT :: forall var argf.
    (Data var, Data argf) =>
    (forall b. Data b => b -> b)
    -> VarBndr var argf -> VarBndr var argf
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (VarBndr var argf))
    $cdataCast2 :: forall var argf (t :: * -> * -> *) (c :: * -> *).
    (Data var, Data argf, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (VarBndr var argf))
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf))
    $cdataCast1 :: forall var argf (t :: * -> *) (c :: * -> *).
    (Data var, Data argf, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf))
    dataTypeOf :: VarBndr var argf -> DataType
    $cdataTypeOf :: forall var argf.
    (Data var, Data argf) =>
    VarBndr var argf -> DataType
    toConstr :: VarBndr var argf -> Constr
    $ctoConstr :: forall var argf.
    (Data var, Data argf) =>
    VarBndr var argf -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (VarBndr var argf)
    $cgunfold :: forall var argf (c :: * -> *).
    (Data var, Data argf) =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (VarBndr var argf)
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> VarBndr var argf -> c (VarBndr var argf)
    $cgfoldl :: forall var argf (c :: * -> *).
    (Data var, Data argf) =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> VarBndr var argf -> c (VarBndr var argf)
    Data )

    -- | Variable Binder
    --
    -- A 'TyCoVarBinder' is the binder of a ForAllTy
    -- It's convenient to define this synonym here rather its natural
    -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot
    --
    -- A 'TyVarBinder' is a binder with only TyVar
    type TyCoVarBinder     = VarBndr TyCoVar ArgFlag
    type TyVarBinder       = VarBndr TyVar   ArgFlag
    type InvisTVBinder     = VarBndr TyVar   Specificity
    type ReqTVBinder       = VarBndr TyVar   ()

    tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ArgFlag]
    tyVarSpecToBinders :: forall a. [VarBndr a Specificity] -> [VarBndr a ArgFlag]
    tyVarSpecToBinders = (VarBndr a Specificity -> VarBndr a ArgFlag)
    -> [VarBndr a Specificity] -> [VarBndr a ArgFlag]
    forall a b. (a -> b) -> [a] -> [b]
    map VarBndr a Specificity -> VarBndr a ArgFlag
    forall a. VarBndr a Specificity -> VarBndr a ArgFlag
    tyVarSpecToBinder

    tyVarSpecToBinder :: (VarBndr a Specificity) -> (VarBndr a ArgFlag)
    tyVarSpecToBinder :: forall a. VarBndr a Specificity -> VarBndr a ArgFlag
    tyVarSpecToBinder (Bndr a
    tv Specificity
    vis) = a -> ArgFlag -> VarBndr a ArgFlag
    forall var argf. var -> argf -> VarBndr var argf
    Bndr a
    tv (Specificity -> ArgFlag
    Invisible Specificity
    vis)

    binderVar :: VarBndr tv argf -> tv
    binderVar :: forall tv argf. VarBndr tv argf -> tv
    binderVar (Bndr tv
    v argf
    _) = tv
    v

    binderVars :: [VarBndr tv argf] -> [tv]
    binderVars :: forall tv argf. [VarBndr tv argf] -> [tv]
    binderVars [VarBndr tv argf]
    tvbs = (VarBndr tv argf -> tv) -> [VarBndr tv argf] -> [tv]
    forall a b. (a -> b) -> [a] -> [b]
    map VarBndr tv argf -> tv
    forall tv argf. VarBndr tv argf -> tv
    binderVar [VarBndr tv argf]
    tvbs

    binderArgFlag :: VarBndr tv argf -> argf
    binderArgFlag :: forall tv argf. VarBndr tv argf -> argf
    binderArgFlag (Bndr tv
    _ argf
    argf) = argf
    argf

    binderType :: VarBndr TyCoVar argf -> Type
    binderType :: forall argf. VarBndr Var argf -> Mult
    binderType (Bndr Var
    tv argf
    _) = Var -> Mult
    varType Var
    tv

    -- | Make a named binder
    mkTyCoVarBinder :: vis -> TyCoVar -> (VarBndr TyCoVar vis)
    mkTyCoVarBinder :: forall vis. vis -> Var -> VarBndr Var vis
    mkTyCoVarBinder vis
    vis Var
    var = Var -> vis -> VarBndr Var vis
    forall var argf. var -> argf -> VarBndr var argf
    Bndr Var
    var vis
    vis

    -- | Make a named binder
    -- 'var' should be a type variable
    mkTyVarBinder :: vis -> TyVar -> (VarBndr TyVar vis)
    mkTyVarBinder :: forall vis. vis -> Var -> VarBndr Var vis
    mkTyVarBinder vis
    vis Var
    var
      = ASSERT( isTyVar var )
        Var -> vis -> VarBndr Var vis
    forall var argf. var -> argf -> VarBndr var argf
    Bndr Var
    var vis
    vis

    -- | Make many named binders
    mkTyCoVarBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]
    mkTyCoVarBinders :: forall vis. vis -> [Var] -> [VarBndr Var vis]
    mkTyCoVarBinders vis
    vis = (Var -> VarBndr Var vis) -> [Var] -> [VarBndr Var vis]
    forall a b. (a -> b) -> [a] -> [b]
    map (vis -> Var -> VarBndr Var vis
    forall vis. vis -> Var -> VarBndr Var vis
    mkTyCoVarBinder vis
    vis)

    -- | Make many named binders
    -- Input vars should be type variables
    mkTyVarBinders :: vis -> [TyVar] -> [VarBndr TyVar vis]
    mkTyVarBinders :: forall vis. vis -> [Var] -> [VarBndr Var vis]
    mkTyVarBinders vis
    vis = (Var -> VarBndr Var vis) -> [Var] -> [VarBndr Var vis]
    forall a b. (a -> b) -> [a] -> [b]
    map (vis -> Var -> VarBndr Var vis
    forall vis. vis -> Var -> VarBndr Var vis
    mkTyVarBinder vis
    vis)

    isTyVarBinder :: TyCoVarBinder -> Bool
    isTyVarBinder :: TyCoVarBinder -> Bool
    isTyVarBinder (Bndr Var
    v ArgFlag
    _) = Var -> Bool
    isTyVar Var
    v

    mapVarBndr :: (var -> var') -> (VarBndr var flag) -> (VarBndr var' flag)
    mapVarBndr :: forall var var' flag.
    (var -> var') -> VarBndr var flag -> VarBndr var' flag
    mapVarBndr var -> var'
    f (Bndr var
    v flag
    fl) = var' -> flag -> VarBndr var' flag
    forall var argf. var -> argf -> VarBndr var argf
    Bndr (var -> var'
    f var
    v) flag
    fl

    mapVarBndrs :: (var -> var') -> [VarBndr var flag] -> [VarBndr var' flag]
    mapVarBndrs :: forall var var' flag.
    (var -> var') -> [VarBndr var flag] -> [VarBndr var' flag]
    mapVarBndrs var -> var'
    f = (VarBndr var flag -> VarBndr var' flag)
    -> [VarBndr var flag] -> [VarBndr var' flag]
    forall a b. (a -> b) -> [a] -> [b]
    map ((var -> var') -> VarBndr var flag -> VarBndr var' flag
    forall var var' flag.
    (var -> var') -> VarBndr var flag -> VarBndr var' flag
    mapVarBndr var -> var'
    f)

    lookupVarBndr :: Eq var => var -> [VarBndr var flag] -> Maybe flag
    lookupVarBndr :: forall var flag. Eq var => var -> [VarBndr var flag] -> Maybe flag
    lookupVarBndr var
    var [VarBndr var flag]
    bndrs = var -> [(var, flag)] -> Maybe flag
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup var
    var [(var, flag)]
    zipped_bndrs
      where
        zipped_bndrs :: [(var, flag)]
    zipped_bndrs = (VarBndr var flag -> (var, flag))
    -> [VarBndr var flag] -> [(var, flag)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Bndr var
    v flag
    f) -> (var
    v,flag
    f)) [VarBndr var flag]
    bndrs

    instance Outputable tv => Outputable (VarBndr tv ArgFlag) where
      ppr :: VarBndr tv ArgFlag -> SDoc
    ppr (Bndr tv
    v ArgFlag
    Required)  = tv -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr tv
    v
      ppr (Bndr tv
    v ArgFlag
    Specified) = Char -> SDoc
    char Char
    '@' SDoc -> SDoc -> SDoc
    <> tv -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr tv
    v
      ppr (Bndr tv
    v ArgFlag
    Inferred)  = SDoc -> SDoc
    braces (tv -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr tv
    v)

    instance Outputable tv => Outputable (VarBndr tv Specificity) where
      ppr :: VarBndr tv Specificity -> SDoc
    ppr = VarBndr tv ArgFlag -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (VarBndr tv ArgFlag -> SDoc)
    -> (VarBndr tv Specificity -> VarBndr tv ArgFlag)
    -> VarBndr tv Specificity
    -> SDoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . VarBndr tv Specificity -> VarBndr tv ArgFlag
    forall a. VarBndr a Specificity -> VarBndr a ArgFlag
    tyVarSpecToBinder

    instance (Binary tv, Binary vis) => Binary (VarBndr tv vis) where
      put_ :: BinHandle -> VarBndr tv vis -> IO ()
    put_ BinHandle
    bh (Bndr tv
    tv vis
    vis) = do { BinHandle -> tv -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh tv
    tv; BinHandle -> vis -> IO ()
    forall a. Binary a => BinHandle -> a -> IO ()
    put_ BinHandle
    bh vis
    vis }

      get :: BinHandle -> IO (VarBndr tv vis)
    get BinHandle
    bh = do { tv
    tv <- BinHandle -> IO tv
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh; vis
    vis <- BinHandle -> IO vis
    forall a. Binary a => BinHandle -> IO a
    get BinHandle
    bh; VarBndr tv vis -> IO (VarBndr tv vis)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (tv -> vis -> VarBndr tv vis
    forall var argf. var -> argf -> VarBndr var argf
    Bndr tv
    tv vis
    vis) }

    instance NamedThing tv => NamedThing (VarBndr tv flag) where
      getName :: VarBndr tv flag -> Name
    getName (Bndr tv
    tv flag
    _) = tv -> Name
    forall a. NamedThing a => a -> Name
    getName tv
    tv

    {-
    ************************************************************************
    *                                                                      *
    *                 Type and kind variables                              *
    *                                                                      *
    ************************************************************************
    -}

    tyVarName :: TyVar -> Name
    tyVarName :: Var -> Name
    tyVarName = Var -> Name
    varName

    tyVarKind :: TyVar -> Kind
    tyVarKind :: Var -> Mult
    tyVarKind = Var -> Mult
    varType

    setTyVarUnique :: TyVar -> Unique -> TyVar
    setTyVarUnique :: Var -> Unique -> Var
    setTyVarUnique = Var -> Unique -> Var
    setVarUnique

    setTyVarName :: TyVar -> Name -> TyVar
    setTyVarName :: Var -> Name -> Var
    setTyVarName   = Var -> Name -> Var
    setVarName

    setTyVarKind :: TyVar -> Kind -> TyVar
    setTyVarKind :: Var -> Mult -> Var
    setTyVarKind Var
    tv Mult
    k = Var
    tv {varType :: Mult
    varType = Mult
    k}

    updateTyVarKind :: (Kind -> Kind) -> TyVar -> TyVar
    updateTyVarKind :: (Mult -> Mult) -> Var -> Var
    updateTyVarKind Mult -> Mult
    update Var
    tv = Var
    tv {varType :: Mult
    varType = Mult -> Mult
    update (Var -> Mult
    tyVarKind Var
    tv)}

    updateTyVarKindM :: (Monad m) => (Kind -> m Kind) -> TyVar -> m TyVar
    updateTyVarKindM :: forall (m :: * -> *). Monad m => (Mult -> m Mult) -> Var -> m Var
    updateTyVarKindM Mult -> m Mult
    update Var
    tv
      = do { Mult
    k' <- Mult -> m Mult
    update (Var -> Mult
    tyVarKind Var
    tv)
           ; Var -> m Var
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Var -> m Var) -> Var -> m Var
    forall a b. (a -> b) -> a -> b
    $ Var
    tv {varType :: Mult
    varType = Mult
    k'} }

    mkTyVar :: Name -> Kind -> TyVar
    mkTyVar :: Name -> Mult -> Var
    mkTyVar Name
    name Mult
    kind = TyVar :: Name -> Int -> Mult -> Var
    TyVar { varName :: Name
    varName    = Name
    name
                              , realUnique :: Int
    realUnique = Unique -> Int
    getKey (Name -> Unique
    nameUnique Name
    name)
                              , varType :: Mult
    varType  = Mult
    kind
                              }

    mkTcTyVar :: Name -> Kind -> TcTyVarDetails -> TyVar
    mkTcTyVar :: Name -> Mult -> TcTyVarDetails -> Var
    mkTcTyVar Name
    name Mult
    kind TcTyVarDetails
    details
      = -- NB: 'kind' may be a coercion kind; cf, 'GHC.Tc.Utils.TcMType.newMetaCoVar'
        TcTyVar :: Name -> Int -> Mult -> TcTyVarDetails -> Var
    TcTyVar {   varName :: Name
    varName    = Name
    name,
                    realUnique :: Int
    realUnique = Unique -> Int
    getKey (Name -> Unique
    nameUnique Name
    name),
                    varType :: Mult
    varType  = Mult
    kind,
                    tc_tv_details :: TcTyVarDetails
    tc_tv_details = TcTyVarDetails
    details
            }

    tcTyVarDetails :: TyVar -> TcTyVarDetails
    -- See Note [TcTyVars in the typechecker] in GHC.Tc.Utils.TcType
    tcTyVarDetails :: Var -> TcTyVarDetails
    tcTyVarDetails (TcTyVar { tc_tv_details :: Var -> TcTyVarDetails
    tc_tv_details = TcTyVarDetails
    details }) = TcTyVarDetails
    details
    tcTyVarDetails (TyVar {})                            = TcTyVarDetails
    vanillaSkolemTv
    tcTyVarDetails Var
    var = String -> SDoc -> TcTyVarDetails
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "tcTyVarDetails" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    var SDoc -> SDoc -> SDoc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    <+> Mult -> SDoc
    pprKind (Var -> Mult
    tyVarKind Var
    var))

    setTcTyVarDetails :: TyVar -> TcTyVarDetails -> TyVar
    setTcTyVarDetails :: Var -> TcTyVarDetails -> Var
    setTcTyVarDetails Var
    tv TcTyVarDetails
    details = Var
    tv { tc_tv_details :: TcTyVarDetails
    tc_tv_details = TcTyVarDetails
    details }

    {-
    %************************************************************************
    %*                                                                      *
    \subsection{Ids}
    *                                                                      *
    ************************************************************************
    -}

    idInfo :: HasDebugCallStack => Id -> IdInfo
    idInfo :: HasDebugCallStack => Var -> IdInfo
    idInfo (Id { id_info :: Var -> IdInfo
    id_info = IdInfo
    info }) = IdInfo
    info
    idInfo Var
    other                   = String -> SDoc -> IdInfo
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "idInfo" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    other)

    idDetails :: Id -> IdDetails
    idDetails :: Var -> IdDetails
    idDetails (Id { id_details :: Var -> IdDetails
    id_details = IdDetails
    details }) = IdDetails
    details
    idDetails Var
    other                         = String -> SDoc -> IdDetails
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "idDetails" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    other)

    -- The next three have a 'Var' suffix even though they always build
    -- Ids, because "GHC.Types.Id" uses 'mkGlobalId' etc with different types
    mkGlobalVar :: IdDetails -> Name -> Type -> IdInfo -> Id
    mkGlobalVar :: IdDetails -> Name -> Mult -> IdInfo -> Var
    mkGlobalVar IdDetails
    details Name
    name Mult
    ty IdInfo
    info
      = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Var
    mk_id Name
    name Mult
    manyDataConTy Mult
    ty IdScope
    GlobalId IdDetails
    details IdInfo
    info
      -- There is no support for linear global variables yet. They would require
      -- being checked at link-time, which can be useful, but is not a priority.

    mkLocalVar :: IdDetails -> Name -> Mult -> Type -> IdInfo -> Id
    mkLocalVar :: IdDetails -> Name -> Mult -> Mult -> IdInfo -> Var
    mkLocalVar IdDetails
    details Name
    name Mult
    w Mult
    ty IdInfo
    info
      = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Var
    mk_id Name
    name Mult
    w Mult
    ty (ExportFlag -> IdScope
    LocalId ExportFlag
    NotExported) IdDetails
    details  IdInfo
    info

    mkCoVar :: Name -> Type -> CoVar
    -- Coercion variables have no IdInfo
    mkCoVar :: Name -> Mult -> Var
    mkCoVar Name
    name Mult
    ty = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Var
    mk_id Name
    name Mult
    manyDataConTy Mult
    ty (ExportFlag -> IdScope
    LocalId ExportFlag
    NotExported) IdDetails
    coVarDetails IdInfo
    vanillaIdInfo

    -- | Exported 'Var's will not be removed as dead code
    mkExportedLocalVar :: IdDetails -> Name -> Type -> IdInfo -> Id
    mkExportedLocalVar :: IdDetails -> Name -> Mult -> IdInfo -> Var
    mkExportedLocalVar IdDetails
    details Name
    name Mult
    ty IdInfo
    info
      = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Var
    mk_id Name
    name Mult
    manyDataConTy Mult
    ty (ExportFlag -> IdScope
    LocalId ExportFlag
    Exported) IdDetails
    details IdInfo
    info
      -- There is no support for exporting linear variables. See also [mkGlobalVar]

    mk_id :: Name -> Mult -> Type -> IdScope -> IdDetails -> IdInfo -> Id
    mk_id :: Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Var
    mk_id Name
    name !Mult
    w Mult
    ty IdScope
    scope IdDetails
    details IdInfo
    info
      = Id :: Name
    -> Int -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Var
    Id { varName :: Name
    varName    = Name
    name,
             realUnique :: Int
    realUnique = Unique -> Int
    getKey (Name -> Unique
    nameUnique Name
    name),
             varMult :: Mult
    varMult    = Mult
    w,
             varType :: Mult
    varType    = Mult
    ty,
             idScope :: IdScope
    idScope    = IdScope
    scope,
             id_details :: IdDetails
    id_details = IdDetails
    details,
             id_info :: IdInfo
    id_info    = IdInfo
    info }

    -------------------
    lazySetIdInfo :: Id -> IdInfo -> Var
    lazySetIdInfo :: Var -> IdInfo -> Var
    lazySetIdInfo Var
    id IdInfo
    info = Var
    id { id_info :: IdInfo
    id_info = IdInfo
    info }

    setIdDetails :: Id -> IdDetails -> Id
    setIdDetails :: Var -> IdDetails -> Var
    setIdDetails Var
    id IdDetails
    details = Var
    id { id_details :: IdDetails
    id_details = IdDetails
    details }

    globaliseId :: Id -> Id
    -- ^ If it's a local, make it global
    globaliseId :: Var -> Var
    globaliseId Var
    id = Var
    id { idScope :: IdScope
    idScope = IdScope
    GlobalId }

    setIdExported :: Id -> Id
    -- ^ Exports the given local 'Id'. Can also be called on global 'Id's, such as data constructors
    -- and class operations, which are born as global 'Id's and automatically exported
    setIdExported :: Var -> Var
    setIdExported id :: Var
    id@(Id { idScope :: Var -> IdScope
    idScope = LocalId {} }) = Var
    id { idScope :: IdScope
    idScope = ExportFlag -> IdScope
    LocalId ExportFlag
    Exported }
    setIdExported id :: Var
    id@(Id { idScope :: Var -> IdScope
    idScope = IdScope
    GlobalId })   = Var
    id
    setIdExported Var
    tv                               = String -> SDoc -> Var
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "setIdExported" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    tv)

    setIdNotExported :: Id -> Id
    -- ^ We can only do this to LocalIds
    setIdNotExported :: Var -> Var
    setIdNotExported Var
    id = ASSERT( isLocalId id )
                          Var
    id { idScope :: IdScope
    idScope = ExportFlag -> IdScope
    LocalId ExportFlag
    NotExported }

    -----------------------
    updateIdTypeButNotMult :: (Type -> Type) -> Id -> Id
    updateIdTypeButNotMult :: (Mult -> Mult) -> Var -> Var
    updateIdTypeButNotMult Mult -> Mult
    f Var
    id = Var
    id { varType :: Mult
    varType = Mult -> Mult
    f (Var -> Mult
    varType Var
    id) }

    updateIdTypeAndMult :: (Type -> Type) -> Id -> Id
    updateIdTypeAndMult :: (Mult -> Mult) -> Var -> Var
    updateIdTypeAndMult Mult -> Mult
    f id :: Var
    id@(Id { varType :: Var -> Mult
    varType = Mult
    ty
                                 , varMult :: Var -> Mult
    varMult = Mult
    mult })
      = Var
    id { varType :: Mult
    varType = Mult
    ty'
           , varMult :: Mult
    varMult = Mult
    mult' }
      where
        !ty' :: Mult
    ty'   = Mult -> Mult
    f Mult
    ty
        !mult' :: Mult
    mult' = Mult -> Mult
    f Mult
    mult
    updateIdTypeAndMult Mult -> Mult
    _ Var
    other = String -> SDoc -> Var
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "updateIdTypeAndMult" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    other)

    updateIdTypeAndMultM :: Monad m => (Type -> m Type) -> Id -> m Id
    updateIdTypeAndMultM :: forall (m :: * -> *). Monad m => (Mult -> m Mult) -> Var -> m Var
    updateIdTypeAndMultM Mult -> m Mult
    f id :: Var
    id@(Id { varType :: Var -> Mult
    varType = Mult
    ty
                                  , varMult :: Var -> Mult
    varMult = Mult
    mult })
      = do { !Mult
    ty' <- Mult -> m Mult
    f Mult
    ty
           ; !Mult
    mult' <- Mult -> m Mult
    f Mult
    mult
           ; Var -> m Var
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Var
    id { varType :: Mult
    varType = Mult
    ty', varMult :: Mult
    varMult = Mult
    mult' }) }
    updateIdTypeAndMultM Mult -> m Mult
    _ Var
    other = String -> SDoc -> m Var
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "updateIdTypeAndMultM" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    other)

    setIdMult :: Id -> Mult -> Id
    setIdMult :: Var -> Mult -> Var
    setIdMult Var
    id !Mult
    r | Var -> Bool
    isId Var
    id = Var
    id { varMult :: Mult
    varMult = Mult
    r }
                    | Bool
    otherwise = String -> SDoc -> Var
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "setIdMult" (Var -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Var
    id SDoc -> SDoc -> SDoc
    <+> Mult -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Mult
    r)

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Predicates over variables}
    *                                                                      *
    ************************************************************************
    -}

    -- | Is this a type-level (i.e., computationally irrelevant, thus erasable)
    -- variable? Satisfies @isTyVar = not . isId@.
    isTyVar :: Var -> Bool        -- True of both TyVar and TcTyVar
    isTyVar :: Var -> Bool
    isTyVar (TyVar {})   = Bool
    True
    isTyVar (TcTyVar {}) = Bool
    True
    isTyVar Var
    _            = Bool
    False

    isTcTyVar :: Var -> Bool      -- True of TcTyVar only
    isTcTyVar :: Var -> Bool
    isTcTyVar (TcTyVar {}) = Bool
    True
    isTcTyVar Var
    _            = Bool
    False

    isTyCoVar :: Var -> Bool
    isTyCoVar :: Var -> Bool
    isTyCoVar Var
    v = Var -> Bool
    isTyVar Var
    v Bool -> Bool -> Bool
    || Var -> Bool
    isCoVar Var
    v

    -- | Is this a value-level (i.e., computationally relevant) 'Id'entifier?
    -- Satisfies @isId = not . isTyVar@.
    isId :: Var -> Bool
    isId :: Var -> Bool
    isId (Id {}) = Bool
    True
    isId Var
    _       = Bool
    False

    -- | Is this a coercion variable?
    -- Satisfies @'isId' v ==> 'isCoVar' v == not ('isNonCoVarId' v)@.
    isCoVar :: Var -> Bool
    isCoVar :: Var -> Bool
    isCoVar (Id { id_details :: Var -> IdDetails
    id_details = IdDetails
    details }) = IdDetails -> Bool
    isCoVarDetails IdDetails
    details
    isCoVar Var
    _                             = Bool
    False

    -- | Is this a term variable ('Id') that is /not/ a coercion variable?
    -- Satisfies @'isId' v ==> 'isCoVar' v == not ('isNonCoVarId' v)@.
    isNonCoVarId :: Var -> Bool
    isNonCoVarId :: Var -> Bool
    isNonCoVarId (Id { id_details :: Var -> IdDetails
    id_details = IdDetails
    details }) = Bool -> Bool
    not (IdDetails -> Bool
    isCoVarDetails IdDetails
    details)
    isNonCoVarId Var
    _                             = Bool
    False

    isLocalId :: Var -> Bool
    isLocalId :: Var -> Bool
    isLocalId (Id { idScope :: Var -> IdScope
    idScope = LocalId ExportFlag
    _ }) = Bool
    True
    isLocalId Var
    _                            = Bool
    False

    -- | 'isLocalVar' returns @True@ for type variables as well as local 'Id's
    -- These are the variables that we need to pay attention to when finding free
    -- variables, or doing dependency analysis.
    isLocalVar :: Var -> Bool
    isLocalVar :: Var -> Bool
    isLocalVar Var
    v = Bool -> Bool
    not (Var -> Bool
    isGlobalId Var
    v)

    isGlobalId :: Var -> Bool
    isGlobalId :: Var -> Bool
    isGlobalId (Id { idScope :: Var -> IdScope
    idScope = IdScope
    GlobalId }) = Bool
    True
    isGlobalId Var
    _                           = Bool
    False

    -- | 'mustHaveLocalBinding' returns @True@ of 'Id's and 'TyVar's
    -- that must have a binding in this module.  The converse
    -- is not quite right: there are some global 'Id's that must have
    -- bindings, such as record selectors.  But that doesn't matter,
    -- because it's only used for assertions
    mustHaveLocalBinding        :: Var -> Bool
    mustHaveLocalBinding :: Var -> Bool
    mustHaveLocalBinding Var
    var = Var -> Bool
    isLocalVar Var
    var

    -- | 'isExportedIdVar' means \"don't throw this away\"
    isExportedId :: Var -> Bool
    isExportedId :: Var -> Bool
    isExportedId (Id { idScope :: Var -> IdScope
    idScope = IdScope
    GlobalId })        = Bool
    True
    isExportedId (Id { idScope :: Var -> IdScope
    idScope = LocalId ExportFlag
    Exported}) = Bool
    True
    isExportedId Var
    _ = Bool
    False