Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 8d1ef08c9e0d44c69764afc615a03d0d > files > 1675

ghc-ghc-devel-6.12.3-5.fc14.i686.rpm

<?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   -&gt; 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] -&gt; VarSet</span>
<a name="line-13"></a>	<span class='hs-varid'>bindFreeVars</span><span class='hs-layout'>,</span> 	<span class='hs-comment'>-- CoreBind   -&gt; 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 -&gt; CoreExprWithFVs</span>
<a name="line-29"></a>	<span class='hs-varid'>freeVarsOf</span>		<span class='hs-comment'>-- CoreExprWithFVs -&gt; 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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-19"></a>		 <span class='hs-keyglyph'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>VarSet</span>		<span class='hs-comment'>-- In scope</span>
<a name="line-3"></a>	<span class='hs-keyglyph'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>FV</span> <span class='hs-keyglyph'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-- &gt; 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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-&gt;</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'>-&gt;</span> <span class='hs-conid'>VarSet</span> <span class='hs-keyglyph'>-&gt;</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 -&gt; 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 -&gt; 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'>--	    		    _ -&gt; 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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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'>-&gt;</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>