-
+s%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section{@Vars@: Variables}
\begin{code}
module Var (
- Var, IdOrTyVar, -- Abstract
- VarDetails(..), -- Concrete
- varName, varUnique, varDetails, varInfo, varType,
- setVarName, setVarUnique, setVarType, setVarOcc,
+ Var, IdOrTyVar, VarDetails, -- Abstract
+ varName, varUnique, varInfo, varType,
+ setVarName, setVarUnique, setVarType, setVarOcc,
-- TyVars
TyVar,
tyVarName, tyVarKind,
setTyVarName, setTyVarUnique,
- mkTyVar, mkSysTyVar, isTyVar,
- newMutTyVar, readMutTyVar, writeMutTyVar, isMutTyVar, makeTyVarImmutable,
+ mkTyVar, mkSysTyVar, isTyVar, isSigTyVar,
+ newMutTyVar, newSigTyVar,
+ readMutTyVar, writeMutTyVar, isMutTyVar, makeTyVarImmutable,
+
+ -- UVars
+ UVar,
+ isUVar,
+ mkUVar,
-- Ids
Id, DictId,
- idDetails, idName, idType, idUnique, idInfo, modifyIdInfo,
- setIdName, setIdUnique, setIdInfo,
- mkId, isId, externallyVisibleId
+ idName, idType, idUnique, idInfo, modifyIdInfo, maybeModifyIdInfo,
+ setIdName, setIdUnique, setIdInfo, lazySetIdInfo,
+ mkIdVar, isId, externallyVisibleId
) where
#include "HsVersions.h"
import {-# SOURCE #-} Type( Type, Kind )
-import {-# SOURCE #-} IdInfo( IdInfo )
-import {-# SOURCE #-} Const( Con )
+import {-# SOURCE #-} IdInfo( IdInfo, seqIdInfo )
-import FieldLabel ( FieldLabel )
import Unique ( Unique, Uniquable(..), mkUniqueGrimily, getKey )
import Name ( Name, OccName, NamedThing(..),
setNameUnique, setNameOcc, nameUnique,
}
data VarDetails
- = VanillaId -- Most Ids are like this
- | ConstantId Con -- The Id for a constant (data constructor or primop)
- | RecordSelId FieldLabel -- The Id for a record selector
+ = AnId
| TyVar
- | MutTyVar (IORef (Maybe Type)) -- Used during unification
+ | MutTyVar (IORef (Maybe Type)) -- Used during unification;
+ Bool -- True <=> this is a type signature variable, which
+ -- should not be unified with a non-tyvar type
+ | UVar -- Usage variable
-- For a long time I tried to keep mutable Vars statically type-distinct
-- from immutable Vars, but I've finally given up. It's just too painful.
varUnique (Var {realUnique = uniq}) = mkUniqueGrimily uniq
setVarUnique :: Var -> Unique -> Var
-setVarUnique var uniq = var {realUnique = getKey uniq,
- varName = setNameUnique (varName var) uniq}
+setVarUnique var@(Var {varName = name}) uniq
+ = var {realUnique = getKey uniq,
+ varName = setNameUnique name uniq}
setVarName :: Var -> Name -> Var
setVarName var new_name
\begin{code}
mkTyVar :: Name -> Kind -> TyVar
-mkTyVar name kind = Var { varName = name, realUnique = getKey (nameUnique name),
- varType = kind, varDetails = TyVar }
+mkTyVar name kind = Var { varName = name
+ , realUnique = getKey (nameUnique name)
+ , varType = kind
+ , varDetails = TyVar
+#ifdef DEBUG
+ , varInfo = pprPanic "looking at IdInfo of a tyvar" (ppr name)
+#endif
+ }
mkSysTyVar :: Unique -> Kind -> TyVar
-mkSysTyVar uniq kind = Var { varName = name, realUnique = getKey uniq,
- varType = kind, varDetails = TyVar }
+mkSysTyVar uniq kind = Var { varName = name
+ , realUnique = getKey uniq
+ , varType = kind
+ , varDetails = TyVar
+#ifdef DEBUG
+ , varInfo = pprPanic "mkSysTyVar" (ppr name)
+#endif
+ }
where
name = mkSysLocalName uniq SLIT("t")
return (Var { varName = name,
realUnique = getKey (nameUnique name),
varType = kind,
- varDetails = MutTyVar loc })
+ varDetails = MutTyVar loc False})
+
+newSigTyVar :: Name -> Kind -> IO TyVar
+newSigTyVar name kind =
+ do loc <- newIORef Nothing
+ return (Var { varName = name,
+ realUnique = getKey (nameUnique name),
+ varType = kind,
+ varDetails = MutTyVar loc True})
readMutTyVar :: TyVar -> IO (Maybe Type)
-readMutTyVar (Var {varDetails = MutTyVar loc}) = readIORef loc
+readMutTyVar (Var {varDetails = MutTyVar loc _}) = readIORef loc
writeMutTyVar :: TyVar -> Maybe Type -> IO ()
-writeMutTyVar (Var {varDetails = MutTyVar loc}) val = writeIORef loc val
+writeMutTyVar (Var {varDetails = MutTyVar loc _}) val = writeIORef loc val
makeTyVarImmutable :: TyVar -> TyVar
makeTyVarImmutable tyvar = tyvar { varDetails = TyVar}
-\end{code}
-\begin{code}
isTyVar :: Var -> Bool
isTyVar (Var {varDetails = details}) = case details of
- TyVar -> True
- MutTyVar _ -> True
- other -> False
+ TyVar -> True
+ MutTyVar _ _ -> True
+ other -> False
isMutTyVar :: Var -> Bool
-isMutTyVar (Var {varDetails = MutTyVar _}) = True
-isMutTyVar other = False
+isMutTyVar (Var {varDetails = MutTyVar _ _}) = True
+isMutTyVar other = False
+
+isSigTyVar :: Var -> Bool
+isSigTyVar (Var {varDetails = MutTyVar _ is_sig}) = is_sig
+isSigTyVar other = False
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Usage variables}
+%* *
+%************************************************************************
+
+\begin{code}
+type UVar = Var
+\end{code}
+
+\begin{code}
+mkUVar :: Unique -> UVar
+mkUVar unique = Var { varName = mkSysLocalName unique SLIT("u"),
+ realUnique = getKey unique,
+ varDetails = UVar }
+\end{code}
+
+\begin{code}
+isUVar :: Var -> Bool
+isUVar (Var {varDetails = details}) = case details of
+ UVar -> True
+ other -> False
\end{code}
%* *
%************************************************************************
- Most Id-related functions are in Id.lhs and MkId.lhs
+Most Id-related functions are in Id.lhs and MkId.lhs
\begin{code}
type Id = Var
idType = varType
idUnique = varUnique
idInfo = varInfo
-idDetails = varDetails
setIdUnique :: Id -> Unique -> Id
setIdUnique = setVarUnique
setIdName :: Id -> Name -> Id
setIdName = setVarName
-setIdInfo :: Id -> IdInfo -> Id
-setIdInfo var info = var {varInfo = info}
+lazySetIdInfo :: Id -> IdInfo -> Id
+lazySetIdInfo var info = var {varInfo = info}
-modifyIdInfo :: Id -> (IdInfo -> IdInfo) -> Id
-modifyIdInfo var@(Var {varInfo = info}) fn = var {varInfo = fn info}
+setIdInfo :: Id -> IdInfo -> Id
+setIdInfo var info = seqIdInfo info `seq` var {varInfo = info}
+ -- Try to avoid spack leaks by seq'ing
+
+modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
+modifyIdInfo fn var@(Var {varInfo = info})
+ = seqIdInfo new_info `seq` var {varInfo = new_info}
+ where
+ new_info = fn info
+
+-- maybeModifyIdInfo tries to avoid unnecesary thrashing
+maybeModifyIdInfo :: (IdInfo -> Maybe IdInfo) -> Id -> Id
+maybeModifyIdInfo fn var@(Var {varInfo = info}) = case fn info of
+ Nothing -> var
+ Just new_info -> var {varInfo = new_info}
\end{code}
\begin{code}
-mkId :: Name -> Type -> VarDetails -> IdInfo -> Id
-mkId name ty details info
+mkIdVar :: Name -> Type -> IdInfo -> Id
+mkIdVar name ty info
= Var {varName = name, realUnique = getKey (nameUnique name), varType = ty,
- varDetails = details, varInfo = info}
+ varDetails = AnId, varInfo = info}
\end{code}
\begin{code}
isId :: Var -> Bool
-isId (Var {varDetails = details}) = case details of
- VanillaId -> True
- ConstantId _ -> True
- RecordSelId _ -> True
- other -> False
+isId (Var {varDetails = AnId}) = True
+isId other = False
\end{code}
@externallyVisibleId@: is it true that another module might be