Use "$@" rather than $* when calling things in darcs-all
[ghc-hetmet.git] / compiler / coreSyn / CoreFVs.lhs
index 2fae6ac..bda9342 100644 (file)
@@ -1,4 +1,5 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 Taken quite directly from the Peyton Jones/Lester paper.
@@ -12,7 +13,7 @@ module CoreFVs (
        exprSomeFreeVars, exprsSomeFreeVars,
        exprFreeNames, exprsFreeNames,
 
-       idRuleVars, idFreeVars, idFreeTyVars, 
+       idRuleVars, idFreeVars, varTypeTyVars, 
        ruleRhsFreeVars, rulesRhsFreeVars,
        ruleLhsFreeNames, ruleLhsFreeIds, 
 
@@ -25,16 +26,15 @@ module CoreFVs (
 #include "HsVersions.h"
 
 import CoreSyn
-import Id              ( Id, idType, idSpecialisation, isLocalId )
-import IdInfo          ( specInfoFreeVars )
+import Id
+import IdInfo
 import NameSet
-import UniqFM          ( delFromUFM )
-import Name            ( isExternalName )
+import UniqFM
+import Name
 import VarSet
-import Var             ( Var, isId, isLocalVar, varName )
-import Type            ( tyVarsOfType )
-import TcType          ( tyClsNamesOfType )
-import Util            ( mapAndUnzip )
+import Var
+import TcType
+import Util
 import Outputable
 \end{code}
 
@@ -138,10 +138,10 @@ keep_it fv_cand in_scope var
 
 addBndr :: CoreBndr -> FV -> FV
 addBndr bndr fv fv_cand in_scope
-  | isId bndr = inside_fvs `unionVarSet` someVars (idFreeTyVars bndr) fv_cand in_scope
-  | otherwise = inside_fvs
-  where
-    inside_fvs = fv fv_cand (in_scope `extendVarSet` bndr) 
+  = someVars (varTypeTyVars bndr) fv_cand in_scope
+       -- Include type varibles in the binder's type
+       --      (not just Ids; coercion variables too!)
+    `unionVarSet`  fv fv_cand (in_scope `extendVarSet` bndr) 
 
 addBndrs :: [CoreBndr] -> FV -> FV
 addBndrs bndrs fv = foldr addBndr fv bndrs
@@ -157,6 +157,7 @@ expr_fvs (Lit lit)   = noVars
 expr_fvs (Note _ expr)   = expr_fvs expr
 expr_fvs (App fun arg)   = expr_fvs fun `union` expr_fvs arg
 expr_fvs (Lam bndr body) = addBndr bndr (expr_fvs body)
+expr_fvs (Cast expr co)  = expr_fvs expr `union` someVars (tyVarsOfType co)
 
 expr_fvs (Case scrut bndr ty alts)
   = expr_fvs scrut `union` someVars (tyVarsOfType ty) `union` addBndr bndr  
@@ -212,12 +213,13 @@ exprFreeNames e
     go (Var v) 
       | isExternalName n    = unitNameSet n
       | otherwise          = emptyNameSet
-      where n = varName v
+      where n = idName v
     go (Lit _)                     = emptyNameSet
     go (Type ty)           = tyClsNamesOfType ty       -- Don't need free tyvars
     go (App e1 e2)         = go e1 `unionNameSets` go e2
-    go (Lam v e)           = go e `delFromNameSet` varName v
-    go (Note n e)          = go e   
+    go (Lam v e)           = go e `delFromNameSet` idName v
+    go (Note n e)          = go e  
+    go (Cast e co)          = go e `unionNameSets` tyClsNamesOfType co
     go (Let (NonRec b r) e) = go e `unionNameSets` go r
     go (Let (Rec prs) e)    = exprsFreeNames (map snd prs) `unionNameSets` go e
     go (Case e b ty as)     = go e `unionNameSets` tyClsNamesOfType ty 
@@ -316,18 +318,18 @@ delBinderFV :: Var -> VarSet -> VarSet
 --                       where
 --                         bottom = bottom -- Never evaluated
 
-delBinderFV b s | isId b    = (s `delVarSet` b) `unionFVs` idFreeVars b
-               | otherwise = s `delVarSet` b
+delBinderFV b s = (s `delVarSet` b) `unionFVs` varTypeTyVars b
+       -- Include coercion variables too!
 
-idFreeVars :: Id -> VarSet
-idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` idFreeTyVars id
+varTypeTyVars :: Var -> TyVarSet
+-- Find the type variables free in the type of the variable
+-- Remember, coercion variables can mention type variables...
+varTypeTyVars var
+  | isLocalId var || isCoVar var = tyVarsOfType (idType var)
+  | otherwise = emptyVarSet    -- Global Ids and non-coercion TyVars
 
-idFreeTyVars :: Id -> TyVarSet
--- Only local Ids conjured up locally, can have free type variables.
--- (During type checking top-level Ids can have free tyvars)
-idFreeTyVars id = tyVarsOfType (idType id)
---  | isLocalId id = tyVarsOfType (idType id)
---  | otherwise    = emptyVarSet
+idFreeVars :: Id -> VarSet
+idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` varTypeTyVars id
 
 idRuleVars ::Id -> VarSet
 idRuleVars id = ASSERT( isId id) specInfoFreeVars (idSpecialisation id)
@@ -367,7 +369,6 @@ freeVars (App fun arg)
     arg2 = freeVars arg
 
 freeVars (Case scrut bndr ty alts)
--- gaw 2004
   = ((bndr `delBinderFV` alts_fvs) `unionFVs` freeVarsOf scrut2 `unionFVs` tyVarsOfType ty,
      AnnCase scrut2 bndr ty alts2)
   where
@@ -382,7 +383,8 @@ freeVars (Case scrut bndr ty alts)
                             rhs2 = freeVars rhs
 
 freeVars (Let (NonRec binder rhs) body)
-  = (freeVarsOf rhs2 `unionFVs` body_fvs,
+  = (freeVarsOf rhs2 `unionFVs` body_fvs `unionFVs` idRuleVars binder,
+               -- Remember any rules; cf rhs_fvs above
      AnnLet (AnnNonRec binder rhs2) body2)
   where
     rhs2     = freeVars rhs
@@ -390,27 +392,26 @@ freeVars (Let (NonRec binder rhs) body)
     body_fvs = binder `delBinderFV` freeVarsOf body2
 
 freeVars (Let (Rec binds) body)
-  = (foldl delVarSet group_fvs binders,
-       -- The "delBinderFV" part may have added one of the binders
-       -- via the idSpecVars part, so we must delete it again
+  = (delBindersFV binders all_fvs,
      AnnLet (AnnRec (binders `zip` rhss2)) body2)
   where
     (binders, rhss) = unzip binds
 
     rhss2     = map freeVars rhss
-    all_fvs   = foldr (unionFVs . fst) body_fvs rhss2
-    group_fvs = delBindersFV binders all_fvs
+    rhs_body_fvs = foldr (unionFVs . freeVarsOf) body_fvs rhss2
+    all_fvs      = foldr (unionFVs . idRuleVars) rhs_body_fvs binders
+       -- The "delBinderFV" happens after adding the idSpecVars,
+       -- since the latter may add some of the binders as fvs
 
     body2     = freeVars body
     body_fvs  = freeVarsOf body2
 
-freeVars (Note (Coerce to_ty from_ty) expr)
-  = (freeVarsOf expr2 `unionFVs` tfvs1 `unionFVs` tfvs2,
-     AnnNote (Coerce to_ty from_ty) expr2)
+
+freeVars (Cast expr co)
+  = (freeVarsOf expr2 `unionFVs` cfvs, AnnCast expr2 co)
   where
-    expr2  = freeVars expr
-    tfvs1  = tyVarsOfType from_ty
-    tfvs2  = tyVarsOfType to_ty
+    expr2 = freeVars expr
+    cfvs  = tyVarsOfType co
 
 freeVars (Note other_note expr)
   = (freeVarsOf expr2, AnnNote other_note expr2)