%
+% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section{@Vars@: Variables}
\begin{code}
module Var (
Var,
- varName, varUnique,
+ varName, varUnique, varType,
setVarName, setVarUnique,
-- TyVars
- TyVar, mkTyVar, mkTcTyVar,
+ TyVar, mkTyVar, mkTcTyVar, mkWildCoVar,
tyVarName, tyVarKind,
setTyVarName, setTyVarUnique, setTyVarKind,
tcTyVarDetails,
Id, DictId,
idName, idType, idUnique, idInfo, modifyIdInfo, maybeModifyIdInfo,
setIdName, setIdUnique, setIdType, setIdInfo, lazySetIdInfo,
- setIdExported, setIdNotExported,
+ setIdExported, setIdNotExported,
globalIdDetails, globaliseId,
#include "HsVersions.h"
-import {-# SOURCE #-} TypeRep( Type, Kind, isCoSuperKind )
+import {-# SOURCE #-} TypeRep( Type, Kind )
import {-# SOURCE #-} TcType( TcTyVarDetails, pprTcTyVarDetails )
-import {-# SOURCE #-} IdInfo( GlobalIdDetails, notGlobalId, IdInfo, seqIdInfo )
+import {-# SOURCE #-} IdInfo( GlobalIdDetails, notGlobalId,
+ IdInfo, seqIdInfo )
+import {-# SOURCE #-} TypeRep( isCoercionKind )
-import Name ( Name, NamedThing(..),
- setNameUnique, nameUnique
- )
-import Unique ( Unique, Uniquable(..), mkUniqueGrimily, getKey# )
+import Name hiding (varName)
+import Unique
import FastTypes
-import Outputable
+import FastString
+import Outputable
\end{code}
realUnique :: FastInt, -- Key for fast comparison
-- Identical to the Unique in the name,
-- cached here for speed
- tyVarKind :: Kind }
+ varType :: Kind,
+ isCoercionVar :: Bool
+ }
| TcTyVar { -- Used only during type inference
-- Used for kind variables during
-- inference, as well
varName :: !Name,
realUnique :: FastInt,
- tyVarKind :: Kind,
+ varType :: Kind,
tcTyVarDetails :: TcTyVarDetails }
| GlobalId { -- Used for imported Ids, dict selectors etc
-- See Note [GlobalId/LocalId] below
varName :: !Name, -- Always an External or WiredIn Name
realUnique :: FastInt,
- idType :: Type,
- idInfo :: IdInfo,
+ varType :: Type,
+ idInfo_ :: IdInfo,
gblDetails :: GlobalIdDetails }
| LocalId { -- Used for locally-defined Ids
-- See Note [GlobalId/LocalId] below
varName :: !Name,
realUnique :: FastInt,
- idType :: Type,
- idInfo :: IdInfo,
+ varType :: Type,
+ idInfo_ :: IdInfo,
lclDetails :: LocalIdDetails }
data LocalIdDetails
setVarUnique :: Var -> Unique -> Var
setVarUnique var uniq
- = var { realUnique = getKey# uniq,
+ = var { realUnique = getKeyFastInt uniq,
varName = setNameUnique (varName var) uniq }
setVarName :: Var -> Name -> Var
setVarName var new_name
- = var { realUnique = getKey# (getUnique new_name),
+ = var { realUnique = getKeyFastInt (getUnique new_name),
varName = new_name }
\end{code}
\begin{code}
type TyVar = Var
+tyVarName :: TyVar -> Name
tyVarName = varName
+tyVarKind :: TyVar -> Kind
+tyVarKind = varType
+
+setTyVarUnique :: TyVar -> Unique -> TyVar
setTyVarUnique = setVarUnique
+
+setTyVarName :: TyVar -> Name -> TyVar
setTyVarName = setVarName
setTyVarKind :: TyVar -> Kind -> TyVar
-setTyVarKind tv k = tv {tyVarKind = k}
+setTyVarKind tv k = tv {varType = k}
\end{code}
\begin{code}
mkTyVar :: Name -> Kind -> TyVar
-mkTyVar name kind = TyVar { varName = name
- , realUnique = getKey# (nameUnique name)
- , tyVarKind = kind
+mkTyVar name kind = ASSERT( not (isCoercionKind kind ) )
+ TyVar { varName = name
+ , realUnique = getKeyFastInt (nameUnique name)
+ , varType = kind
+ , isCoercionVar = False
}
mkTcTyVar :: Name -> Kind -> TcTyVarDetails -> TyVar
mkTcTyVar name kind details
- = TcTyVar { varName = name,
- realUnique = getKey# (nameUnique name),
- tyVarKind = kind,
+ = -- TOM: no longer valid assertion?
+ -- ASSERT( not (isCoercionKind kind) )
+ TcTyVar { varName = name,
+ realUnique = getKeyFastInt (nameUnique name),
+ varType = kind,
tcTyVarDetails = details
}
\end{code}
\begin{code}
type CoVar = Var -- A coercion variable is simply a type
-- variable of kind (ty1 :=: ty2)
+
+coVarName :: CoVar -> Name
coVarName = varName
+setCoVarUnique :: CoVar -> Unique -> CoVar
setCoVarUnique = setVarUnique
+
+setCoVarName :: CoVar -> Name -> CoVar
setCoVarName = setVarName
mkCoVar :: Name -> Kind -> CoVar
-mkCoVar name kind = mkTyVar name kind
+mkCoVar name kind = ASSERT( isCoercionKind kind )
+ TyVar { varName = name
+ , realUnique = getKeyFastInt (nameUnique name)
+ , varType = kind
+ -- varType is always PredTy (EqPred t1 t2)
+ , isCoercionVar = True
+ }
-isCoVar :: TyVar -> Bool
-isCoVar ty = isCoSuperKind (tyVarKind ty)
+mkWildCoVar :: Kind -> TyVar
+-- A type variable that is never referred to,
+-- so its unique doesn't matter
+mkWildCoVar kind
+ = ASSERT( isCoercionKind kind )
+ TyVar { varName = mkSysTvName wild_uniq FSLIT("co_wild"),
+ realUnique = _ILIT(1),
+ varType = kind,
+ isCoercionVar = True }
+ where
+ wild_uniq = mkBuiltinUnique 1
\end{code}
%************************************************************************
\end{code}
\begin{code}
+idName :: Id -> Name
+idUnique :: Id -> Unique
+idType :: Id -> Kind
+
idName = varName
idUnique = varUnique
+idType = varType
setIdUnique :: Id -> Unique -> Id
setIdUnique = setVarUnique
setIdName = setVarName
setIdType :: Id -> Type -> Id
-setIdType id ty = id {idType = ty}
+setIdType id ty = id {varType = ty}
setIdExported :: Id -> Id
-- Can be called on GlobalIds, such as data cons and class ops,
-- If it's a local, make it global
globaliseId details id = GlobalId { varName = varName id,
realUnique = realUnique id,
- idType = idType id,
- idInfo = idInfo id,
+ varType = varType id,
+ idInfo_ = idInfo id,
gblDetails = details }
+idInfo :: Id -> IdInfo
+idInfo (GlobalId {idInfo_ = info}) = info
+idInfo (LocalId {idInfo_ = info}) = info
+idInfo other_var = pprPanic "idInfo" (ppr other_var)
+
lazySetIdInfo :: Id -> IdInfo -> Id
-lazySetIdInfo id info = id {idInfo = info}
+lazySetIdInfo id info = id {idInfo_ = info}
setIdInfo :: Id -> IdInfo -> Id
-setIdInfo id info = seqIdInfo info `seq` id {idInfo = info}
+setIdInfo id info = seqIdInfo info `seq` id {idInfo_ = info}
-- Try to avoid spack leaks by seq'ing
modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
modifyIdInfo fn id
- = seqIdInfo new_info `seq` id {idInfo = new_info}
+ = seqIdInfo new_info `seq` id {idInfo_ = new_info}
where
new_info = fn (idInfo id)
-- maybeModifyIdInfo tries to avoid unnecesary thrashing
maybeModifyIdInfo :: Maybe IdInfo -> Id -> Id
-maybeModifyIdInfo (Just new_info) id = id {idInfo = new_info}
+maybeModifyIdInfo (Just new_info) id = id {idInfo_ = new_info}
maybeModifyIdInfo Nothing id = id
\end{code}
mkGlobalId :: GlobalIdDetails -> Name -> Type -> IdInfo -> Id
mkGlobalId details name ty info
= GlobalId { varName = name,
- realUnique = getKey# (nameUnique name), -- Cache the unique
- idType = ty,
+ realUnique = getKeyFastInt (nameUnique name), -- Cache the unique
+ varType = ty,
gblDetails = details,
- idInfo = info }
+ idInfo_ = info }
mk_local_id :: Name -> Type -> LocalIdDetails -> IdInfo -> Id
mk_local_id name ty details info
= LocalId { varName = name,
- realUnique = getKey# (nameUnique name), -- Cache the unique
- idType = ty,
+ realUnique = getKeyFastInt (nameUnique name), -- Cache the unique
+ varType = ty,
lclDetails = details,
- idInfo = info }
+ idInfo_ = info }
mkLocalId :: Name -> Type -> IdInfo -> Id
mkLocalId name ty info = mk_local_id name ty NotExported info
isId, isLocalVar, isLocalId :: Var -> Bool
isGlobalId, isExportedId :: Var -> Bool
mustHaveLocalBinding :: Var -> Bool
+isCoVar :: Var -> Bool
isTyVar (TyVar {}) = True
isTyVar (TcTyVar {}) = True
-isTyVar other = False
+isTyVar _ = False
isTcTyVar (TcTyVar {}) = True
-isTcTyVar other = False
+isTcTyVar _ = False
isId (LocalId {}) = True
isId (GlobalId {}) = True
-isId other = False
+isId _ = False
isLocalId (LocalId {}) = True
-isLocalId other = False
+isLocalId _ = False
+
+isCoVar (v@(TyVar {})) = isCoercionVar v
+isCoVar _ = False
-- isLocalVar returns True for type variables as well as local Ids
-- These are the variables that we need to pay attention to when finding free
-- variables, or doing dependency analysis.
isLocalVar (GlobalId {}) = False
-isLocalVar other = True
+isLocalVar _ = True
-- mustHaveLocalBinding returns True of Ids and TyVars
-- that must have a binding in this module. The converse
mustHaveLocalBinding var = isLocalVar var
isGlobalId (GlobalId {}) = True
-isGlobalId other = False
+isGlobalId _ = False
-- isExportedId means "don't throw this away"
isExportedId (GlobalId {}) = True
isExportedId (LocalId {lclDetails = details})
= case details of
Exported -> True
- other -> False
-isExportedId other = False
+ _ -> False
+isExportedId _ = False
\end{code}
\begin{code}
globalIdDetails :: Var -> GlobalIdDetails
-- Works OK on local Ids too, returning notGlobalId
globalIdDetails (GlobalId {gblDetails = details}) = details
-globalIdDetails other = notGlobalId
+globalIdDetails _ = notGlobalId
\end{code}