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

\section{@Vars@: Variables}
-}

{-# LANGUAGE 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),
        AnonArgFlag(..), Specificity(..),
        isVisibleArgFlag, isInvisibleArgFlag, isInferredArgFlag,
        sameVis,

        -- * TyVar's
        VarBndr(..), TyCoVarBinder, TyVarBinder, InvisTVBinder, ReqTVBinder,
        binderVar, binderVars, binderArgFlag, binderType,
        mkTyCoVarBinder, mkTyCoVarBinders,
        mkTyVarBinder, mkTyVarBinders,
        isTyVarBinder,
        tyVarSpecToBinder, tyVarSpecToBinders, tyVarReqToBinder, tyVarReqToBinders,
        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

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, vanillaSkolemTvUnk )
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 GHC.Utils.Panic
import GHC.Utils.Panic.Plain

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 = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressVarKinds forall a b. (a -> b) -> a -> b
$ \Bool
supp_var_kinds ->
            (Bool -> SDoc) -> SDoc
getPprDebug forall a b. (a -> b) -> a -> b
$ \Bool
debug ->
            (PprStyle -> SDoc) -> SDoc
getPprStyle 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 (forall a. Outputable a => a -> SDoc
ppr (Var -> Name
varName Var
var) SDoc -> SDoc -> 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
                 -> 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 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 forall a. Ord a => a -> a -> Bool
<= Var -> Int
realUnique Var
b
    Var
a < :: Var -> Var -> Bool
<  Var
b = Var -> Int
realUnique Var
a forall a. Ord a => a -> a -> Bool
<  Var -> Int
realUnique Var
b
    Var
a >= :: Var -> Var -> Bool
>= Var
b = Var -> Int
realUnique Var
a forall a. Ord a => a -> a -> Bool
>= Var -> Int
realUnique Var
b
    Var
a > :: Var -> Var -> Bool
>  Var
b = Var -> Int
realUnique Var
a 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
_  = 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 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 }) = forall a. a -> Maybe a
Just Mult
mult
varMultMaybe Var
_ = 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 (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
  = case Var
var of
      Id { id_details :: Var -> IdDetails
id_details = IdDetails
details } -> forall a. HasCallStack => Bool -> a -> a
assert (IdDetails -> Bool
isCoVarDetails IdDetails
details) forall a b. (a -> b) -> a -> b
$
                                     Var
result
      Var
_ -> 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
  = case Var
var of
      Id { id_details :: Var -> IdDetails
id_details = IdDetails
details } -> forall a. HasCallStack => Bool -> a -> a
assert (IdDetails -> Bool
isCoVarDetails IdDetails
details) forall a b. (a -> b) -> a -> b
$
                                     m Var
result
      Var
_ -> m Var
result
  where
    result :: m Var
result = do { Mult
ty' <- Mult -> m Mult
upd (Var -> Mult
varType Var
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
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
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
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
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
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
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 $bInferred :: ArgFlag
$mInferred :: forall {r}. ArgFlag -> ((# #) -> r) -> ((# #) -> r) -> r
Inferred  = Invisible InferredSpec
pattern $bSpecified :: ArgFlag
$mSpecified :: forall {r}. ArgFlag -> ((# #) -> r) -> ((# #) -> r) -> r
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
af = Bool -> Bool
not (ArgFlag -> Bool
isInvisibleArgFlag ArgFlag
af)

-- | Does this 'ArgFlag' classify an argument that is not written in Haskell?
isInvisibleArgFlag :: ArgFlag -> Bool
isInvisibleArgFlag :: ArgFlag -> Bool
isInvisibleArgFlag (Invisible {}) = Bool
True
isInvisibleArgFlag ArgFlag
Required       = Bool
False

isInferredArgFlag :: ArgFlag -> Bool
-- More restrictive than isInvisibleArgFlag
isInferredArgFlag :: ArgFlag -> Bool
isInferredArgFlag (Invisible Specificity
InferredSpec) = Bool
True
isInferredArgFlag ArgFlag
_                        = Bool
False

-- | 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 -> forall (m :: * -> *) a. Monad m => a -> m a
return Specificity
SpecifiedSpec
      Word8
_ -> 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 -> forall (m :: * -> *) a. Monad m => a -> m a
return ArgFlag
Required
      Word8
1 -> forall (m :: * -> *) a. Monad m => a -> m a
return ArgFlag
Specified
      Word8
_ -> 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
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
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
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 -> forall (m :: * -> *) a. Monad m => a -> m a
return AnonArgFlag
VisArg
      Word8
_ -> 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
*                                                                      *
********************************************************************* -}

{- Note [The VarBndr type and its uses]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VarBndr is polymorphic in both var and visibility fields.
Currently there are nine different uses of 'VarBndr':

* Var.TyCoVarBinder = VarBndr TyCoVar ArgFlag
  Binder of a forall-type; see ForAllTy in GHC.Core.TyCo.Rep

* Var.TyVarBinder = VarBndr TyVar ArgFlag
  Subset of TyCoVarBinder when we are sure the binder is a TyVar

* Var.InvisTVBinder = VarBndr TyVar Specificity
  Specialised form of TyVarBinder, when ArgFlag = Invisible s
  See GHC.Core.Type.splitForAllInvisTVBinders

* Var.ReqTVBinder = VarBndr TyVar ()
  Specialised form of TyVarBinder, when ArgFlag = Required
  See GHC.Core.Type.splitForAllReqTVBinders
  This one is barely used

* TyCon.TyConBinder = VarBndr TyVar TyConBndrVis
  Binders of a TyCon; see TyCon in GHC.Core.TyCon

* TyCon.TyConTyCoBinder = VarBndr TyCoVar TyConBndrVis
  Binders of a PromotedDataCon
  See Note [Promoted GADT data constructors] in GHC.Core.TyCon

* IfaceType.IfaceForAllBndr     = VarBndr IfaceBndr ArgFlag
* IfaceType.IfaceForAllSpecBndr = VarBndr IfaceBndr Specificity
* IfaceType.IfaceTyConBinder    = VarBndr IfaceBndr TyConBndrVis
-}

data VarBndr var argf = Bndr var argf
  -- See Note [The VarBndr type and its uses]
  deriving( VarBndr var argf -> DataType
VarBndr var argf -> Constr
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 {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 (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 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 = forall a b. (a -> b) -> [a] -> [b]
map 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) = forall var argf. var -> argf -> VarBndr var argf
Bndr a
tv (Specificity -> ArgFlag
Invisible Specificity
vis)

tyVarReqToBinders :: [VarBndr a ()] -> [VarBndr a ArgFlag]
tyVarReqToBinders :: forall a. [VarBndr a ()] -> [VarBndr a ArgFlag]
tyVarReqToBinders = forall a b. (a -> b) -> [a] -> [b]
map forall a. VarBndr a () -> VarBndr a ArgFlag
tyVarReqToBinder

tyVarReqToBinder :: VarBndr a () -> VarBndr a ArgFlag
tyVarReqToBinder :: forall a. VarBndr a () -> VarBndr a ArgFlag
tyVarReqToBinder (Bndr a
tv ()
_) = forall var argf. var -> argf -> VarBndr var argf
Bndr a
tv ArgFlag
Required

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 = forall a b. (a -> b) -> [a] -> [b]
map 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 = 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
  = forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
var) forall a b. (a -> b) -> a -> b
$
    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 = forall a b. (a -> b) -> [a] -> [b]
map (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 = forall a b. (a -> b) -> [a] -> [b]
map (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) = 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 = forall a b. (a -> b) -> [a] -> [b]
map (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 = forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup var
var [(var, flag)]
zipped_bndrs
  where
    zipped_bndrs :: [(var, flag)]
zipped_bndrs = 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)  = forall a. Outputable a => a -> SDoc
ppr tv
v
  ppr (Bndr tv
v ArgFlag
Specified) = Char -> SDoc
char Char
'@' SDoc -> SDoc -> SDoc
<> forall a. Outputable a => a -> SDoc
ppr tv
v
  ppr (Bndr tv
v ArgFlag
Inferred)  = SDoc -> SDoc
braces (forall a. Outputable a => a -> SDoc
ppr tv
v)

instance Outputable tv => Outputable (VarBndr tv Specificity) where
  ppr :: VarBndr tv Specificity -> SDoc
ppr = forall a. Outputable a => a -> SDoc
ppr forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 { forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh tv
tv; forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh vis
vis }

  get :: BinHandle -> IO (VarBndr tv vis)
get BinHandle
bh = do { tv
tv <- forall a. Binary a => BinHandle -> IO a
get BinHandle
bh; vis
vis <- forall a. Binary a => BinHandle -> IO a
get BinHandle
bh; forall (m :: * -> *) a. Monad m => a -> m a
return (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
_) = 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)
       ; forall (m :: * -> *) a. Monad m => a -> m a
return 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 { 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 {   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 and TyVars 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
-- MP: This should never happen, but it does. Future work is to turn this into a panic.
tcTyVarDetails (TyVar {})                            = HasCallStack => TcTyVarDetails
vanillaSkolemTvUnk
tcTyVarDetails Var
var = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"tcTyVarDetails" (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                   = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"idInfo" (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                         = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"idDetails" (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 { 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                               = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"setIdExported" (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 = forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isLocalId Var
id) forall a b. (a -> b) -> a -> b
$
                      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 = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"updateIdTypeAndMult" (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
       ; 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 = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"updateIdTypeAndMultM" (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 = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"setIdMult" (forall a. Outputable a => a -> SDoc
ppr Var
id SDoc -> SDoc -> 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