[project @ 1999-07-14 14:40:20 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Var.lhs
index e5c820d..d80eab6 100644 (file)
@@ -1,37 +1,40 @@
-
+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, 
@@ -72,11 +75,12 @@ data Var
     }
 
 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.
@@ -114,8 +118,9 @@ varUnique :: Var -> Unique
 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
@@ -155,7 +160,7 @@ mkTyVar name kind = Var { varName    = name
                        , varType    = kind
                        , varDetails = TyVar
 #ifdef DEBUG
-                       , varInfo = pprPanic "mkTyVar" (ppr name)
+                       , varInfo = pprPanic "looking at IdInfo of a tyvar" (ppr name)
 #endif
                        }
 
@@ -177,28 +182,63 @@ newMutTyVar name kind =
      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}
 
 
@@ -208,7 +248,7 @@ isMutTyVar other                           = False
 %*                                                                     *
 %************************************************************************
 
-       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
@@ -220,7 +260,6 @@ idName    = varName
 idType    = varType
 idUnique  = varUnique
 idInfo   = varInfo
-idDetails = varDetails
 
 setIdUnique :: Id -> Unique -> Id
 setIdUnique = setVarUnique
@@ -228,27 +267,37 @@ 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