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

\section{@Vars@: Variables}
-}

{-# LANGUAGE CPP, FlexibleContexts, MultiWayIf, FlexibleInstances, DeriveDataTypeable #-}

-- |
-- #name_types#
-- GHC uses several kinds of name internally:
--
-- * 'OccName.OccName': see "OccName#name_types"
--
-- * 'RdrName.RdrName': see "RdrName#name_types"
--
-- * 'Name.Name': see "Name#name_types"
--
-- * 'Id.Id': see "Id#name_types"
--
-- * 'Var.Var' is a synonym for the 'Id.Id' type but it may additionally
--   potentially contain type variables, which have a 'TyCoRep.Kind'
--   rather than a 'TyCoRep.Type' and only contain some extra
--   details during typechecking.
--
--   These 'Var.Var' names may either be global or local, see "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 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,

        -- ** 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,

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

        -- * TyVar's
        VarBndr(..), ArgFlag(..), TyCoVarBinder, TyVarBinder,
        binderVar, binderVars, binderArgFlag, binderType,
        isVisibleArgFlag, isInvisibleArgFlag, sameVis,
        mkTyCoVarBinder, mkTyCoVarBinders,
        mkTyVarBinder, mkTyVarBinders,
        isTyVarBinder,

        -- ** 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 GhcPrelude

import {-# SOURCE #-}   TyCoRep( Type, Kind, pprKind )
import {-# SOURCE #-}   TcType( TcTyVarDetails, pprTcTyVarDetails, vanillaSkolemTv )
import {-# SOURCE #-}   IdInfo( IdDetails, IdInfo, coVarDetails, isCoVarDetails,
                                vanillaIdInfo, pprIdDetails )

import Name hiding (varName)
import Unique ( Uniquable, Unique, getKey, getUnique
              , mkUniqueGrimily, nonDetCmpUnique )
import Util
import Binary
import DynFlags
import 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 Id.hs :-(
-}

-- | 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 -> Kind
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 -> 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
-}

instance Outputable Var where
  ppr :: Var -> SDoc
ppr var :: Var
var = (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags ((DynFlags -> SDoc) -> SDoc) -> (DynFlags -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \dflags :: DynFlags
dflags ->
            (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \ppr_style :: PprStyle
ppr_style ->
            if |  PprStyle -> Bool
debugStyle PprStyle
ppr_style Bool -> Bool -> Bool
&& (Bool -> Bool
not (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_SuppressVarKinds DynFlags
dflags))
                 -> SDoc -> SDoc
parens (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> Name
varName Var
var) SDoc -> SDoc -> SDoc
<+> Var -> PprStyle -> SDoc
ppr_debug Var
var PprStyle
ppr_style SDoc -> SDoc -> SDoc
<+>
                          SDoc
dcolon SDoc -> SDoc -> SDoc
<+> Kind -> SDoc
pprKind (Var -> Kind
tyVarKind Var
var))
               |  Bool
otherwise
                 -> Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> Name
varName Var
var) SDoc -> SDoc -> SDoc
<> Var -> PprStyle -> SDoc
ppr_debug Var
var PprStyle
ppr_style

ppr_debug :: Var -> PprStyle -> SDoc
ppr_debug :: Var -> PprStyle -> SDoc
ppr_debug (TyVar {}) sty :: PprStyle
sty
  | PprStyle -> Bool
debugStyle PprStyle
sty = SDoc -> SDoc
brackets (String -> SDoc
text "tv")
ppr_debug (TcTyVar {tc_tv_details :: Var -> TcTyVarDetails
tc_tv_details = TcTyVarDetails
d}) sty :: PprStyle
sty
  | PprStyle -> Bool
dumpStyle PprStyle
sty Bool -> Bool -> Bool
|| PprStyle -> Bool
debugStyle PprStyle
sty = SDoc -> SDoc
brackets (TcTyVarDetails -> SDoc
pprTcTyVarDetails TcTyVarDetails
d)
ppr_debug (Id { idScope :: Var -> IdScope
idScope = IdScope
s, id_details :: Var -> IdDetails
id_details = IdDetails
d }) sty :: PprStyle
sty
  | PprStyle -> Bool
debugStyle PprStyle
sty = SDoc -> SDoc
brackets (IdScope -> SDoc
ppr_id_scope IdScope
s SDoc -> SDoc -> SDoc
<> IdDetails -> SDoc
pprIdDetails IdDetails
d)
ppr_debug _ _ = SDoc
empty

ppr_id_scope :: IdScope -> SDoc
ppr_id_scope :: IdScope -> SDoc
ppr_id_scope GlobalId              = String -> SDoc
text "gid"
ppr_id_scope (LocalId Exported)    = String -> SDoc
text "lidx"
ppr_id_scope (LocalId NotExported) = String -> SDoc
text "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
    a :: Var
a == :: Var -> Var -> Bool
== b :: 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
    a :: Var
a <= :: Var -> Var -> Bool
<= b :: Var
b = Var -> Int
realUnique Var
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Var -> Int
realUnique Var
b
    a :: Var
a < :: Var -> Var -> Bool
<  b :: Var
b = Var -> Int
realUnique Var
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<  Var -> Int
realUnique Var
b
    a :: Var
a >= :: Var -> Var -> Bool
>= b :: Var
b = Var -> Int
realUnique Var
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Var -> Int
realUnique Var
b
    a :: Var
a > :: Var -> Var -> Bool
>  b :: Var
b = Var -> Int
realUnique Var
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>  Var -> Int
realUnique Var
b
    a :: Var
a compare :: Var -> Var -> Ordering
`compare` b :: 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 a :: Var
a b :: 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 _   = String -> Constr
abstractConstr "Var"
  gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Var
gunfold _ _  = String -> Constr -> c Var
forall a. HasCallStack => String -> a
error "gunfold"
  dataTypeOf :: Var -> DataType
dataTypeOf _ = String -> DataType
mkNoRepType "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
var = Int -> Unique
mkUniqueGrimily (Var -> Int
realUnique Var
var)

setVarUnique :: Var -> Unique -> Var
setVarUnique :: Var -> Unique -> Var
setVarUnique var :: Var
var uniq :: 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
var new_name :: 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 :: Id -> Type -> Id
setVarType :: Var -> Kind -> Var
setVarType id :: Var
id ty :: Kind
ty = Var
id { varType :: Kind
varType = Kind
ty }

updateVarType :: (Type -> Type) -> Id -> Id
updateVarType :: (Kind -> Kind) -> Var -> Var
updateVarType f :: Kind -> Kind
f id :: Var
id = Var
id { varType :: Kind
varType = Kind -> Kind
f (Var -> Kind
varType Var
id) }

updateVarTypeM :: Monad m => (Type -> m Type) -> Id -> m Id
updateVarTypeM :: (Kind -> m Kind) -> Var -> m Var
updateVarTypeM f :: Kind -> m Kind
f id :: Var
id = do { Kind
ty' <- Kind -> m Kind
f (Var -> Kind
varType Var
id)
                         ; Var -> m Var
forall (m :: * -> *) a. Monad m => a -> m a
return (Var
id { varType :: Kind
varType = Kind
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 TyCoRep
data ArgFlag = Inferred | Specified | 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
$cp1Ord :: Eq ArgFlag
Ord, Typeable ArgFlag
DataType
Constr
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 d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ArgFlag -> c ArgFlag
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cRequired :: Constr
$cSpecified :: Constr
$cInferred :: Constr
$tArgFlag :: DataType
gmapMo :: (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 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 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 :: Int -> (forall d. Data d => d -> u) -> ArgFlag -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ArgFlag -> u
gmapQ :: (forall d. Data d => d -> u) -> ArgFlag -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ArgFlag -> [u]
gmapQr :: (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 :: (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 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 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 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 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
$cp1Data :: Typeable ArgFlag
Data)
  -- (<) on ArgFlag means "is less visible than"

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

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

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

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

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

-- Variable Binder
--
-- VarBndr is polymorphic in both var and visibility fields.
-- Currently there are six different uses of 'VarBndr':
--   * Var.TyVarBinder   = VarBndr TyVar ArgFlag
--   * Var.TyCoVarBinder = VarBndr TyCoVar ArgFlag
--   * TyCon.TyConBinder     = VarBndr TyVar TyConBndrVis
--   * TyCon.TyConTyCoBinder = VarBndr TyCoVar TyConBndrVis
--   * IfaceType.IfaceForAllBndr  = VarBndr IfaceBndr ArgFlag
--   * IfaceType.IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis
data VarBndr var argf = Bndr var argf
  deriving( Typeable (VarBndr var argf)
DataType
Constr
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 d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> VarBndr var argf -> c (VarBndr var argf)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (VarBndr var argf)
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (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))
$cBndr :: Constr
$tVarBndr :: DataType
gmapMo :: (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 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 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 :: 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 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 :: (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 :: (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 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 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 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 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)
$cp1Data :: forall var argf.
(Data var, Data argf) =>
Typeable (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 TyCoRep, because it's used in DataCon.hs-boot
--
-- A 'TyVarBinder' is a binder with only TyVar
type TyCoVarBinder = VarBndr TyCoVar ArgFlag
type TyVarBinder   = VarBndr TyVar ArgFlag

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

binderVars :: [VarBndr tv argf] -> [tv]
binderVars :: [VarBndr tv argf] -> [tv]
binderVars tvbs :: [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 :: VarBndr tv argf -> argf
binderArgFlag (Bndr _ argf :: argf
argf) = argf
argf

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

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

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

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

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

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

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

instance (Binary tv, Binary vis) => Binary (VarBndr tv vis) where
  put_ :: BinHandle -> VarBndr tv vis -> IO ()
put_ bh :: BinHandle
bh (Bndr tv :: tv
tv vis :: 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 bh :: 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
tv _) = 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 -> Kind
tyVarKind = Var -> Kind
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 -> Kind -> Var
setTyVarKind tv :: Var
tv k :: Kind
k = Var
tv {varType :: Kind
varType = Kind
k}

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

updateTyVarKindM :: (Monad m) => (Kind -> m Kind) -> TyVar -> m TyVar
updateTyVarKindM :: (Kind -> m Kind) -> Var -> m Var
updateTyVarKindM update :: Kind -> m Kind
update tv :: Var
tv
  = do { Kind
k' <- Kind -> m Kind
update (Var -> Kind
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 :: Kind
varType = Kind
k'} }

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

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

tcTyVarDetails :: TyVar -> TcTyVarDetails
-- See Note [TcTyVars in the typechecker] in 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
var = String -> SDoc -> TcTyVarDetails
forall a. HasCallStack => String -> SDoc -> a
pprPanic "tcTyVarDetails" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
var SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> Kind -> SDoc
pprKind (Var -> Kind
tyVarKind Var
var))

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

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

idInfo :: HasDebugCallStack => Id -> IdInfo
idInfo :: Var -> IdInfo
idInfo (Id { id_info :: Var -> IdInfo
id_info = IdInfo
info }) = IdInfo
info
idInfo other :: Var
other                   = String -> SDoc -> IdInfo
forall a. HasCallStack => String -> SDoc -> a
pprPanic "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 other :: Var
other                         = String -> SDoc -> IdDetails
forall a. HasCallStack => String -> SDoc -> a
pprPanic "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 Id.hs uses 'mkGlobalId' etc with different types
mkGlobalVar :: IdDetails -> Name -> Type -> IdInfo -> Id
mkGlobalVar :: IdDetails -> Name -> Kind -> IdInfo -> Var
mkGlobalVar details :: IdDetails
details name :: Name
name ty :: Kind
ty info :: IdInfo
info
  = Name -> Kind -> IdScope -> IdDetails -> IdInfo -> Var
mk_id Name
name Kind
ty IdScope
GlobalId IdDetails
details IdInfo
info

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

mkCoVar :: Name -> Type -> CoVar
-- Coercion variables have no IdInfo
mkCoVar :: Name -> Kind -> Var
mkCoVar name :: Name
name ty :: Kind
ty = Name -> Kind -> IdScope -> IdDetails -> IdInfo -> Var
mk_id Name
name Kind
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 -> Kind -> IdInfo -> Var
mkExportedLocalVar details :: IdDetails
details name :: Name
name ty :: Kind
ty info :: IdInfo
info
  = Name -> Kind -> IdScope -> IdDetails -> IdInfo -> Var
mk_id Name
name Kind
ty (ExportFlag -> IdScope
LocalId ExportFlag
Exported) IdDetails
details IdInfo
info

mk_id :: Name -> Type -> IdScope -> IdDetails -> IdInfo -> Id
mk_id :: Name -> Kind -> IdScope -> IdDetails -> IdInfo -> Var
mk_id name :: Name
name ty :: Kind
ty scope :: IdScope
scope details :: IdDetails
details info :: IdInfo
info
  = $WId :: Name -> Int -> Kind -> IdScope -> IdDetails -> IdInfo -> Var
Id { varName :: Name
varName    = Name
name,
         realUnique :: Int
realUnique = Unique -> Int
getKey (Name -> Unique
nameUnique Name
name),
         varType :: Kind
varType    = Kind
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 id :: Var
id info :: IdInfo
info = Var
id { id_info :: IdInfo
id_info = IdInfo
info }

setIdDetails :: Id -> IdDetails -> Id
setIdDetails :: Var -> IdDetails -> Var
setIdDetails id :: Var
id details :: 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 id :: 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 tv :: Var
tv                               = String -> SDoc -> Var
forall a. HasCallStack => String -> SDoc -> a
pprPanic "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 id :: Var
id = ASSERT( isLocalId id )
                      Var
id { idScope :: IdScope
idScope = ExportFlag -> IdScope
LocalId ExportFlag
NotExported }

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

isTyVar :: Var -> Bool        -- True of both TyVar and TcTyVar
isTyVar :: Var -> Bool
isTyVar (TyVar {})   = Bool
True
isTyVar (TcTyVar {}) = Bool
True
isTyVar _            = Bool
False

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

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

isId :: Var -> Bool
isId :: Var -> Bool
isId (Id {}) = Bool
True
isId _       = Bool
False

isCoVar :: Var -> Bool
-- A coercion variable
isCoVar :: Var -> Bool
isCoVar (Id { id_details :: Var -> IdDetails
id_details = IdDetails
details }) = IdDetails -> Bool
isCoVarDetails IdDetails
details
isCoVar _                             = Bool
False

isNonCoVarId :: Var -> Bool
-- A term variable (Id) that is /not/ a coercion variable
isNonCoVarId :: Var -> Bool
isNonCoVarId (Id { id_details :: Var -> IdDetails
id_details = IdDetails
details }) = Bool -> Bool
not (IdDetails -> Bool
isCoVarDetails IdDetails
details)
isNonCoVarId _                             = Bool
False

isLocalId :: Var -> Bool
isLocalId :: Var -> Bool
isLocalId (Id { idScope :: Var -> IdScope
idScope = LocalId _ }) = Bool
True
isLocalId _                            = 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 v :: 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 _                           = 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 = 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 Exported}) = Bool
True
isExportedId _ = Bool
False