{-
(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]
        Id -> Name
varName    :: !Name,
        Id -> Int
realUnique :: {-# UNPACK #-} !Int,
                                     -- ^ Key for fast comparison
                                     -- Identical to the Unique in the name,
                                     -- cached here for speed
        Id -> 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,
        Id -> TcTyVarDetails
tc_tv_details  :: TcTyVarDetails
  }

  | Id {
        varName    :: !Name,
        realUnique :: {-# UNPACK #-} !Int,
        varType    :: Type,
        Id -> Mult
varMult    :: Mult,             -- See Note [Multiplicity of let binders]
        Id -> IdScope
idScope    :: IdScope,
        Id -> IdDetails
id_details :: IdDetails,        -- Stable, doesn't change
        Id -> 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 :: Id -> SDoc
ppr Id
var = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressVarKinds ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
supp_var_kinds ->
            (Bool -> SDoc) -> SDoc
getPprDebug ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
debug ->
            (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
sty ->
            let
              ppr_var :: SDoc
ppr_var = case Id
var of
                  (TyVar {})
                     | Bool
debug
                     -> SDoc -> SDoc
brackets (String -> SDoc
text String
"tv")

                  (TcTyVar {tc_tv_details :: Id -> 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 :: Id -> IdScope
idScope = IdScope
s, id_details :: Id -> 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)

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

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

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

instance Ord Var where
    Id
a <= :: Id -> Id -> Bool
<= Id
b = Id -> Int
realUnique Id
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Id -> Int
realUnique Id
b
    Id
a < :: Id -> Id -> Bool
<  Id
b = Id -> Int
realUnique Id
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<  Id -> Int
realUnique Id
b
    Id
a >= :: Id -> Id -> Bool
>= Id
b = Id -> Int
realUnique Id
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Id -> Int
realUnique Id
b
    Id
a > :: Id -> Id -> Bool
>  Id
b = Id -> Int
realUnique Id
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>  Id -> Int
realUnique Id
b
    Id
a compare :: Id -> Id -> Ordering
`compare` Id
b = Id
a Id -> Id -> Ordering
`nonDetCmpVar` Id
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 :: Id -> Id -> Ordering
nonDetCmpVar Id
a Id
b = Id -> Unique
varUnique Id
a Unique -> Unique -> Ordering
`nonDetCmpUnique` Id -> Unique
varUnique Id
b

instance Data Var where
  -- don't traverse?
  toConstr :: Id -> Constr
toConstr Id
_   = 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 Id
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
_  = String -> Constr -> c Id
forall a. HasCallStack => String -> a
error String
"gunfold"
  dataTypeOf :: Id -> DataType
dataTypeOf Id
_ = String -> DataType
mkNoRepType String
"Var"

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

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

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

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

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

setVarType :: Var -> Type -> Var
setVarType :: Id -> Mult -> Id
setVarType Id
id Mult
ty = Id
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) -> Id -> Id
updateVarType Mult -> Mult
upd Id
var
  = case Id
var of
      Id { id_details :: Id -> IdDetails
id_details = IdDetails
details } -> Bool -> Id -> Id
forall a. HasCallStack => Bool -> a -> a
assert (IdDetails -> Bool
isCoVarDetails IdDetails
details) (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$
                                     Id
result
      Id
_ -> Id
result
  where
    result :: Id
result = Id
var { varType :: Mult
varType = Mult -> Mult
upd (Id -> Mult
varType Id
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) -> Id -> m Id
updateVarTypeM Mult -> m Mult
upd Id
var
  = case Id
var of
      Id { id_details :: Id -> IdDetails
id_details = IdDetails
details } -> Bool -> m Id -> m Id
forall a. HasCallStack => Bool -> a -> a
assert (IdDetails -> Bool
isCoVarDetails IdDetails
details) (m Id -> m Id) -> m Id -> m Id
forall a b. (a -> b) -> a -> b
$
                                     m Id
result
      Id
_ -> m Id
result
  where
    result :: m Id
result = do { Mult
ty' <- Mult -> m Mult
upd (Id -> Mult
varType Id
var)
                ; Id -> m Id
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id
var { varType :: Mult
varType = Mult
ty' }) }

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

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

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

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

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

-- | Does this 'ArgFlag' classify an argument that is written in Haskell?
isVisibleArgFlag :: ArgFlag -> Bool
isVisibleArgFlag :: ArgFlag -> Bool
isVisibleArgFlag ArgFlag
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 -> Specificity -> IO Specificity
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Specificity
SpecifiedSpec
      Word8
_ -> Specificity -> IO Specificity
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Specificity
InferredSpec

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

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

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

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

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

  get :: BinHandle -> IO AnonArgFlag
get BinHandle
bh = do
    Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
    case Word8
h of
      Word8
0 -> AnonArgFlag -> IO AnonArgFlag
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return AnonArgFlag
VisArg
      Word8
_ -> AnonArgFlag -> IO AnonArgFlag
forall a. a -> IO a
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( Typeable (VarBndr var argf)
Typeable (VarBndr var argf)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> VarBndr var argf
    -> c (VarBndr var argf))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (VarBndr var argf))
-> (VarBndr var argf -> Constr)
-> (VarBndr var argf -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (VarBndr var argf)))
-> ((forall b. Data b => b -> b)
    -> VarBndr var argf -> VarBndr var argf)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> VarBndr var argf -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> VarBndr var argf -> m (VarBndr var argf))
-> Data (VarBndr var argf)
VarBndr var argf -> Constr
VarBndr var argf -> DataType
(forall b. Data b => b -> b)
-> VarBndr var argf -> VarBndr var argf
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u
forall u. (forall d. Data d => d -> u) -> VarBndr var argf -> [u]
forall {var} {argf}.
(Data var, Data argf) =>
Typeable (VarBndr var argf)
forall var argf.
(Data var, Data argf) =>
VarBndr var argf -> Constr
forall var argf.
(Data var, Data argf) =>
VarBndr var argf -> DataType
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))
$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)
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)
$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)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (VarBndr var argf)
$ctoConstr :: forall var argf.
(Data var, Data argf) =>
VarBndr var argf -> Constr
toConstr :: VarBndr var argf -> Constr
$cdataTypeOf :: forall var argf.
(Data var, Data argf) =>
VarBndr var argf -> DataType
dataTypeOf :: VarBndr var argf -> DataType
$cdataCast1 :: forall var argf (t :: * -> *) (c :: * -> *).
(Data var, Data argf, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (VarBndr var argf))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> 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))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (VarBndr var argf))
$cgmapT :: forall var argf.
(Data var, Data argf) =>
(forall b. Data b => b -> b)
-> VarBndr var argf -> VarBndr var argf
gmapT :: (forall b. Data b => b -> b)
-> VarBndr var argf -> VarBndr var argf
$cgmapQl :: 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
$cgmapQr :: forall var argf r r'.
(Data var, Data argf) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> VarBndr var argf -> r
$cgmapQ :: forall var argf u.
(Data var, Data argf) =>
(forall d. Data d => d -> u) -> VarBndr var argf -> [u]
gmapQ :: forall u. (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
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> VarBndr var argf -> u
$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)
gmapM :: forall (m :: * -> *).
Monad 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)
gmapMp :: 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)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> VarBndr var argf -> m (VarBndr var argf)
Data )

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

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

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

