[project @ 2000-12-07 08:22:53 by simonpj]
[ghc-hetmet.git] / ghc / compiler / coreSyn / Subst.lhs
index 94c40da..1866956 100644 (file)
@@ -37,23 +37,23 @@ module Subst (
 #include "HsVersions.h"
 
 import CmdLineOpts     ( opt_PprStyle_Debug )
-import CoreSyn         ( Expr(..), Bind(..), Note(..), CoreExpr, CoreBndr,
+import CoreSyn         ( Expr(..), Bind(..), Note(..), CoreExpr,
                          CoreRules(..), CoreRule(..), 
-                         emptyCoreRules, isEmptyCoreRules, seqRules
+                         isEmptyCoreRules, seqRules
                        )
 import CoreFVs         ( exprFreeVars, mustHaveLocalBinding )
-import TypeRep         ( Type(..), TyNote(..), 
-                       )  -- friend
+import TypeRep         ( Type(..), TyNote(..) )  -- friend
 import Type            ( ThetaType, PredType(..), ClassContext,
-                         tyVarsOfType, tyVarsOfTypes, mkAppTy
+                         tyVarsOfType, tyVarsOfTypes, mkAppTy, mkUTy, isUTy
                        )
 import VarSet
 import VarEnv
 import Var             ( setVarUnique, isId )
-import Id              ( idType, setIdType, idOccInfo, zapFragileIdInfo )
+import Id              ( idType, setIdType, idOccInfo, zapFragileIdInfo, maybeModifyIdInfo )
 import IdInfo          ( IdInfo, isFragileOcc,
                          specInfo, setSpecInfo, 
-                         WorkerInfo(..), workerExists, workerInfo, setWorkerInfo, WorkerInfo
+                         WorkerInfo(..), workerExists, workerInfo, setWorkerInfo, WorkerInfo,
+                          lbvarInfo, LBVarInfo(..), setLBVarInfo
                        )
 import Unique          ( Uniquable(..), deriveUnique )
 import UniqSet         ( elemUniqSet_Directly )
@@ -63,6 +63,7 @@ import Outputable
 import PprCore         ()              -- Instances
 import UniqFM          ( ufmToList )   -- Yuk (add a new op to VarEnv)
 import Util            ( mapAccumL, foldl2, seqList, ($!) )
+import FastTypes
 \end{code}
 
 
@@ -73,7 +74,7 @@ import Util           ( mapAccumL, foldl2, seqList, ($!) )
 %************************************************************************
 
 \begin{code}
-data InScopeSet = InScope (VarEnv Var) Int#
+data InScopeSet = InScope (VarEnv Var) FastInt
        -- The Int# is a kind of hash-value used by uniqAway
        -- For example, it might be the size of the set
        -- INVARIANT: it's not zero; we use it as a multiplier in uniqAway
@@ -88,8 +89,9 @@ extendInScopeSet :: InScopeSet -> Var -> InScopeSet
 extendInScopeSet (InScope in_scope n) v = InScope (extendVarEnv in_scope v v) (n +# 1#)
 
 extendInScopeSetList :: InScopeSet -> [Var] -> InScopeSet
-extendInScopeSetList (InScope in_scope n) vs = InScope (foldl (\s v -> extendVarEnv s v v) in_scope vs)
-                                                      (case length vs of { I# l -> n +# l })
+extendInScopeSetList (InScope in_scope n) vs
+   = InScope (foldl (\s v -> extendVarEnv s v v) in_scope vs)
+                   (n +# iUnbox (length vs))
 
 modifyInScopeSet :: InScopeSet -> Var -> Var -> InScopeSet
 -- Exploit the fact that the in-scope "set" is really a map
@@ -132,17 +134,17 @@ uniqAway (InScope set n) var
     try k 
 #ifdef DEBUG
          | k ># 1000#
-         = pprPanic "uniqAway loop:" (ppr (I# k) <+> text "tries" <+> ppr var <+> int (I# n)) 
+         = pprPanic "uniqAway loop:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n)) 
 #endif                     
          | uniq `elemUniqSet_Directly` set = try (k +# 1#)
 #ifdef DEBUG
          | opt_PprStyle_Debug && k ># 3#
-         = pprTrace "uniqAway:" (ppr (I# k) <+> text "tries" <+> ppr var <+> int (I# n)) 
+         = pprTrace "uniqAway:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n)) 
            setVarUnique var uniq
 #endif                     
          | otherwise = setVarUnique var uniq
          where
-           uniq = deriveUnique orig_unique (I# (n *# k))
+           uniq = deriveUnique orig_unique (iBox (n *# k))
 \end{code}
 
 
@@ -243,10 +245,12 @@ zapSubstEnv :: Subst -> Subst
 zapSubstEnv (Subst in_scope env) = Subst in_scope emptySubstEnv
 
 extendSubst :: Subst -> Var -> SubstResult -> Subst
-extendSubst (Subst in_scope env) v r = Subst in_scope (extendSubstEnv env v r)
+extendSubst (Subst in_scope env) v r = UASSERT( case r of { DoneTy ty -> not (isUTy ty) ; _ -> True } )
+                                       Subst in_scope (extendSubstEnv env v r)
 
 extendSubstList :: Subst -> [Var] -> [SubstResult] -> Subst
-extendSubstList (Subst in_scope env) v r = Subst in_scope (extendSubstEnvList env v r)
+extendSubstList (Subst in_scope env) v r = UASSERT( all (\ r1 -> case r1 of { DoneTy ty -> not (isUTy ty) ; _ -> True }) r )
+                                           Subst in_scope (extendSubstEnvList env v r)
 
 lookupSubst :: Subst -> Var -> Maybe SubstResult
 lookupSubst (Subst _ env) v = lookupSubstEnv env v
@@ -375,7 +379,8 @@ mkTopTyVarSubst :: [TyVar] -> [Type] -> Subst
 mkTopTyVarSubst tyvars tys = Subst emptyInScopeSet (zip_ty_env tyvars tys emptySubstEnv)
 
 zip_ty_env []       []       env = env
-zip_ty_env (tv:tvs) (ty:tys) env = zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
+zip_ty_env (tv:tvs) (ty:tys) env = UASSERT( not (isUTy ty) )
+                                   zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
 \end{code}
 
 substTy works with general Substs, so that it can be called from substExpr too.
@@ -404,11 +409,11 @@ subst_ty subst ty
   where
     go (TyConApp tc tys)          = let args = map go tys
                                     in  args `seqList` TyConApp tc args
+
+    go (PredTy p)                 = PredTy $! (substPred subst p)
+
     go (NoteTy (SynNote ty1) ty2)  = NoteTy (SynNote $! (go ty1)) $! (go ty2)
     go (NoteTy (FTVNote _) ty2)    = go ty2            -- Discard the free tyvar note
-    go (NoteTy (UsgNote usg)  ty2) = (NoteTy $! UsgNote usg) $! go ty2         -- Keep usage annot
-    go (NoteTy (UsgForAll uv) ty2) = (NoteTy $! UsgForAll uv) $! go ty2        -- Keep uvar bdr
-    go (NoteTy (IPNote nm) ty2)           = (NoteTy $! IPNote nm) $! go ty2            -- Keep ip note
 
     go (FunTy arg res)            = (FunTy $! (go arg)) $! (go res)
     go (AppTy fun arg)            = mkAppTy (go fun) $! (go arg)
@@ -418,6 +423,8 @@ subst_ty subst ty
                                        
     go (ForAllTy tv ty)                   = case substTyVar subst tv of
                                        (subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty)
+
+    go (UsageTy u ty)              = mkUTy (go u) $! (go ty)
 \end{code}
 
 Here is where we invent a new binder if necessary.
@@ -561,9 +568,14 @@ substId subst@(Subst in_scope env) old_id
        -- id2 has its IdInfo zapped
     id2 = zapFragileIdInfo id1
 
-       -- new_id is cloned if necessary
-    new_id = uniqAway in_scope id2
+        -- id3 has its LBVarInfo zapped
+    id3 = maybeModifyIdInfo (\ info -> go info (lbvarInfo info)) id2
+            where go info (LBVarInfo u@(TyVarTy _)) = Just $ setLBVarInfo info $
+                                                      LBVarInfo (subst_ty subst u)
+                  go info _                         = Nothing
 
+       -- new_id is cloned if necessary
+    new_id = uniqAway in_scope id3
        -- Extend the substitution if the unique has changed,
        -- or there's some useful occurrence information
        -- See the notes with substTyVar for the delSubstEnv