<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ --> <title>coreSyn/CoreFVs.lhs</title> <link type='text/css' rel='stylesheet' href='hscolour.css' /> </head> <body> % % (c) The University of Glasgow 2006 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % Taken quite directly from the Peyton Jones/Lester paper. \begin{code} <pre><a name="line-1"></a><span class='hs-comment'>{-# OPTIONS -fno-warn-incomplete-patterns #-}</span> <a name="line-2"></a><span class='hs-comment'>-- The above warning supression flag is a temporary kludge.</span> <a name="line-3"></a><span class='hs-comment'>-- While working on this module you are encouraged to remove it and fix</span> <a name="line-4"></a><span class='hs-comment'>-- any warnings in the module. See</span> <a name="line-5"></a><span class='hs-comment'>-- <a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings">http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings</a></span> <a name="line-6"></a><span class='hs-comment'>-- for details</span> <a name="line-7"></a> <a name="line-8"></a><span class='hs-comment'>-- | A module concerned with finding the free variables of an expression.</span> <a name="line-9"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>CoreFVs</span> <span class='hs-layout'>(</span> <a name="line-10"></a> <span class='hs-comment'>-- * Free variables of expressions and binding groups</span> <a name="line-11"></a> <span class='hs-varid'>exprFreeVars</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- CoreExpr -> VarSet -- Find all locally-defined free Ids or tyvars</span> <a name="line-12"></a> <span class='hs-varid'>exprsFreeVars</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- [CoreExpr] -> VarSet</span> <a name="line-13"></a> <span class='hs-varid'>bindFreeVars</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- CoreBind -> VarSet</span> <a name="line-14"></a> <a name="line-15"></a> <span class='hs-comment'>-- * Selective free variables of expressions</span> <a name="line-16"></a> <span class='hs-conid'>InterestingVarFun</span><span class='hs-layout'>,</span> <a name="line-17"></a> <span class='hs-varid'>exprSomeFreeVars</span><span class='hs-layout'>,</span> <span class='hs-varid'>exprsSomeFreeVars</span><span class='hs-layout'>,</span> <a name="line-18"></a> <span class='hs-varid'>exprFreeNames</span><span class='hs-layout'>,</span> <span class='hs-varid'>exprsFreeNames</span><span class='hs-layout'>,</span> <a name="line-19"></a> <a name="line-20"></a> <span class='hs-comment'>-- * Free variables of Rules, Vars and Ids</span> <a name="line-21"></a> <span class='hs-varid'>idRuleVars</span><span class='hs-layout'>,</span> <span class='hs-varid'>idFreeVars</span><span class='hs-layout'>,</span> <span class='hs-varid'>varTypeTyVars</span><span class='hs-layout'>,</span> <span class='hs-varid'>varTypeTcTyVars</span><span class='hs-layout'>,</span> <a name="line-22"></a> <span class='hs-varid'>ruleRhsFreeVars</span><span class='hs-layout'>,</span> <span class='hs-varid'>rulesFreeVars</span><span class='hs-layout'>,</span> <a name="line-23"></a> <span class='hs-varid'>ruleLhsFreeNames</span><span class='hs-layout'>,</span> <span class='hs-varid'>ruleLhsFreeIds</span><span class='hs-layout'>,</span> <a name="line-24"></a> <a name="line-25"></a> <span class='hs-comment'>-- * Core syntax tree annotation with free variables</span> <a name="line-26"></a> <span class='hs-conid'>CoreExprWithFVs</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- = AnnExpr Id VarSet</span> <a name="line-27"></a> <span class='hs-conid'>CoreBindWithFVs</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- = AnnBind Id VarSet</span> <a name="line-28"></a> <span class='hs-varid'>freeVars</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- CoreExpr -> CoreExprWithFVs</span> <a name="line-29"></a> <span class='hs-varid'>freeVarsOf</span> <span class='hs-comment'>-- CoreExprWithFVs -> IdSet</span> <a name="line-30"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> <a name="line-31"></a> <a name="line-32"></a><span class='hs-cpp'>#include "HsVersions.h"</span> <a name="line-33"></a> <a name="line-34"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreSyn</span> <a name="line-35"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Id</span> <a name="line-36"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>IdInfo</span> <a name="line-37"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>NameSet</span> <a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>UniqFM</span> <a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Name</span> <a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>VarSet</span> <a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Var</span> <a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TcType</span> <a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Util</span> <a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span> </pre>\end{code} %************************************************************************ %* * \section{Finding the free variables of an expression} %* * %************************************************************************ This function simply finds the free variables of an expression. So far as type variables are concerned, it only finds tyvars that are * free in type arguments, * free in the type of a binder, but not those that are free in the type of variable occurrence. \begin{code} <pre><a name="line-1"></a><a name="exprFreeVars"></a><span class='hs-comment'>-- | Find all locally-defined free Ids or type variables in an expression</span> <a name="line-2"></a><span class='hs-definition'>exprFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-3"></a><span class='hs-definition'>exprFreeVars</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>exprSomeFreeVars</span> <span class='hs-varid'>isLocalVar</span> <a name="line-4"></a> <a name="line-5"></a><a name="exprsFreeVars"></a><span class='hs-comment'>-- | Find all locally-defined free Ids or type variables in several expressions</span> <a name="line-6"></a><span class='hs-definition'>exprsFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-7"></a><span class='hs-definition'>exprsFreeVars</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionVarSet</span> <span class='hs-varop'>.</span> <span class='hs-varid'>exprFreeVars</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-8"></a> <a name="line-9"></a><a name="bindFreeVars"></a><span class='hs-comment'>-- | Find all locally defined free Ids in a binding group</span> <a name="line-10"></a><span class='hs-definition'>bindFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreBind</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-11"></a><span class='hs-definition'>bindFreeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>exprFreeVars</span> <span class='hs-varid'>r</span> <a name="line-12"></a><span class='hs-definition'>bindFreeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>fst</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <a name="line-13"></a> <span class='hs-layout'>(</span><span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>union</span> <span class='hs-varop'>.</span> <span class='hs-varid'>rhs_fvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>noVars</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <a name="line-14"></a> <span class='hs-varid'>isLocalVar</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-15"></a> <a name="line-16"></a><a name="exprSomeFreeVars"></a><span class='hs-comment'>-- | Finds free variables in an expression selected by a predicate</span> <a name="line-17"></a><span class='hs-definition'>exprSomeFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InterestingVarFun</span> <span class='hs-comment'>-- ^ Says which 'Var's are interesting</span> <a name="line-18"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CoreExpr</span> <a name="line-19"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-20"></a><span class='hs-definition'>exprSomeFreeVars</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>e</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-21"></a> <a name="line-22"></a><a name="exprsSomeFreeVars"></a><span class='hs-comment'>-- | Finds free variables in several expressions selected by a predicate</span> <a name="line-23"></a><span class='hs-definition'>exprsSomeFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InterestingVarFun</span> <span class='hs-comment'>-- Says which 'Var's are interesting</span> <a name="line-24"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span> <a name="line-25"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-26"></a><span class='hs-definition'>exprsSomeFreeVars</span> <span class='hs-varid'>fv_cand</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionVarSet</span> <span class='hs-varop'>.</span> <span class='hs-varid'>exprSomeFreeVars</span> <span class='hs-varid'>fv_cand</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-27"></a> <a name="line-28"></a><a name="InterestingVarFun"></a><span class='hs-comment'>-- | Predicate on possible free variables: returns @True@ iff the variable is interesting</span> <a name="line-29"></a><a name="InterestingVarFun"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>InterestingVarFun</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> </pre>\end{code} \begin{code} <pre><a name="line-1"></a><a name="FV"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>InterestingVarFun</span> <a name="line-2"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <span class='hs-comment'>-- In scope</span> <a name="line-3"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <span class='hs-comment'>-- Free vars</span> <a name="line-4"></a> <a name="line-5"></a><a name="union"></a><span class='hs-definition'>union</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-6"></a><span class='hs-definition'>union</span> <span class='hs-varid'>fv1</span> <span class='hs-varid'>fv2</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fv1</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <span class='hs-varop'>`unionVarSet`</span> <span class='hs-varid'>fv2</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <a name="line-7"></a> <a name="line-8"></a><a name="noVars"></a><span class='hs-definition'>noVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FV</span> <a name="line-9"></a><span class='hs-definition'>noVars</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-10"></a> <a name="line-11"></a><span class='hs-comment'>-- Comment about obselete code</span> <a name="line-12"></a><span class='hs-comment'>-- We used to gather the free variables the RULES at a variable occurrence</span> <a name="line-13"></a><span class='hs-comment'>-- with the following cryptic comment:</span> <a name="line-14"></a><span class='hs-comment'>-- "At a variable occurrence, add in any free variables of its rule rhss</span> <a name="line-15"></a><span class='hs-comment'>-- Curiously, we gather the Id's free *type* variables from its binding</span> <a name="line-16"></a><span class='hs-comment'>-- site, but its free *rule-rhs* variables from its usage sites. This</span> <a name="line-17"></a><span class='hs-comment'>-- is a little weird. The reason is that the former is more efficient,</span> <a name="line-18"></a><span class='hs-comment'>-- but the latter is more fine grained, and a makes a difference when</span> <a name="line-19"></a><span class='hs-comment'>-- a variable mentions itself one of its own rule RHSs"</span> <a name="line-20"></a><span class='hs-comment'>-- Not only is this "weird", but it's also pretty bad because it can make</span> <a name="line-21"></a><span class='hs-comment'>-- a function seem more recursive than it is. Suppose</span> <a name="line-22"></a><span class='hs-comment'>-- f = ...g...</span> <a name="line-23"></a><span class='hs-comment'>-- g = ...</span> <a name="line-24"></a><span class='hs-comment'>-- RULE g x = ...f...</span> <a name="line-25"></a><span class='hs-comment'>-- Then f is not mentioned in its own RHS, and needn't be a loop breaker</span> <a name="line-26"></a><span class='hs-comment'>-- (though g may be). But if we collect the rule fvs from g's occurrence,</span> <a name="line-27"></a><span class='hs-comment'>-- it looks as if f mentions itself. (This bites in the eftInt/eftIntFB</span> <a name="line-28"></a><span class='hs-comment'>-- code in GHC.Enum.)</span> <a name="line-29"></a><span class='hs-comment'>-- </span> <a name="line-30"></a><span class='hs-comment'>-- Anyway, it seems plain wrong. The RULE is like an extra RHS for the</span> <a name="line-31"></a><span class='hs-comment'>-- function, so its free variables belong at the definition site.</span> <a name="line-32"></a><span class='hs-comment'>--</span> <a name="line-33"></a><span class='hs-comment'>-- Deleted code looked like</span> <a name="line-34"></a><span class='hs-comment'>-- foldVarSet add_rule_var var_itself_set (idRuleVars var)</span> <a name="line-35"></a><span class='hs-comment'>-- add_rule_var var set | keep_it fv_cand in_scope var = extendVarSet set var</span> <a name="line-36"></a><span class='hs-comment'>-- | otherwise = set</span> <a name="line-37"></a><span class='hs-comment'>-- SLPJ Feb06</span> <a name="line-38"></a> <a name="line-39"></a><a name="oneVar"></a><span class='hs-definition'>oneVar</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-40"></a><span class='hs-definition'>oneVar</span> <span class='hs-varid'>var</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <a name="line-41"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>isId</span> <span class='hs-varid'>var</span> <span class='hs-layout'>)</span> <a name="line-42"></a> <span class='hs-keyword'>if</span> <span class='hs-varid'>keep_it</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>var</span> <a name="line-43"></a> <span class='hs-keyword'>then</span> <span class='hs-varid'>unitVarSet</span> <span class='hs-varid'>var</span> <a name="line-44"></a> <span class='hs-keyword'>else</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-45"></a> <a name="line-46"></a><a name="someVars"></a><span class='hs-definition'>someVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-47"></a><span class='hs-definition'>someVars</span> <span class='hs-varid'>vars</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <a name="line-48"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>filterVarSet</span> <span class='hs-layout'>(</span><span class='hs-varid'>keep_it</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span><span class='hs-layout'>)</span> <span class='hs-varid'>vars</span> <a name="line-49"></a> <a name="line-50"></a><a name="keep_it"></a><span class='hs-definition'>keep_it</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InterestingVarFun</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-51"></a><span class='hs-definition'>keep_it</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>var</span> <a name="line-52"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>var</span> <span class='hs-varop'>`elemVarSet`</span> <span class='hs-varid'>in_scope</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span> <a name="line-53"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>var</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span> <a name="line-54"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span> <a name="line-55"></a> <a name="line-56"></a> <a name="line-57"></a><a name="addBndr"></a><span class='hs-definition'>addBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreBndr</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-58"></a><span class='hs-definition'>addBndr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>fv</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <a name="line-59"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>someVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>varTypeTyVars</span> <span class='hs-varid'>bndr</span><span class='hs-layout'>)</span> <span class='hs-varid'>fv_cand</span> <span class='hs-varid'>in_scope</span> <a name="line-60"></a> <span class='hs-comment'>-- Include type varibles in the binder's type</span> <a name="line-61"></a> <span class='hs-comment'>-- (not just Ids; coercion variables too!)</span> <a name="line-62"></a> <span class='hs-varop'>`unionVarSet`</span> <span class='hs-varid'>fv</span> <span class='hs-varid'>fv_cand</span> <span class='hs-layout'>(</span><span class='hs-varid'>in_scope</span> <span class='hs-varop'>`extendVarSet`</span> <span class='hs-varid'>bndr</span><span class='hs-layout'>)</span> <a name="line-63"></a> <a name="line-64"></a><a name="addBndrs"></a><span class='hs-definition'>addBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBndr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-65"></a><span class='hs-definition'>addBndrs</span> <span class='hs-varid'>bndrs</span> <span class='hs-varid'>fv</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-varid'>addBndr</span> <span class='hs-varid'>fv</span> <span class='hs-varid'>bndrs</span> </pre>\end{code} \begin{code} <pre><a name="line-1"></a><a name="expr_fvs"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-2"></a> <a name="line-3"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>someVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <a name="line-4"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>var</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>oneVar</span> <span class='hs-varid'>var</span> <a name="line-5"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lit</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>noVars</span> <a name="line-6"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>expr</span> <a name="line-7"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>fun</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>fun</span> <span class='hs-varop'>`union`</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>arg</span> <a name="line-8"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndr</span> <span class='hs-varid'>bndr</span> <span class='hs-layout'>(</span><span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-9"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cast</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>expr</span> <span class='hs-varop'>`union`</span> <span class='hs-varid'>someVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <a name="line-10"></a> <a name="line-11"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Case</span> <span class='hs-varid'>scrut</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span> <a name="line-12"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>scrut</span> <span class='hs-varop'>`union`</span> <span class='hs-varid'>someVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-varop'>`union`</span> <span class='hs-varid'>addBndr</span> <span class='hs-varid'>bndr</span> <a name="line-13"></a> <span class='hs-layout'>(</span><span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>union</span> <span class='hs-varop'>.</span> <span class='hs-varid'>alt_fvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>noVars</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span> <a name="line-14"></a> <span class='hs-keyword'>where</span> <a name="line-15"></a> <span class='hs-varid'>alt_fvs</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndrs</span> <span class='hs-varid'>bndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <a name="line-16"></a> <a name="line-17"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-18"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rhs_fvs</span> <span class='hs-layout'>(</span><span class='hs-varid'>bndr</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varop'>`union`</span> <span class='hs-varid'>addBndr</span> <span class='hs-varid'>bndr</span> <span class='hs-layout'>(</span><span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-19"></a> <a name="line-20"></a><span class='hs-definition'>expr_fvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-21"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>fst</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <a name="line-22"></a> <span class='hs-layout'>(</span><span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>union</span> <span class='hs-varop'>.</span> <span class='hs-varid'>rhs_fvs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <a name="line-23"></a> <a name="line-24"></a><a name="rhs_fvs"></a><span class='hs-comment'>---------</span> <a name="line-25"></a><span class='hs-definition'>rhs_fvs</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span><span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-26"></a><span class='hs-definition'>rhs_fvs</span> <span class='hs-layout'>(</span><span class='hs-varid'>bndr</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>rhs</span> <span class='hs-varop'>`union`</span> <span class='hs-varid'>someVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>bndrRuleVars</span> <span class='hs-varid'>bndr</span><span class='hs-layout'>)</span> <a name="line-27"></a> <span class='hs-comment'>-- Treat any RULES as extra RHSs of the binding</span> <a name="line-28"></a> <a name="line-29"></a><a name="exprs_fvs"></a><span class='hs-comment'>---------</span> <a name="line-30"></a><span class='hs-definition'>exprs_fvs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FV</span> <a name="line-31"></a><span class='hs-definition'>exprs_fvs</span> <span class='hs-varid'>exprs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>union</span> <span class='hs-varop'>.</span> <span class='hs-varid'>expr_fvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>noVars</span> <span class='hs-varid'>exprs</span> </pre>\end{code} %************************************************************************ %* * \section{Free names} %* * %************************************************************************ \begin{code} <pre><a name="line-1"></a><a name="ruleLhsFreeNames"></a><span class='hs-comment'>-- | Similar to 'exprFreeNames'. However, this is used when deciding whether </span> <a name="line-2"></a><span class='hs-comment'>-- a rule is an orphan. In particular, suppose that T is defined in this </span> <a name="line-3"></a><span class='hs-comment'>-- module; we want to avoid declaring that a rule like:</span> <a name="line-4"></a><span class='hs-comment'>-- </span> <a name="line-5"></a><span class='hs-comment'>-- > fromIntegral T = fromIntegral_T</span> <a name="line-6"></a><span class='hs-comment'>--</span> <a name="line-7"></a><span class='hs-comment'>-- is an orphan. Of course it isn't, and declaring it an orphan would</span> <a name="line-8"></a><span class='hs-comment'>-- make the whole module an orphan module, which is bad.</span> <a name="line-9"></a><span class='hs-definition'>ruleLhsFreeNames</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>NameSet</span> <a name="line-10"></a><span class='hs-definition'>ruleLhsFreeNames</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fn</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unitNameSet</span> <span class='hs-varid'>fn</span> <a name="line-11"></a><span class='hs-definition'>ruleLhsFreeNames</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fn</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tpl_args</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <a name="line-12"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addOneToNameSet</span> <span class='hs-layout'>(</span><span class='hs-varid'>exprsFreeNames</span> <span class='hs-varid'>tpl_args</span><span class='hs-layout'>)</span> <span class='hs-varid'>fn</span> <a name="line-13"></a> <a name="line-14"></a><a name="exprFreeNames"></a><span class='hs-comment'>-- | Finds the free /external/ names of an expression, notably</span> <a name="line-15"></a><span class='hs-comment'>-- including the names of type constructors (which of course do not show</span> <a name="line-16"></a><span class='hs-comment'>-- up in 'exprFreeVars').</span> <a name="line-17"></a><span class='hs-definition'>exprFreeNames</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>NameSet</span> <a name="line-18"></a><span class='hs-comment'>-- There's no need to delete local binders, because they will all</span> <a name="line-19"></a><span class='hs-comment'>-- be /internal/ names.</span> <a name="line-20"></a><span class='hs-definition'>exprFreeNames</span> <span class='hs-varid'>e</span> <a name="line-21"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <a name="line-22"></a> <span class='hs-keyword'>where</span> <a name="line-23"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <a name="line-24"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isExternalName</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unitNameSet</span> <span class='hs-varid'>n</span> <a name="line-25"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyNameSet</span> <a name="line-26"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idName</span> <span class='hs-varid'>v</span> <a name="line-27"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lit</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyNameSet</span> <a name="line-28"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyClsNamesOfType</span> <span class='hs-varid'>ty</span> <span class='hs-comment'>-- Don't need free tyvars</span> <a name="line-29"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>e1</span> <span class='hs-varid'>e2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e1</span> <span class='hs-varop'>`unionNameSets`</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e2</span> <a name="line-30"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>v</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`delFromNameSet`</span> <span class='hs-varid'>idName</span> <span class='hs-varid'>v</span> <a name="line-31"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <a name="line-32"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cast</span> <span class='hs-varid'>e</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`unionNameSets`</span> <span class='hs-varid'>tyClsNamesOfType</span> <span class='hs-varid'>co</span> <a name="line-33"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`unionNameSets`</span> <span class='hs-varid'>go</span> <span class='hs-varid'>r</span> <a name="line-34"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>exprsFreeNames</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>snd</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-varop'>`unionNameSets`</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <a name="line-35"></a> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>ty</span> <span class='hs-keyword'>as</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`unionNameSets`</span> <span class='hs-varid'>tyClsNamesOfType</span> <span class='hs-varid'>ty</span> <a name="line-36"></a> <span class='hs-varop'>`unionNameSets`</span> <span class='hs-varid'>unionManyNameSets</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>go_alt</span> <span class='hs-keyword'>as</span><span class='hs-layout'>)</span> <a name="line-37"></a> <a name="line-38"></a> <span class='hs-varid'>go_alt</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>r</span> <a name="line-39"></a> <a name="line-40"></a><a name="exprsFreeNames"></a><span class='hs-comment'>-- | Finds the free /external/ names of several expressions: see 'exprFreeNames' for details</span> <a name="line-41"></a><span class='hs-definition'>exprsFreeNames</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>NameSet</span> <a name="line-42"></a><span class='hs-definition'>exprsFreeNames</span> <span class='hs-varid'>es</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionNameSets</span> <span class='hs-varop'>.</span> <span class='hs-varid'>exprFreeNames</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyNameSet</span> <span class='hs-varid'>es</span> </pre>\end{code} %************************************************************************ %* * \section[freevars-everywhere]{Attaching free variables to every sub-expression} %* * %************************************************************************ \begin{code} <pre><a name="line-1"></a><a name="ruleRhsFreeVars"></a><span class='hs-comment'>-- | Those variables free in the right hand side of a rule</span> <a name="line-2"></a><span class='hs-definition'>ruleRhsFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-3"></a><span class='hs-definition'>ruleRhsFreeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>noFVs</span> <a name="line-4"></a><span class='hs-definition'>ruleRhsFreeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fn</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_rhs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rhs</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <a name="line-5"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>delFromUFM</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>fn</span> <span class='hs-comment'>-- Note [Rule free var hack]</span> <a name="line-6"></a> <span class='hs-keyword'>where</span> <a name="line-7"></a> <span class='hs-varid'>fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndrs</span> <span class='hs-varid'>bndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>expr_fvs</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>isLocalVar</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-8"></a> <a name="line-9"></a><a name="ruleFreeVars"></a><span class='hs-comment'>-- | Those variables free in the both the left right hand sides of a rule</span> <a name="line-10"></a><span class='hs-definition'>ruleFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-11"></a><span class='hs-definition'>ruleFreeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fn</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_rhs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>args</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <a name="line-12"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>delFromUFM</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>fn</span> <span class='hs-comment'>-- Note [Rule free var hack]</span> <a name="line-13"></a> <span class='hs-keyword'>where</span> <a name="line-14"></a> <span class='hs-varid'>fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndrs</span> <span class='hs-varid'>bndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>exprs_fvs</span> <span class='hs-layout'>(</span><span class='hs-varid'>rhs</span><span class='hs-conop'>:</span><span class='hs-varid'>args</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>isLocalVar</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-15"></a> <a name="line-16"></a><a name="rulesFreeVars"></a><span class='hs-comment'>-- | Those variables free in the right hand side of several rules</span> <a name="line-17"></a><span class='hs-definition'>rulesFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreRule</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-18"></a><span class='hs-definition'>rulesFreeVars</span> <span class='hs-varid'>rules</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionVarSet</span> <span class='hs-varop'>.</span> <span class='hs-varid'>ruleFreeVars</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyVarSet</span> <span class='hs-varid'>rules</span> <a name="line-19"></a> <a name="line-20"></a><a name="ruleLhsFreeIds"></a><span class='hs-definition'>ruleLhsFreeIds</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-21"></a><span class='hs-comment'>-- ^ This finds all locally-defined free Ids on the left hand side of a rule</span> <a name="line-22"></a><span class='hs-definition'>ruleLhsFreeIds</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>noFVs</span> <a name="line-23"></a><span class='hs-definition'>ruleLhsFreeIds</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>args</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <a name="line-24"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addBndrs</span> <span class='hs-varid'>bndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>exprs_fvs</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span> <span class='hs-varid'>isLocalId</span> <span class='hs-varid'>emptyVarSet</span> </pre>\end{code} Note [Rule free var hack] ~~~~~~~~~~~~~~~~~~~~~~~~~ Don't include the Id in its own rhs free-var set. Otherwise the occurrence analyser makes bindings recursive that shoudn't be. E.g. RULE: f (f x y) z ==> f x (f y z) Also since rule_fn is a Name, not a Var, we have to use the grungy delUFM. %************************************************************************ %* * \section[freevars-everywhere]{Attaching free variables to every sub-expression} %* * %************************************************************************ The free variable pass annotates every node in the expression with its NON-GLOBAL free variables and type variables. \begin{code} <pre><a name="line-1"></a><a name="CoreBindWithFVs"></a><span class='hs-comment'>-- | Every node in a binding group annotated with its </span> <a name="line-2"></a><a name="CoreBindWithFVs"></a><span class='hs-comment'>-- (non-global) free variables, both Ids and TyVars</span> <a name="line-3"></a><a name="CoreBindWithFVs"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreBindWithFVs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AnnBind</span> <span class='hs-conid'>Id</span> <span class='hs-conid'>VarSet</span> <a name="line-4"></a><a name="CoreExprWithFVs"></a><span class='hs-comment'>-- | Every node in an expression annotated with its </span> <a name="line-5"></a><a name="CoreExprWithFVs"></a><span class='hs-comment'>-- (non-global) free variables, both Ids and TyVars</span> <a name="line-6"></a><a name="CoreExprWithFVs"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreExprWithFVs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-conid'>Id</span> <span class='hs-conid'>VarSet</span> <a name="line-7"></a> <a name="line-8"></a><a name="freeVarsOf"></a><span class='hs-definition'>freeVarsOf</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExprWithFVs</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IdSet</span> <a name="line-9"></a><span class='hs-comment'>-- ^ Inverse function to 'freeVars'</span> <a name="line-10"></a><span class='hs-definition'>freeVarsOf</span> <span class='hs-layout'>(</span><span class='hs-varid'>free_vars</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>free_vars</span> <a name="line-11"></a> <a name="line-12"></a><a name="noFVs"></a><span class='hs-definition'>noFVs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>VarSet</span> <a name="line-13"></a><span class='hs-definition'>noFVs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-14"></a> <a name="line-15"></a><a name="aFreeVar"></a><span class='hs-definition'>aFreeVar</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-16"></a><span class='hs-definition'>aFreeVar</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unitVarSet</span> <a name="line-17"></a> <a name="line-18"></a><a name="unionFVs"></a><span class='hs-definition'>unionFVs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-19"></a><span class='hs-definition'>unionFVs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unionVarSet</span> <a name="line-20"></a> <a name="line-21"></a><a name="delBindersFV"></a><span class='hs-definition'>delBindersFV</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Var</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-22"></a><span class='hs-definition'>delBindersFV</span> <span class='hs-varid'>bs</span> <span class='hs-varid'>fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-varid'>delBinderFV</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>bs</span> <a name="line-23"></a> <a name="line-24"></a><a name="delBinderFV"></a><span class='hs-definition'>delBinderFV</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-25"></a><span class='hs-comment'>-- This way round, so we can do it multiple times using foldr</span> <a name="line-26"></a> <a name="line-27"></a><span class='hs-comment'>-- (b `delBinderFV` s) removes the binder b from the free variable set s,</span> <a name="line-28"></a><span class='hs-comment'>-- but *adds* to s</span> <a name="line-29"></a><span class='hs-comment'>-- (a) the free variables of b's type</span> <a name="line-30"></a><span class='hs-comment'>-- (b) the idSpecVars of b</span> <a name="line-31"></a><span class='hs-comment'>--</span> <a name="line-32"></a><span class='hs-comment'>-- This is really important for some lambdas:</span> <a name="line-33"></a><span class='hs-comment'>-- In (\x::a -> x) the only mention of "a" is in the binder.</span> <a name="line-34"></a><span class='hs-comment'>--</span> <a name="line-35"></a><span class='hs-comment'>-- Also in</span> <a name="line-36"></a><span class='hs-comment'>-- let x::a = b in ...</span> <a name="line-37"></a><span class='hs-comment'>-- we should really note that "a" is free in this expression.</span> <a name="line-38"></a><span class='hs-comment'>-- It'll be pinned inside the /\a by the binding for b, but</span> <a name="line-39"></a><span class='hs-comment'>-- it seems cleaner to make sure that a is in the free-var set </span> <a name="line-40"></a><span class='hs-comment'>-- when it is mentioned.</span> <a name="line-41"></a><span class='hs-comment'>--</span> <a name="line-42"></a><span class='hs-comment'>-- This also shows up in recursive bindings. Consider:</span> <a name="line-43"></a><span class='hs-comment'>-- /\a -> letrec x::a = x in E</span> <a name="line-44"></a><span class='hs-comment'>-- Now, there are no explicit free type variables in the RHS of x,</span> <a name="line-45"></a><span class='hs-comment'>-- but nevertheless "a" is free in its definition. So we add in</span> <a name="line-46"></a><span class='hs-comment'>-- the free tyvars of the types of the binders, and include these in the</span> <a name="line-47"></a><span class='hs-comment'>-- free vars of the group, attached to the top level of each RHS.</span> <a name="line-48"></a><span class='hs-comment'>--</span> <a name="line-49"></a><span class='hs-comment'>-- This actually happened in the defn of errorIO in IOBase.lhs:</span> <a name="line-50"></a><span class='hs-comment'>-- errorIO (ST io) = case (errorIO# io) of</span> <a name="line-51"></a><span class='hs-comment'>-- _ -> bottom</span> <a name="line-52"></a><span class='hs-comment'>-- where</span> <a name="line-53"></a><span class='hs-comment'>-- bottom = bottom -- Never evaluated</span> <a name="line-54"></a> <a name="line-55"></a><span class='hs-definition'>delBinderFV</span> <span class='hs-varid'>b</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-varop'>`delVarSet`</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>varTypeTyVars</span> <span class='hs-varid'>b</span> <a name="line-56"></a> <span class='hs-comment'>-- Include coercion variables too!</span> <a name="line-57"></a> <a name="line-58"></a><a name="varTypeTyVars"></a><span class='hs-definition'>varTypeTyVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>TyVarSet</span> <a name="line-59"></a><span class='hs-comment'>-- Find the type variables free in the type of the variable</span> <a name="line-60"></a><span class='hs-comment'>-- Remember, coercion variables can mention type variables...</span> <a name="line-61"></a><span class='hs-definition'>varTypeTyVars</span> <span class='hs-varid'>var</span> <a name="line-62"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isLocalId</span> <span class='hs-varid'>var</span> <span class='hs-varop'>||</span> <span class='hs-varid'>isCoVar</span> <span class='hs-varid'>var</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyVarsOfType</span> <span class='hs-layout'>(</span><span class='hs-varid'>idType</span> <span class='hs-varid'>var</span><span class='hs-layout'>)</span> <a name="line-63"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyVarSet</span> <span class='hs-comment'>-- Global Ids and non-coercion TyVars</span> <a name="line-64"></a> <a name="line-65"></a><a name="varTypeTcTyVars"></a><span class='hs-definition'>varTypeTcTyVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>TyVarSet</span> <a name="line-66"></a><span class='hs-comment'>-- Find the type variables free in the type of the variable</span> <a name="line-67"></a><span class='hs-comment'>-- Remember, coercion variables can mention type variables...</span> <a name="line-68"></a><span class='hs-definition'>varTypeTcTyVars</span> <span class='hs-varid'>var</span> <a name="line-69"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isLocalId</span> <span class='hs-varid'>var</span> <span class='hs-varop'>||</span> <span class='hs-varid'>isCoVar</span> <span class='hs-varid'>var</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tcTyVarsOfType</span> <span class='hs-layout'>(</span><span class='hs-varid'>idType</span> <span class='hs-varid'>var</span><span class='hs-layout'>)</span> <a name="line-70"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyVarSet</span> <span class='hs-comment'>-- Global Ids and non-coercion TyVars</span> <a name="line-71"></a> <a name="line-72"></a><a name="idFreeVars"></a><span class='hs-definition'>idFreeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-73"></a><span class='hs-definition'>idFreeVars</span> <span class='hs-varid'>id</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>isId</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span> <span class='hs-varid'>idRuleVars</span> <span class='hs-varid'>id</span> <span class='hs-varop'>`unionVarSet`</span> <span class='hs-varid'>varTypeTyVars</span> <span class='hs-varid'>id</span> <a name="line-74"></a> <a name="line-75"></a><a name="bndrRuleVars"></a><span class='hs-definition'>bndrRuleVars</span> <span class='hs-keyglyph'>::</span><span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-76"></a><span class='hs-definition'>bndrRuleVars</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isTyVar</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>emptyVarSet</span> <a name="line-77"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idRuleVars</span> <span class='hs-varid'>v</span> <a name="line-78"></a> <a name="line-79"></a><a name="idRuleVars"></a><span class='hs-definition'>idRuleVars</span> <span class='hs-keyglyph'>::</span><span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>VarSet</span> <a name="line-80"></a><span class='hs-definition'>idRuleVars</span> <span class='hs-varid'>id</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>isId</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span> <span class='hs-varid'>specInfoFreeVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>idSpecialisation</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span> </pre>\end{code} %************************************************************************ %* * \subsection{Free variables (and types)} %* * %************************************************************************ \begin{code} <pre><a name="line-1"></a><a name="freeVars"></a><span class='hs-definition'>freeVars</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CoreExprWithFVs</span> <a name="line-2"></a><span class='hs-comment'>-- ^ Annotate a 'CoreExpr' with its (non-global) free type and value variables at every tree node</span> <a name="line-3"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <a name="line-4"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>fvs</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnVar</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <a name="line-5"></a> <span class='hs-keyword'>where</span> <a name="line-6"></a> <span class='hs-comment'>-- ToDo: insert motivating example for why we *need*</span> <a name="line-7"></a> <span class='hs-comment'>-- to include the idSpecVars in the FV list.</span> <a name="line-8"></a> <span class='hs-comment'>-- Actually [June 98] I don't think it's necessary</span> <a name="line-9"></a> <span class='hs-comment'>-- fvs = fvs_v `unionVarSet` idSpecVars v</span> <a name="line-10"></a> <a name="line-11"></a> <span class='hs-varid'>fvs</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isLocalVar</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>aFreeVar</span> <span class='hs-varid'>v</span> <a name="line-12"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>noFVs</span> <a name="line-13"></a> <a name="line-14"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lit</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>noFVs</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnLit</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span> <a name="line-15"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-16"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span> <span class='hs-varop'>`delBinderFV`</span> <span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>body'</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnLam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span> <a name="line-17"></a> <span class='hs-keyword'>where</span> <a name="line-18"></a> <span class='hs-varid'>body'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>body</span> <a name="line-19"></a> <a name="line-20"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>fun</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span> <a name="line-21"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>fun2</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>arg2</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnApp</span> <span class='hs-varid'>fun2</span> <span class='hs-varid'>arg2</span><span class='hs-layout'>)</span> <a name="line-22"></a> <span class='hs-keyword'>where</span> <a name="line-23"></a> <span class='hs-varid'>fun2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>fun</span> <a name="line-24"></a> <span class='hs-varid'>arg2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>arg</span> <a name="line-25"></a> <a name="line-26"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Case</span> <span class='hs-varid'>scrut</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span> <a name="line-27"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>bndr</span> <span class='hs-varop'>`delBinderFV`</span> <span class='hs-varid'>alts_fvs</span><span class='hs-layout'>)</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>scrut2</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span> <a name="line-28"></a> <span class='hs-conid'>AnnCase</span> <span class='hs-varid'>scrut2</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>alts2</span><span class='hs-layout'>)</span> <a name="line-29"></a> <span class='hs-keyword'>where</span> <a name="line-30"></a> <span class='hs-varid'>scrut2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>scrut</span> <a name="line-31"></a> <a name="line-32"></a> <span class='hs-layout'>(</span><span class='hs-varid'>alts_fvs_s</span><span class='hs-layout'>,</span> <span class='hs-varid'>alts2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapAndUnzip</span> <span class='hs-varid'>fv_alt</span> <span class='hs-varid'>alts</span> <a name="line-33"></a> <span class='hs-varid'>alts_fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr1</span> <span class='hs-varid'>unionFVs</span> <span class='hs-varid'>alts_fvs_s</span> <a name="line-34"></a> <a name="line-35"></a> <span class='hs-varid'>fv_alt</span> <span class='hs-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span><span class='hs-varid'>args</span><span class='hs-layout'>,</span><span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>delBindersFV</span> <span class='hs-varid'>args</span> <span class='hs-layout'>(</span><span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>rhs2</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-36"></a> <span class='hs-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span> <span class='hs-varid'>args</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-37"></a> <span class='hs-keyword'>where</span> <a name="line-38"></a> <span class='hs-varid'>rhs2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>rhs</span> <a name="line-39"></a> <a name="line-40"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-41"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>rhs2</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>body_fvs</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>bndrRuleVars</span> <span class='hs-varid'>binder</span><span class='hs-layout'>,</span> <a name="line-42"></a> <span class='hs-comment'>-- Remember any rules; cf rhs_fvs above</span> <a name="line-43"></a> <span class='hs-conid'>AnnLet</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnNonRec</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>rhs2</span><span class='hs-layout'>)</span> <span class='hs-varid'>body2</span><span class='hs-layout'>)</span> <a name="line-44"></a> <span class='hs-keyword'>where</span> <a name="line-45"></a> <span class='hs-varid'>rhs2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>rhs</span> <a name="line-46"></a> <span class='hs-varid'>body2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>body</span> <a name="line-47"></a> <span class='hs-varid'>body_fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>binder</span> <span class='hs-varop'>`delBinderFV`</span> <span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>body2</span> <a name="line-48"></a> <a name="line-49"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>binds</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-50"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>delBindersFV</span> <span class='hs-varid'>binders</span> <span class='hs-varid'>all_fvs</span><span class='hs-layout'>,</span> <a name="line-51"></a> <span class='hs-conid'>AnnLet</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnRec</span> <span class='hs-layout'>(</span><span class='hs-varid'>binders</span> <span class='hs-varop'>`zip`</span> <span class='hs-varid'>rhss2</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>body2</span><span class='hs-layout'>)</span> <a name="line-52"></a> <span class='hs-keyword'>where</span> <a name="line-53"></a> <span class='hs-layout'>(</span><span class='hs-varid'>binders</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhss</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unzip</span> <span class='hs-varid'>binds</span> <a name="line-54"></a> <a name="line-55"></a> <span class='hs-varid'>rhss2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>rhss</span> <a name="line-56"></a> <span class='hs-varid'>rhs_body_fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionFVs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>freeVarsOf</span><span class='hs-layout'>)</span> <span class='hs-varid'>body_fvs</span> <span class='hs-varid'>rhss2</span> <a name="line-57"></a> <span class='hs-varid'>all_fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionFVs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>idRuleVars</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs_body_fvs</span> <span class='hs-varid'>binders</span> <a name="line-58"></a> <span class='hs-comment'>-- The "delBinderFV" happens after adding the idSpecVars,</span> <a name="line-59"></a> <span class='hs-comment'>-- since the latter may add some of the binders as fvs</span> <a name="line-60"></a> <a name="line-61"></a> <span class='hs-varid'>body2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>body</span> <a name="line-62"></a> <span class='hs-varid'>body_fvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>body2</span> <a name="line-63"></a> <a name="line-64"></a> <a name="line-65"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cast</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <a name="line-66"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>expr2</span> <span class='hs-varop'>`unionFVs`</span> <span class='hs-varid'>cfvs</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnCast</span> <span class='hs-varid'>expr2</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <a name="line-67"></a> <span class='hs-keyword'>where</span> <a name="line-68"></a> <span class='hs-varid'>expr2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>expr</span> <a name="line-69"></a> <span class='hs-varid'>cfvs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>co</span> <a name="line-70"></a> <a name="line-71"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-varid'>other_note</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <a name="line-72"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>freeVarsOf</span> <span class='hs-varid'>expr2</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnNote</span> <span class='hs-varid'>other_note</span> <span class='hs-varid'>expr2</span><span class='hs-layout'>)</span> <a name="line-73"></a> <span class='hs-keyword'>where</span> <a name="line-74"></a> <span class='hs-varid'>expr2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>freeVars</span> <span class='hs-varid'>expr</span> <a name="line-75"></a> <a name="line-76"></a><span class='hs-definition'>freeVars</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnType</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> </pre>\end{code} </body> </html>