tyVarReqToBinders :: [VarBndr a ()] -> [VarBndr a ArgFlag]
tyVarReqToBinders :: forall a. [VarBndr a ()] -> [VarBndr a ArgFlag]
tyVarReqToBinders = (VarBndr a () -> VarBndr a ArgFlag)
-> [VarBndr a ()] -> [VarBndr a ArgFlag]
forall a b. (a -> b) -> [a] -> [b]
map VarBndr a () -> VarBndr a ArgFlag
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 ()
_) = a -> ArgFlag -> VarBndr a ArgFlag
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 = (VarBndr tv argf -> tv) -> [VarBndr tv argf] -> [tv]
forall a b. (a -> b) -> [a] -> [b]
map VarBndr tv argf -> tv
forall tv argf. VarBndr tv argf -> tv
binderVar [VarBndr tv argf]
tvbs

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

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

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

-- | Make a named binder
-- 'var' should be a type variable
mkTyVarBinder :: vis -> TyVar -> VarBndr TyVar vis
mkTyVarBinder :: forall vis. vis -> Id -> VarBndr Id vis
mkTyVarBinder vis
vis Id
var
  = Bool -> VarBndr Id vis -> VarBndr Id vis
forall a. HasCallStack => Bool -> a -> a
assert (Id -> Bool
isTyVar Id
var) (VarBndr Id vis -> VarBndr Id vis)
-> VarBndr Id vis -> VarBndr Id vis
forall a b. (a -> b) -> a -> b
$
    Id -> vis -> VarBndr Id vis
forall var argf. var -> argf -> VarBndr var argf
Bndr Id
var vis
vis

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

mkTyVar :: Name -> Kind -> TyVar
mkTyVar :: Name -> Mult -> Id
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 -> Id
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 :: Id -> TcTyVarDetails
tcTyVarDetails (TcTyVar { tc_tv_details :: Id -> 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 {})                            = TcTyVarDetails
HasCallStack => TcTyVarDetails
vanillaSkolemTvUnk
tcTyVarDetails Id
var = String -> SDoc -> TcTyVarDetails
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"tcTyVarDetails" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
var SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> Mult -> SDoc
pprKind (Id -> Mult
tyVarKind Id
var))

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

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

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

idDetails :: Id -> IdDetails
idDetails :: Id -> IdDetails
idDetails (Id { id_details :: Id -> IdDetails
id_details = IdDetails
details }) = IdDetails
details
idDetails Id
other                         = String -> SDoc -> IdDetails
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"idDetails" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
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 -> Id
mkGlobalVar IdDetails
details Name
name Mult
ty IdInfo
info
  = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Id
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 -> Id
mkLocalVar IdDetails
details Name
name Mult
w Mult
ty IdInfo
info
  = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Id
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 -> Id
mkCoVar Name
name Mult
ty = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Id
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 -> Id
mkExportedLocalVar IdDetails
details Name
name Mult
ty IdInfo
info
  = Name -> Mult -> Mult -> IdScope -> IdDetails -> IdInfo -> Id
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 -> Id
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 :: Id -> IdInfo -> Id
lazySetIdInfo Id
id IdInfo
info = Id
id { id_info :: IdInfo
id_info = IdInfo
info }

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

globaliseId :: Id -> Id
-- ^ If it's a local, make it global
globaliseId :: Id -> Id
globaliseId Id
id = Id
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 :: Id -> Id
setIdExported id :: Id
id@(Id { idScope :: Id -> IdScope
idScope = LocalId {} }) = Id
id { idScope :: IdScope
idScope = ExportFlag -> IdScope
LocalId ExportFlag
Exported }
setIdExported id :: Id
id@(Id { idScope :: Id -> IdScope
idScope = IdScope
GlobalId })   = Id
id
setIdExported Id
tv                               = String -> SDoc -> Id
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"setIdExported" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
tv)

setIdNotExported :: Id -> Id
-- ^ We can only do this to LocalIds
setIdNotExported :: Id -> Id
setIdNotExported Id
id = Bool -> Id -> Id
forall a. HasCallStack => Bool -> a -> a
assert (Id -> Bool
isLocalId Id
id) (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$
                      Id
id { idScope :: IdScope
idScope = ExportFlag -> IdScope
LocalId ExportFlag
NotExported }

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


updateIdTypeAndMult :: (Type -> Type) -> Id -> Id
updateIdTypeAndMult :: (Mult -> Mult) -> Id -> Id
updateIdTypeAndMult Mult -> Mult
f id :: Id
id@(Id { varType :: Id -> Mult
varType = Mult
ty
                             , varMult :: Id -> Mult
varMult = Mult
mult })
  = Id
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
_ Id
other = String -> SDoc -> Id
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"updateIdTypeAndMult" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
other)

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

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

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

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

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

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

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

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

isLocalId :: Var -> Bool
isLocalId :: Id -> Bool
isLocalId (Id { idScope :: Id -> IdScope
idScope = LocalId ExportFlag
_ }) = Bool
True
isLocalId Id
_                            = 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 :: Id -> Bool
isLocalVar Id
v = Bool -> Bool
not (Id -> Bool
isGlobalId Id
v)

isGlobalId :: Var -> Bool
isGlobalId :: Id -> Bool
isGlobalId (Id { idScope :: Id -> IdScope
idScope = IdScope
GlobalId }) = Bool
True
isGlobalId Id
_                           = 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 :: Id -> Bool
mustHaveLocalBinding Id
var = Id -> Bool
isLocalVar Id
var

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