Sophie

Sophie

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

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/CoreSubst.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
%

Utility functions on @Core@ syntax

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>CoreSubst</span> <span class='hs-layout'>(</span>
<a name="line-2"></a>	<span class='hs-comment'>-- * Main data types</span>
<a name="line-3"></a>	<span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>TvSubstEnv</span><span class='hs-layout'>,</span> <span class='hs-conid'>IdSubstEnv</span><span class='hs-layout'>,</span> <span class='hs-conid'>InScopeSet</span><span class='hs-layout'>,</span>
<a name="line-4"></a>
<a name="line-5"></a>        <span class='hs-comment'>-- ** Substituting into expressions and related types</span>
<a name="line-6"></a>	<span class='hs-varid'>deShadowBinds</span><span class='hs-layout'>,</span>
<a name="line-7"></a>	<span class='hs-varid'>substTy</span><span class='hs-layout'>,</span> <span class='hs-varid'>substExpr</span><span class='hs-layout'>,</span> <span class='hs-varid'>substBind</span><span class='hs-layout'>,</span> <span class='hs-varid'>substSpec</span><span class='hs-layout'>,</span> <span class='hs-varid'>substWorker</span><span class='hs-layout'>,</span>
<a name="line-8"></a>	<span class='hs-varid'>lookupIdSubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>lookupTvSubst</span><span class='hs-layout'>,</span> 
<a name="line-9"></a>
<a name="line-10"></a>        <span class='hs-comment'>-- ** Operations on substitutions</span>
<a name="line-11"></a>	<span class='hs-varid'>emptySubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkEmptySubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkSubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>substInScope</span><span class='hs-layout'>,</span> <span class='hs-varid'>isEmptySubst</span><span class='hs-layout'>,</span> 
<a name="line-12"></a> 	<span class='hs-varid'>extendIdSubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>extendIdSubstList</span><span class='hs-layout'>,</span> <span class='hs-varid'>extendTvSubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>extendTvSubstList</span><span class='hs-layout'>,</span>
<a name="line-13"></a>	<span class='hs-varid'>extendSubst</span><span class='hs-layout'>,</span> <span class='hs-varid'>extendSubstList</span><span class='hs-layout'>,</span> <span class='hs-varid'>zapSubstEnv</span><span class='hs-layout'>,</span>
<a name="line-14"></a>	<span class='hs-varid'>extendInScope</span><span class='hs-layout'>,</span> <span class='hs-varid'>extendInScopeList</span><span class='hs-layout'>,</span> <span class='hs-varid'>extendInScopeIds</span><span class='hs-layout'>,</span> 
<a name="line-15"></a>	<span class='hs-varid'>isInScope</span><span class='hs-layout'>,</span>
<a name="line-16"></a>
<a name="line-17"></a>	<span class='hs-comment'>-- ** Substituting and cloning binders</span>
<a name="line-18"></a>	<span class='hs-varid'>substBndr</span><span class='hs-layout'>,</span> <span class='hs-varid'>substBndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>substRecBndrs</span><span class='hs-layout'>,</span>
<a name="line-19"></a>	<span class='hs-varid'>cloneIdBndr</span><span class='hs-layout'>,</span> <span class='hs-varid'>cloneIdBndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>cloneRecIdBndrs</span>
<a name="line-20"></a>    <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-21"></a>
<a name="line-22"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-23"></a>
<a name="line-24"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreSyn</span>
<a name="line-25"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreFVs</span>
<a name="line-26"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreUtils</span>
<a name="line-27"></a>
<a name="line-28"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Type</span>
<a name="line-29"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span>     <span class='hs-layout'>(</span> <span class='hs-conid'>Type</span><span class='hs-layout'>,</span> <span class='hs-conid'>TvSubst</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>TvSubstEnv</span> <span class='hs-layout'>)</span>
<a name="line-30"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>VarSet</span>
<a name="line-31"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>VarEnv</span>
<a name="line-32"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Id</span>
<a name="line-33"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Var</span>      <span class='hs-layout'>(</span> <span class='hs-conid'>Var</span><span class='hs-layout'>,</span> <span class='hs-conid'>TyVar</span><span class='hs-layout'>,</span> <span class='hs-varid'>setVarUnique</span> <span class='hs-layout'>)</span>
<a name="line-34"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>IdInfo</span>
<a name="line-35"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Unique</span>
<a name="line-36"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>UniqSupply</span>
<a name="line-37"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Maybes</span>
<a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span>
<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>PprCore</span>		<span class='hs-conid'>()</span>		<span class='hs-comment'>-- Instances</span>
<a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastString</span>
<a name="line-41"></a>
<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>List</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection{Substitutions}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="Subst"></a><span class='hs-comment'>-- | A substitution environment, containing both 'Id' and 'TyVar' substitutions.</span>
<a name="line-2"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-3"></a><a name="Subst"></a><span class='hs-comment'>-- Some invariants apply to how you use the substitution:</span>
<a name="line-4"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-5"></a><a name="Subst"></a><span class='hs-comment'>-- 1. #in_scope_invariant# The in-scope set contains at least those 'Id's and 'TyVar's that will be in scope /after/</span>
<a name="line-6"></a><a name="Subst"></a><span class='hs-comment'>-- applying the substitution to a term. Precisely, the in-scope set must be a superset of the free vars of the</span>
<a name="line-7"></a><a name="Subst"></a><span class='hs-comment'>-- substitution range that might possibly clash with locally-bound variables in the thing being substituted in.</span>
<a name="line-8"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-9"></a><a name="Subst"></a><span class='hs-comment'>-- 2. #apply_once# You may apply the substitution only /once/</span>
<a name="line-10"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-11"></a><a name="Subst"></a><span class='hs-comment'>-- There are various ways of setting up the in-scope set such that the first of these invariants hold:</span>
<a name="line-12"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-13"></a><a name="Subst"></a><span class='hs-comment'>-- * Arrange that the in-scope set really is all the things in scope</span>
<a name="line-14"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-15"></a><a name="Subst"></a><span class='hs-comment'>-- * Arrange that it's the free vars of the range of the substitution</span>
<a name="line-16"></a><a name="Subst"></a><span class='hs-comment'>--</span>
<a name="line-17"></a><a name="Subst"></a><span class='hs-comment'>-- * Make it empty, if you know that all the free vars of the substitution are fresh, and hence can't possibly clash</span>
<a name="line-18"></a><a name="Subst"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Subst</span> 
<a name="line-19"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-conid'>InScopeSet</span>  <span class='hs-comment'>-- Variables in in scope (both Ids and TyVars) /after/</span>
<a name="line-20"></a>                      <span class='hs-comment'>-- applying the substitution</span>
<a name="line-21"></a>          <span class='hs-conid'>IdSubstEnv</span>  <span class='hs-comment'>-- Substitution for Ids</span>
<a name="line-22"></a>          <span class='hs-conid'>TvSubstEnv</span>  <span class='hs-comment'>-- Substitution for TyVars</span>
<a name="line-23"></a>
<a name="line-24"></a>	<span class='hs-comment'>-- INVARIANT 1: See #in_scope_invariant#</span>
<a name="line-25"></a>	<span class='hs-comment'>-- This is what lets us deal with name capture properly</span>
<a name="line-26"></a>	<span class='hs-comment'>-- It's a hard invariant to check...</span>
<a name="line-27"></a>	<span class='hs-comment'>--</span>
<a name="line-28"></a>	<span class='hs-comment'>-- INVARIANT 2: The substitution is apply-once; see Note [Apply once] with</span>
<a name="line-29"></a>	<span class='hs-comment'>--		Types.TvSubstEnv</span>
<a name="line-30"></a>	<span class='hs-comment'>--</span>
<a name="line-31"></a>	<span class='hs-comment'>-- INVARIANT 3: See Note [Extending the Subst]</span>
</pre>\end{code}

Note [Extending the Subst]
~~~~~~~~~~~~~~~~~~~~~~~~~~
For a core Subst, which binds Ids as well, we make a different choice for Ids
than we do for TyVars.  

For TyVars, see Note [Extending the TvSubst] with Type.TvSubstEnv

For Ids, we have a different invariant
	The IdSubstEnv is extended *only* when the Unique on an Id changes
	Otherwise, we just extend the InScopeSet

In consequence:

* In substIdBndr, we extend the IdSubstEnv only when the unique changes

* If the TvSubstEnv and IdSubstEnv are both empty, substExpr does nothing
  (Note that the above rule for substIdBndr maintains this property.  If
   the incoming envts are both empty, then substituting the type and
   IdInfo can't change anything.)

* In lookupIdSubst, we *must* look up the Id in the in-scope set, because
  it may contain non-trivial changes.  Example:
	(/\a. \x:a. ...x...) Int
  We extend the TvSubstEnv with [a |-> Int]; but x's unique does not change
  so we only extend the in-scope set.  Then we must look up in the in-scope
  set when we find the occurrence of x.

* The requirement to look up the Id in the in-scope set means that we
  must NOT take no-op short cut in the case the substitution is empty.
  We must still look up every Id in the in-scope set.

* (However, we don't need to do so for expressions found in the IdSubst
  itself, whose range is assumed to be correct wrt the in-scope set.)

Why do we make a different choice for the IdSubstEnv than the TvSubstEnv?

* For Ids, we change the IdInfo all the time (e.g. deleting the
  unfolding), and adding it back later, so using the TyVar convention
  would entail extending the substitution almost all the time

* The simplifier wants to look up in the in-scope set anyway, in case it 
  can see a better unfolding from an enclosing case expression

* For TyVars, only coercion variables can possibly change, and they are 
  easy to spot

\begin{code}
<pre><a name="line-1"></a><a name="IdSubstEnv"></a><span class='hs-comment'>-- | An environment for substituting for 'Id's</span>
<a name="line-2"></a><a name="IdSubstEnv"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>IdSubstEnv</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IdEnv</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="isEmptySubst"></a><span class='hs-comment'>----------------------------</span>
<a name="line-5"></a><span class='hs-definition'>isEmptySubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-6"></a><span class='hs-definition'>isEmptySubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>id_env</span> <span class='hs-varid'>tv_env</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isEmptyVarEnv</span> <span class='hs-varid'>id_env</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>isEmptyVarEnv</span> <span class='hs-varid'>tv_env</span>
<a name="line-7"></a>
<a name="line-8"></a><a name="emptySubst"></a><span class='hs-definition'>emptySubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span>
<a name="line-9"></a><span class='hs-definition'>emptySubst</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>emptyInScopeSet</span> <span class='hs-varid'>emptyVarEnv</span> <span class='hs-varid'>emptyVarEnv</span>
<a name="line-10"></a>
<a name="line-11"></a><a name="mkEmptySubst"></a><span class='hs-definition'>mkEmptySubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InScopeSet</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-12"></a><span class='hs-definition'>mkEmptySubst</span> <span class='hs-varid'>in_scope</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>emptyVarEnv</span> <span class='hs-varid'>emptyVarEnv</span>
<a name="line-13"></a>
<a name="line-14"></a><a name="mkSubst"></a><span class='hs-definition'>mkSubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InScopeSet</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TvSubstEnv</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IdSubstEnv</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-15"></a><span class='hs-definition'>mkSubst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>ids</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span>
<a name="line-16"></a>
<a name="line-17"></a><span class='hs-comment'>-- getTvSubst :: Subst -&gt; TvSubst</span>
<a name="line-18"></a><span class='hs-comment'>-- getTvSubst (Subst in_scope _ tv_env) = TvSubst in_scope tv_env</span>
<a name="line-19"></a>
<a name="line-20"></a><span class='hs-comment'>-- getTvSubstEnv :: Subst -&gt; TvSubstEnv</span>
<a name="line-21"></a><span class='hs-comment'>-- getTvSubstEnv (Subst _ _ tv_env) = tv_env</span>
<a name="line-22"></a><span class='hs-comment'>-- </span>
<a name="line-23"></a><span class='hs-comment'>-- setTvSubstEnv :: Subst -&gt; TvSubstEnv -&gt; Subst</span>
<a name="line-24"></a><span class='hs-comment'>-- setTvSubstEnv (Subst in_scope ids _) tvs = Subst in_scope ids tvs</span>
<a name="line-25"></a>
<a name="line-26"></a><a name="substInScope"></a><span class='hs-comment'>-- | Find the in-scope set: see "CoreSubst#in_scope_invariant"</span>
<a name="line-27"></a><span class='hs-definition'>substInScope</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InScopeSet</span>
<a name="line-28"></a><span class='hs-definition'>substInScope</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>in_scope</span>
<a name="line-29"></a>
<a name="line-30"></a><a name="zapSubstEnv"></a><span class='hs-comment'>-- | Remove all substitutions for 'Id's and 'Var's that might have been built up</span>
<a name="line-31"></a><span class='hs-comment'>-- while preserving the in-scope set</span>
<a name="line-32"></a><span class='hs-definition'>zapSubstEnv</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-33"></a><span class='hs-definition'>zapSubstEnv</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>emptyVarEnv</span> <span class='hs-varid'>emptyVarEnv</span>
<a name="line-34"></a>
<a name="line-35"></a><a name="extendIdSubst"></a><span class='hs-comment'>-- | Add a substitution for an 'Id' to the 'Subst': you must ensure that the in-scope set is</span>
<a name="line-36"></a><span class='hs-comment'>-- such that the "CoreSubst#in_scope_invariant" is true after extending the substitution like this</span>
<a name="line-37"></a><span class='hs-definition'>extendIdSubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-38"></a><span class='hs-comment'>-- ToDo: add an ASSERT that fvs(subst-result) is already in the in-scope set</span>
<a name="line-39"></a><span class='hs-definition'>extendIdSubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>v</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendVarEnv</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>v</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-varid'>tvs</span>
<a name="line-40"></a>
<a name="line-41"></a><a name="extendIdSubstList"></a><span class='hs-comment'>-- | Adds multiple 'Id' substitutions to the 'Subst': see also 'extendIdSubst'</span>
<a name="line-42"></a><span class='hs-definition'>extendIdSubstList</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</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-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-43"></a><span class='hs-definition'>extendIdSubstList</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>prs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendVarEnvList</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-varid'>tvs</span>
<a name="line-44"></a>
<a name="line-45"></a><a name="extendTvSubst"></a><span class='hs-comment'>-- | Add a substitution for a 'TyVar' to the 'Subst': you must ensure that the in-scope set is</span>
<a name="line-46"></a><span class='hs-comment'>-- such that the "CoreSubst#in_scope_invariant" is true after extending the substitution like this</span>
<a name="line-47"></a><span class='hs-definition'>extendTvSubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyVar</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-48"></a><span class='hs-definition'>extendTvSubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>v</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendVarEnv</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>v</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> 
<a name="line-49"></a>
<a name="line-50"></a><a name="extendTvSubstList"></a><span class='hs-comment'>-- | Adds multiple 'TyVar' substitutions to the 'Subst': see also 'extendTvSubst'</span>
<a name="line-51"></a><span class='hs-definition'>extendTvSubstList</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>TyVar</span><span class='hs-layout'>,</span><span class='hs-conid'>Type</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-52"></a><span class='hs-definition'>extendTvSubstList</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>prs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendVarEnvList</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span>
<a name="line-53"></a>
<a name="line-54"></a><a name="extendSubst"></a><span class='hs-comment'>-- | Add a substitution for a 'TyVar' or 'Id' as appropriate to the 'Var' being added. See also</span>
<a name="line-55"></a><span class='hs-comment'>-- 'extendIdSubst' and 'extendTvSubst'</span>
<a name="line-56"></a><span class='hs-definition'>extendSubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreArg</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-57"></a><span class='hs-definition'>extendSubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>tv</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-58"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>isTyVar</span> <span class='hs-varid'>tv</span> <span class='hs-layout'>)</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendVarEnv</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-59"></a><span class='hs-definition'>extendSubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>id</span> <span class='hs-varid'>expr</span>
<a name="line-60"></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'>id</span> <span class='hs-layout'>)</span> <span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendVarEnv</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>id</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-varid'>tvs</span>
<a name="line-61"></a>
<a name="line-62"></a><a name="extendSubstList"></a><span class='hs-comment'>-- | Add a substitution for a 'TyVar' or 'Id' as appropriate to all the 'Var's being added. See also 'extendSubst'</span>
<a name="line-63"></a><span class='hs-definition'>extendSubstList</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Var</span><span class='hs-layout'>,</span><span class='hs-conid'>CoreArg</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-64"></a><span class='hs-definition'>extendSubstList</span> <span class='hs-varid'>subst</span> <span class='hs-conid'>[]</span>	      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>subst</span>
<a name="line-65"></a><span class='hs-definition'>extendSubstList</span> <span class='hs-varid'>subst</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>var</span><span class='hs-layout'>,</span><span class='hs-varid'>rhs</span><span class='hs-layout'>)</span><span class='hs-conop'>:</span><span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>extendSubstList</span> <span class='hs-layout'>(</span><span class='hs-varid'>extendSubst</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>var</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>prs</span>
<a name="line-66"></a>
<a name="line-67"></a><a name="lookupIdSubst"></a><span class='hs-comment'>-- | Find the substitution for an 'Id' in the 'Subst'</span>
<a name="line-68"></a><span class='hs-definition'>lookupIdSubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-69"></a><span class='hs-definition'>lookupIdSubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varid'>v</span>
<a name="line-70"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isLocalId</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span> <span class='hs-varid'>v</span>
<a name="line-71"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>e</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>lookupVarEnv</span> <span class='hs-varid'>ids</span>       <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>e</span>
<a name="line-72"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>v'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>lookupInScope</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span> <span class='hs-varid'>v'</span>
<a name="line-73"></a>	<span class='hs-comment'>-- Vital! See Note [Extending the Subst]</span>
<a name="line-74"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>WARN</span><span class='hs-layout'>(</span> <span class='hs-conid'>True</span><span class='hs-layout'>,</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>"CoreSubst.lookupIdSubst"</span><span class='hs-layout'>)</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>v</span> <span class='hs-layout'>)</span> 
<a name="line-75"></a>		<span class='hs-conid'>Var</span> <span class='hs-varid'>v</span>
<a name="line-76"></a>
<a name="line-77"></a><a name="lookupTvSubst"></a><span class='hs-comment'>-- | Find the substitution for a 'TyVar' in the 'Subst'</span>
<a name="line-78"></a><span class='hs-definition'>lookupTvSubst</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyVar</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span>
<a name="line-79"></a><span class='hs-definition'>lookupTvSubst</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lookupVarEnv</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>v</span> <span class='hs-varop'>`orElse`</span> <span class='hs-conid'>Type</span><span class='hs-varop'>.</span><span class='hs-varid'>mkTyVarTy</span> <span class='hs-varid'>v</span>
<a name="line-80"></a>
<a name="line-81"></a><a name="isInScope"></a><span class='hs-comment'>------------------------------</span>
<a name="line-82"></a><span class='hs-definition'>isInScope</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-83"></a><span class='hs-definition'>isInScope</span> <span class='hs-varid'>v</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>v</span> <span class='hs-varop'>`elemInScopeSet`</span> <span class='hs-varid'>in_scope</span>
<a name="line-84"></a>
<a name="line-85"></a><a name="extendInScope"></a><span class='hs-comment'>-- | Add the 'Var' to the in-scope set: as a side effect, removes any existing substitutions for it</span>
<a name="line-86"></a><span class='hs-definition'>extendInScope</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-87"></a><span class='hs-definition'>extendInScope</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>v</span>
<a name="line-88"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>in_scope</span> <span class='hs-varop'>`extendInScopeSet`</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> 
<a name="line-89"></a>	  <span class='hs-layout'>(</span><span class='hs-varid'>ids</span> <span class='hs-varop'>`delVarEnv`</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>tvs</span> <span class='hs-varop'>`delVarEnv`</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span>
<a name="line-90"></a>
<a name="line-91"></a><a name="extendInScopeList"></a><span class='hs-comment'>-- | Add the 'Var's to the in-scope set: see also 'extendInScope'</span>
<a name="line-92"></a><span class='hs-definition'>extendInScopeList</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</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'>Subst</span>
<a name="line-93"></a><span class='hs-definition'>extendInScopeList</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>vs</span>
<a name="line-94"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>in_scope</span> <span class='hs-varop'>`extendInScopeSetList`</span> <span class='hs-varid'>vs</span><span class='hs-layout'>)</span> 
<a name="line-95"></a>	  <span class='hs-layout'>(</span><span class='hs-varid'>ids</span> <span class='hs-varop'>`delVarEnvList`</span> <span class='hs-varid'>vs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>tvs</span> <span class='hs-varop'>`delVarEnvList`</span> <span class='hs-varid'>vs</span><span class='hs-layout'>)</span>
<a name="line-96"></a>
<a name="line-97"></a><a name="extendInScopeIds"></a><span class='hs-comment'>-- | Optimized version of 'extendInScopeList' that can be used if you are certain </span>
<a name="line-98"></a><span class='hs-comment'>-- all the things being added are 'Id's and hence none are 'TyVar's</span>
<a name="line-99"></a><span class='hs-definition'>extendInScopeIds</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span>
<a name="line-100"></a><span class='hs-definition'>extendInScopeIds</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>vs</span> 
<a name="line-101"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>in_scope</span> <span class='hs-varop'>`extendInScopeSetList`</span> <span class='hs-varid'>vs</span><span class='hs-layout'>)</span> 
<a name="line-102"></a>	  <span class='hs-layout'>(</span><span class='hs-varid'>ids</span> <span class='hs-varop'>`delVarEnvList`</span> <span class='hs-varid'>vs</span><span class='hs-layout'>)</span> <span class='hs-varid'>tvs</span>
</pre>\end{code}

Pretty printing, for debugging only

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Outputable</span> <span class='hs-conid'>Subst</span> <span class='hs-keyword'>where</span>
<a name="line-2"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> 
<a name="line-3"></a>	<span class='hs-keyglyph'>=</span>  <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>"&lt;InScope ="</span><span class='hs-layout'>)</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>braces</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsep</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-varid'>varEnvElts</span> <span class='hs-layout'>(</span><span class='hs-varid'>getInScopeVars</span> <span class='hs-varid'>in_scope</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-4"></a>	<span class='hs-varop'>$$</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>" IdSubst   ="</span><span class='hs-layout'>)</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>ids</span>
<a name="line-5"></a>	<span class='hs-varop'>$$</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>" TvSubst   ="</span><span class='hs-layout'>)</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>tvs</span>
<a name="line-6"></a> 	 <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'&gt;'</span>
</pre>\end{code}


%************************************************************************
%*									*
	Substituting expressions
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="substExpr"></a><span class='hs-comment'>-- | Apply a substititon to an entire 'CoreExpr'. Rememeber, you may only </span>
<a name="line-2"></a><span class='hs-comment'>-- apply the substitution /once/: see "CoreSubst#apply_once"</span>
<a name="line-3"></a><span class='hs-comment'>--</span>
<a name="line-4"></a><span class='hs-comment'>-- Do *not* attempt to short-cut in the case of an empty substitution!</span>
<a name="line-5"></a><span class='hs-comment'>-- See Note [Extending the Subst]</span>
<a name="line-6"></a><span class='hs-definition'>substExpr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-7"></a><span class='hs-definition'>substExpr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>expr</span>
<a name="line-8"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>expr</span>
<a name="line-9"></a>  <span class='hs-keyword'>where</span>
<a name="line-10"></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>	       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lookupIdSubst</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>v</span> 
<a name="line-11"></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-conid'>Type</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTy</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-12"></a>    <span class='hs-varid'>go</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-conid'>Lit</span> <span class='hs-varid'>lit</span>
<a name="line-13"></a>    <span class='hs-varid'>go</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-conid'>App</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varid'>fun</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span>
<a name="line-14"></a>    <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-varid'>note</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Note</span> <span class='hs-layout'>(</span><span class='hs-varid'>go_note</span> <span class='hs-varid'>note</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>
<a name="line-15"></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-conid'>Cast</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTy</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>
<a name="line-16"></a>    <span class='hs-varid'>go</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-conid'>Lam</span> <span class='hs-varid'>bndr'</span> <span class='hs-layout'>(</span><span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst'</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-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndr'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndr</span>
<a name="line-19"></a>
<a name="line-20"></a>    <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-varid'>bind</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Let</span> <span class='hs-varid'>bind'</span> <span class='hs-layout'>(</span><span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst'</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-21"></a>		       <span class='hs-keyword'>where</span>
<a name="line-22"></a>			 <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bind'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substBind</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bind</span>
<a name="line-23"></a>
<a name="line-24"></a>    <span class='hs-varid'>go</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> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Case</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varid'>scrut</span><span class='hs-layout'>)</span> <span class='hs-varid'>bndr'</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTy</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>go_alt</span> <span class='hs-varid'>subst'</span><span class='hs-layout'>)</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span>
<a name="line-25"></a>			         <span class='hs-keyword'>where</span>
<a name="line-26"></a>			  	 <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndr'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndr</span>
<a name="line-27"></a>
<a name="line-28"></a>    <span class='hs-varid'>go_alt</span> <span class='hs-varid'>subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>con</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-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndrs'</span><span class='hs-layout'>,</span> <span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst'</span> <span class='hs-varid'>rhs</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-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndrs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substBndrs</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndrs</span>
<a name="line-31"></a>
<a name="line-32"></a>    <span class='hs-varid'>go_note</span> <span class='hs-varid'>note</span>	     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>note</span>
<a name="line-33"></a>
<a name="line-34"></a><a name="substBind"></a><span class='hs-comment'>-- | Apply a substititon to an entire 'CoreBind', additionally returning an updated 'Subst'</span>
<a name="line-35"></a><span class='hs-comment'>-- that should be used by subsequent substitutons.</span>
<a name="line-36"></a><span class='hs-definition'>substBind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreBind</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreBind</span><span class='hs-layout'>)</span>
<a name="line-37"></a><span class='hs-definition'>substBind</span> <span class='hs-varid'>subst</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-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-conid'>NonRec</span> <span class='hs-varid'>bndr'</span> <span class='hs-layout'>(</span><span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-38"></a>				  <span class='hs-keyword'>where</span>
<a name="line-39"></a>				    <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndr'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndr</span>
<a name="line-40"></a>
<a name="line-41"></a><span class='hs-definition'>substBind</span> <span class='hs-varid'>subst</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-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs'</span><span class='hs-layout'>)</span>
<a name="line-42"></a>			    <span class='hs-keyword'>where</span>
<a name="line-43"></a>				<span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndrs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substRecBndrs</span> <span class='hs-varid'>subst</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-44"></a>				<span class='hs-varid'>pairs'</span>	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>bndrs'</span> <span class='hs-varop'>`zip`</span> <span class='hs-varid'>rhss'</span>
<a name="line-45"></a>				<span class='hs-varid'>rhss'</span>	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst'</span> <span class='hs-varop'>.</span> <span class='hs-varid'>snd</span><span class='hs-layout'>)</span> <span class='hs-varid'>pairs</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="deShadowBinds"></a><span class='hs-comment'>-- | De-shadowing the program is sometimes a useful pre-pass. It can be done simply</span>
<a name="line-2"></a><span class='hs-comment'>-- by running over the bindings with an empty substitution, becuase substitution</span>
<a name="line-3"></a><span class='hs-comment'>-- returns a result that has no-shadowing guaranteed.</span>
<a name="line-4"></a><span class='hs-comment'>--</span>
<a name="line-5"></a><span class='hs-comment'>-- (Actually, within a single /type/ there might still be shadowing, because </span>
<a name="line-6"></a><span class='hs-comment'>-- 'substTy' is a no-op for the empty substitution, but that's probably OK.)</span>
<a name="line-7"></a><span class='hs-definition'>deShadowBinds</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBind</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBind</span><span class='hs-keyglyph'>]</span>
<a name="line-8"></a><span class='hs-definition'>deShadowBinds</span> <span class='hs-varid'>binds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>snd</span> <span class='hs-layout'>(</span><span class='hs-varid'>mapAccumL</span> <span class='hs-varid'>substBind</span> <span class='hs-varid'>emptySubst</span> <span class='hs-varid'>binds</span><span class='hs-layout'>)</span>
</pre>\end{code}


%************************************************************************
%*									*
	Substituting binders
%*									*
%************************************************************************

Remember that substBndr and friends are used when doing expression
substitution only.  Their only business is substitution, so they
preserve all IdInfo (suitably substituted).  For example, we *want* to
preserve occ info in rules.

\begin{code}
<pre><a name="line-1"></a><a name="substBndr"></a><span class='hs-comment'>-- | Substitutes a 'Var' for another one according to the 'Subst' given, returning</span>
<a name="line-2"></a><span class='hs-comment'>-- the result and an updated 'Subst' that should be used by subsequent substitutons.</span>
<a name="line-3"></a><span class='hs-comment'>-- 'IdInfo' is preserved by this process, although it is substituted into appropriately.</span>
<a name="line-4"></a><span class='hs-definition'>substBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>Var</span><span class='hs-layout'>)</span>
<a name="line-5"></a><span class='hs-definition'>substBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndr</span>
<a name="line-6"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isTyVar</span> <span class='hs-varid'>bndr</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substTyVarBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndr</span>
<a name="line-7"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substIdBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndr</span>
<a name="line-8"></a>
<a name="line-9"></a><a name="substBndrs"></a><span class='hs-comment'>-- | Applies 'substBndr' to a number of 'Var's, accumulating a new 'Subst' left-to-right</span>
<a name="line-10"></a><span class='hs-definition'>substBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</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-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Var</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-11"></a><span class='hs-definition'>substBndrs</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapAccumL</span> <span class='hs-varid'>substBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndrs</span>
<a name="line-12"></a>
<a name="line-13"></a><a name="substRecBndrs"></a><span class='hs-comment'>-- | Substitute in a mutually recursive group of 'Id's</span>
<a name="line-14"></a><span class='hs-definition'>substRecBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-15"></a><span class='hs-definition'>substRecBndrs</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndrs</span> 
<a name="line-16"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>new_subst</span><span class='hs-layout'>,</span> <span class='hs-varid'>new_bndrs</span><span class='hs-layout'>)</span>
<a name="line-17"></a>  <span class='hs-keyword'>where</span>		<span class='hs-comment'>-- Here's the reason we need to pass rec_subst to subst_id</span>
<a name="line-18"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>new_subst</span><span class='hs-layout'>,</span> <span class='hs-varid'>new_bndrs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapAccumL</span> <span class='hs-layout'>(</span><span class='hs-varid'>substIdBndr</span> <span class='hs-varid'>new_subst</span><span class='hs-layout'>)</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndrs</span>
</pre>\end{code}


\begin{code}
<pre><a name="line-1"></a><a name="substIdBndr"></a><span class='hs-definition'>substIdBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span>		<span class='hs-comment'>-- ^ Substitution to use for the IdInfo</span>
<a name="line-2"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> 	<span class='hs-comment'>-- ^ Substitition and Id to transform</span>
<a name="line-3"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>Id</span><span class='hs-layout'>)</span>	<span class='hs-comment'>-- ^ Transformed pair</span>
<a name="line-4"></a>				<span class='hs-comment'>-- NB: unfolding may be zapped</span>
<a name="line-5"></a>
<a name="line-6"></a><span class='hs-definition'>substIdBndr</span> <span class='hs-varid'>rec_subst</span> <span class='hs-varid'>subst</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>env</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>old_id</span>
<a name="line-7"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>in_scope</span> <span class='hs-varop'>`extendInScopeSet`</span> <span class='hs-varid'>new_id</span><span class='hs-layout'>)</span> <span class='hs-varid'>new_env</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>new_id</span><span class='hs-layout'>)</span>
<a name="line-8"></a>  <span class='hs-keyword'>where</span>
<a name="line-9"></a>    <span class='hs-varid'>id1</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>uniqAway</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>old_id</span>	<span class='hs-comment'>-- id1 is cloned if necessary</span>
<a name="line-10"></a>    <span class='hs-varid'>id2</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>no_type_change</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>id1</span>
<a name="line-11"></a>	<span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>	 <span class='hs-keyglyph'>=</span> <span class='hs-varid'>setIdType</span> <span class='hs-varid'>id1</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTy</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>old_ty</span><span class='hs-layout'>)</span>
<a name="line-12"></a>
<a name="line-13"></a>    <span class='hs-varid'>old_ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idType</span> <span class='hs-varid'>old_id</span>
<a name="line-14"></a>    <span class='hs-varid'>no_type_change</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isEmptyVarEnv</span> <span class='hs-varid'>tvs</span> <span class='hs-varop'>||</span> 
<a name="line-15"></a>                     <span class='hs-varid'>isEmptyVarSet</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-varop'>.</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>old_ty</span><span class='hs-layout'>)</span>
<a name="line-16"></a>
<a name="line-17"></a>	<span class='hs-comment'>-- new_id has the right IdInfo</span>
<a name="line-18"></a>	<span class='hs-comment'>-- The lazy-set is because we're in a loop here, with </span>
<a name="line-19"></a>	<span class='hs-comment'>-- rec_subst, when dealing with a mutually-recursive group</span>
<a name="line-20"></a>    <span class='hs-varid'>new_id</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybeModifyIdInfo</span> <span class='hs-varid'>mb_new_info</span> <span class='hs-varid'>id2</span>
<a name="line-21"></a>    <span class='hs-varid'>mb_new_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substIdInfo</span> <span class='hs-varid'>rec_subst</span> <span class='hs-varid'>id2</span> <span class='hs-layout'>(</span><span class='hs-varid'>idInfo</span> <span class='hs-varid'>id2</span><span class='hs-layout'>)</span>
<a name="line-22"></a>	<span class='hs-comment'>-- NB: unfolding info may be zapped</span>
<a name="line-23"></a>
<a name="line-24"></a>	<span class='hs-comment'>-- Extend the substitution if the unique has changed</span>
<a name="line-25"></a>	<span class='hs-comment'>-- See the notes with substTyVarBndr for the delVarEnv</span>
<a name="line-26"></a>    <span class='hs-varid'>new_env</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>no_change</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>delVarEnv</span> <span class='hs-varid'>env</span> <span class='hs-varid'>old_id</span>
<a name="line-27"></a>	    <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>extendVarEnv</span> <span class='hs-varid'>env</span> <span class='hs-varid'>old_id</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>new_id</span><span class='hs-layout'>)</span>
<a name="line-28"></a>
<a name="line-29"></a>    <span class='hs-varid'>no_change</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>id1</span> <span class='hs-varop'>==</span> <span class='hs-varid'>old_id</span>
<a name="line-30"></a>	<span class='hs-comment'>-- See Note [Extending the Subst]</span>
<a name="line-31"></a>	<span class='hs-comment'>-- it's /not/ necessary to check mb_new_info and no_type_change</span>
</pre>\end{code}

Now a variant that unconditionally allocates a new unique.
It also unconditionally zaps the OccInfo.

\begin{code}
<pre><a name="line-1"></a><a name="cloneIdBndr"></a><span class='hs-comment'>-- | Very similar to 'substBndr', but it always allocates a new 'Unique' for</span>
<a name="line-2"></a><span class='hs-comment'>-- each variable in its output and removes all 'IdInfo'</span>
<a name="line-3"></a><span class='hs-definition'>cloneIdBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>UniqSupply</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>Id</span><span class='hs-layout'>)</span>
<a name="line-4"></a><span class='hs-definition'>cloneIdBndr</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>us</span> <span class='hs-varid'>old_id</span>
<a name="line-5"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>clone_id</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>old_id</span><span class='hs-layout'>,</span> <span class='hs-varid'>uniqFromSupply</span> <span class='hs-varid'>us</span><span class='hs-layout'>)</span>
<a name="line-6"></a>
<a name="line-7"></a><a name="cloneIdBndrs"></a><span class='hs-comment'>-- | Applies 'cloneIdBndr' to a number of 'Id's, accumulating a final</span>
<a name="line-8"></a><span class='hs-comment'>-- substitution from left to right</span>
<a name="line-9"></a><span class='hs-definition'>cloneIdBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>UniqSupply</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-10"></a><span class='hs-definition'>cloneIdBndrs</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>us</span> <span class='hs-varid'>ids</span>
<a name="line-11"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapAccumL</span> <span class='hs-layout'>(</span><span class='hs-varid'>clone_id</span> <span class='hs-varid'>subst</span><span class='hs-layout'>)</span> <span class='hs-varid'>subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>ids</span> <span class='hs-varop'>`zip`</span> <span class='hs-varid'>uniqsFromSupply</span> <span class='hs-varid'>us</span><span class='hs-layout'>)</span>
<a name="line-12"></a>
<a name="line-13"></a><a name="cloneRecIdBndrs"></a><span class='hs-comment'>-- | Clone a mutually recursive group of 'Id's</span>
<a name="line-14"></a><span class='hs-definition'>cloneRecIdBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>UniqSupply</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-15"></a><span class='hs-definition'>cloneRecIdBndrs</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>us</span> <span class='hs-varid'>ids</span>
<a name="line-16"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>ids'</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-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>ids'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapAccumL</span> <span class='hs-layout'>(</span><span class='hs-varid'>clone_id</span> <span class='hs-varid'>subst'</span><span class='hs-layout'>)</span> <span class='hs-varid'>subst</span>
<a name="line-19"></a>			       <span class='hs-layout'>(</span><span class='hs-varid'>ids</span> <span class='hs-varop'>`zip`</span> <span class='hs-varid'>uniqsFromSupply</span> <span class='hs-varid'>us</span><span class='hs-layout'>)</span>
<a name="line-20"></a>
<a name="line-21"></a><a name="clone_id"></a><span class='hs-comment'>-- Just like substIdBndr, except that it always makes a new unique</span>
<a name="line-22"></a><span class='hs-comment'>-- It is given the unique to use</span>
<a name="line-23"></a><span class='hs-definition'>clone_id</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span>			<span class='hs-comment'>-- Substitution for the IdInfo</span>
<a name="line-24"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span> <span class='hs-conid'>Unique</span><span class='hs-layout'>)</span>	<span class='hs-comment'>-- Substitition and Id to transform</span>
<a name="line-25"></a>	    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>Id</span><span class='hs-layout'>)</span>		<span class='hs-comment'>-- Transformed pair</span>
<a name="line-26"></a>
<a name="line-27"></a><span class='hs-definition'>clone_id</span> <span class='hs-varid'>rec_subst</span> <span class='hs-varid'>subst</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>env</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>old_id</span><span class='hs-layout'>,</span> <span class='hs-varid'>uniq</span><span class='hs-layout'>)</span>
<a name="line-28"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-layout'>(</span><span class='hs-varid'>in_scope</span> <span class='hs-varop'>`extendInScopeSet`</span> <span class='hs-varid'>new_id</span><span class='hs-layout'>)</span> <span class='hs-varid'>new_env</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>new_id</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'>id1</span>	    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>setVarUnique</span> <span class='hs-varid'>old_id</span> <span class='hs-varid'>uniq</span>
<a name="line-31"></a>    <span class='hs-varid'>id2</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substIdType</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>id1</span>
<a name="line-32"></a>    <span class='hs-varid'>new_id</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybeModifyIdInfo</span> <span class='hs-layout'>(</span><span class='hs-varid'>substIdInfo</span> <span class='hs-varid'>rec_subst</span> <span class='hs-varid'>id2</span> <span class='hs-layout'>(</span><span class='hs-varid'>idInfo</span> <span class='hs-varid'>old_id</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>id2</span>
<a name="line-33"></a>    <span class='hs-varid'>new_env</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>extendVarEnv</span> <span class='hs-varid'>env</span> <span class='hs-varid'>old_id</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>new_id</span><span class='hs-layout'>)</span>
</pre>\end{code}


%************************************************************************
%*									*
		Types
%*									*
%************************************************************************

For types we just call the corresponding function in Type, but we have
to repackage the substitution, from a Subst to a TvSubst

\begin{code}
<pre><a name="line-1"></a><a name="substTyVarBndr"></a><span class='hs-definition'>substTyVarBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TyVar</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span><span class='hs-layout'>,</span> <span class='hs-conid'>TyVar</span><span class='hs-layout'>)</span>
<a name="line-2"></a><span class='hs-definition'>substTyVarBndr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>id_env</span> <span class='hs-varid'>tv_env</span><span class='hs-layout'>)</span> <span class='hs-varid'>tv</span>
<a name="line-3"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-conid'>Type</span><span class='hs-varop'>.</span><span class='hs-varid'>substTyVarBndr</span> <span class='hs-layout'>(</span><span class='hs-conid'>TvSubst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>tv_env</span><span class='hs-layout'>)</span> <span class='hs-varid'>tv</span> <span class='hs-keyword'>of</span>
<a name="line-4"></a>	<span class='hs-layout'>(</span><span class='hs-conid'>TvSubst</span> <span class='hs-varid'>in_scope'</span> <span class='hs-varid'>tv_env'</span><span class='hs-layout'>,</span> <span class='hs-varid'>tv'</span><span class='hs-layout'>)</span> 
<a name="line-5"></a>	   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope'</span> <span class='hs-varid'>id_env</span> <span class='hs-varid'>tv_env'</span><span class='hs-layout'>,</span> <span class='hs-varid'>tv'</span><span class='hs-layout'>)</span>
<a name="line-6"></a>
<a name="line-7"></a><a name="substTy"></a><span class='hs-comment'>-- | See 'Type.substTy'</span>
<a name="line-8"></a><span class='hs-definition'>substTy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> 
<a name="line-9"></a><span class='hs-definition'>substTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-varid'>in_scope</span> <span class='hs-sel'>_id_env</span> <span class='hs-varid'>tv_env</span><span class='hs-layout'>)</span> <span class='hs-varid'>ty</span>
<a name="line-10"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Type</span><span class='hs-varop'>.</span><span class='hs-varid'>substTy</span> <span class='hs-layout'>(</span><span class='hs-conid'>TvSubst</span> <span class='hs-varid'>in_scope</span> <span class='hs-varid'>tv_env</span><span class='hs-layout'>)</span> <span class='hs-varid'>ty</span>
</pre>\end{code}


%************************************************************************
%*									*
\section{IdInfo substitution}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="substIdType"></a><span class='hs-definition'>substIdType</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span>
<a name="line-2"></a><span class='hs-definition'>substIdType</span> <span class='hs-varid'>subst</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Subst</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>tv_env</span><span class='hs-layout'>)</span> <span class='hs-varid'>id</span>
<a name="line-3"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isEmptyVarEnv</span> <span class='hs-varid'>tv_env</span> <span class='hs-varop'>||</span> <span class='hs-varid'>isEmptyVarSet</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span><span class='hs-varop'>.</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-varid'>old_ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>id</span>
<a name="line-4"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>setIdType</span> <span class='hs-varid'>id</span> <span class='hs-layout'>(</span><span class='hs-varid'>substTy</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>old_ty</span><span class='hs-layout'>)</span>
<a name="line-5"></a>		<span class='hs-comment'>-- The tyVarsOfType is cheaper than it looks</span>
<a name="line-6"></a>		<span class='hs-comment'>-- because we cache the free tyvars of the type</span>
<a name="line-7"></a>		<span class='hs-comment'>-- in a Note in the id's type itself</span>
<a name="line-8"></a>  <span class='hs-keyword'>where</span>
<a name="line-9"></a>    <span class='hs-varid'>old_ty</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idType</span> <span class='hs-varid'>id</span>
<a name="line-10"></a>
<a name="line-11"></a><a name="substIdInfo"></a><span class='hs-comment'>------------------</span>
<a name="line-12"></a><span class='hs-comment'>-- | Substitute into some 'IdInfo' with regard to the supplied new 'Id'.</span>
<a name="line-13"></a><span class='hs-comment'>-- Always zaps the unfolding, to save substitution work</span>
<a name="line-14"></a><span class='hs-definition'>substIdInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IdInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>IdInfo</span>
<a name="line-15"></a><span class='hs-definition'>substIdInfo</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>new_id</span> <span class='hs-varid'>info</span>
<a name="line-16"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>nothing_to_do</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-17"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>info</span> <span class='hs-varop'>`setSpecInfo`</span>   	  <span class='hs-varid'>substSpec</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>new_id</span> <span class='hs-varid'>old_rules</span>
<a name="line-18"></a>			       <span class='hs-varop'>`setWorkerInfo`</span> 	  <span class='hs-varid'>substWorker</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>old_wrkr</span>
<a name="line-19"></a>			       <span class='hs-varop'>`setUnfoldingInfo`</span> <span class='hs-varid'>noUnfolding</span><span class='hs-layout'>)</span>
<a name="line-20"></a>  <span class='hs-keyword'>where</span>
<a name="line-21"></a>    <span class='hs-varid'>old_rules</span> 	  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>specInfo</span> <span class='hs-varid'>info</span>
<a name="line-22"></a>    <span class='hs-varid'>old_wrkr</span>  	  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>workerInfo</span> <span class='hs-varid'>info</span>
<a name="line-23"></a>    <span class='hs-varid'>nothing_to_do</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isEmptySpecInfo</span> <span class='hs-varid'>old_rules</span> <span class='hs-varop'>&amp;&amp;</span>
<a name="line-24"></a>		    <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>workerExists</span> <span class='hs-varid'>old_wrkr</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span>
<a name="line-25"></a>		    <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>hasUnfolding</span> <span class='hs-layout'>(</span><span class='hs-varid'>unfoldingInfo</span> <span class='hs-varid'>info</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-26"></a>    
<a name="line-27"></a>
<a name="line-28"></a><a name="substWorker"></a><span class='hs-comment'>------------------</span>
<a name="line-29"></a><span class='hs-comment'>-- | Substitutes for the 'Id's within the 'WorkerInfo'</span>
<a name="line-30"></a><span class='hs-definition'>substWorker</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WorkerInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WorkerInfo</span>
<a name="line-31"></a>	<span class='hs-comment'>-- Seq'ing on the returned WorkerInfo is enough to cause all the </span>
<a name="line-32"></a>	<span class='hs-comment'>-- substitutions to happen completely</span>
<a name="line-33"></a>
<a name="line-34"></a><span class='hs-definition'>substWorker</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>NoWorker</span>
<a name="line-35"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoWorker</span>
<a name="line-36"></a><span class='hs-definition'>substWorker</span> <span class='hs-varid'>subst</span> <span class='hs-layout'>(</span><span class='hs-conid'>HasWorker</span> <span class='hs-varid'>w</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-37"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lookupIdSubst</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>w</span> <span class='hs-keyword'>of</span>
<a name="line-38"></a>	<span class='hs-conid'>Var</span> <span class='hs-varid'>w1</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>HasWorker</span> <span class='hs-varid'>w1</span> <span class='hs-varid'>a</span>
<a name="line-39"></a>	<span class='hs-varid'>other</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WARN</span><span class='hs-layout'>(</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>exprIsTrivial</span> <span class='hs-varid'>other</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>text</span> <span class='hs-str'>"CoreSubst.substWorker:"</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>w</span> <span class='hs-layout'>)</span>
<a name="line-40"></a>		  <span class='hs-conid'>NoWorker</span>	<span class='hs-comment'>-- Worker has got substituted away altogether</span>
<a name="line-41"></a>				<span class='hs-comment'>-- (This can happen if it's trivial, </span>
<a name="line-42"></a>				<span class='hs-comment'>--  via postInlineUnconditionally, hence warning)</span>
<a name="line-43"></a>
<a name="line-44"></a><a name="substSpec"></a><span class='hs-comment'>------------------</span>
<a name="line-45"></a><span class='hs-comment'>-- | Substitutes for the 'Id's within the 'WorkerInfo' given the new function 'Id'</span>
<a name="line-46"></a><span class='hs-definition'>substSpec</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>SpecInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>SpecInfo</span>
<a name="line-47"></a><span class='hs-definition'>substSpec</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>new_fn</span> <span class='hs-layout'>(</span><span class='hs-conid'>SpecInfo</span> <span class='hs-varid'>rules</span> <span class='hs-varid'>rhs_fvs</span><span class='hs-layout'>)</span>
<a name="line-48"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqSpecInfo</span> <span class='hs-varid'>new_rules</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>new_rules</span>
<a name="line-49"></a>  <span class='hs-keyword'>where</span>
<a name="line-50"></a>    <span class='hs-varid'>new_name</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idName</span> <span class='hs-varid'>new_fn</span>
<a name="line-51"></a>    <span class='hs-varid'>new_rules</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SpecInfo</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>do_subst</span> <span class='hs-varid'>rules</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>substVarSet</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>rhs_fvs</span><span class='hs-layout'>)</span>
<a name="line-52"></a>
<a name="line-53"></a>    <span class='hs-varid'>do_subst</span> <span class='hs-varid'>rule</span><span class='hs-keyglyph'>@</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'>rule</span>
<a name="line-54"></a>    <span class='hs-varid'>do_subst</span> <span class='hs-varid'>rule</span><span class='hs-keyglyph'>@</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-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-55"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>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> 
<a name="line-56"></a>		 <span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>new_name</span><span class='hs-layout'>,</span> 	<span class='hs-comment'>-- Important: the function may have changed its name!</span>
<a name="line-57"></a>		 <span class='hs-varid'>ru_args</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst'</span><span class='hs-layout'>)</span> <span class='hs-varid'>args</span><span class='hs-layout'>,</span>
<a name="line-58"></a>		 <span class='hs-varid'>ru_rhs</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substExpr</span> <span class='hs-varid'>subst'</span> <span class='hs-varid'>rhs</span> <span class='hs-layout'>}</span>
<a name="line-59"></a>	<span class='hs-keyword'>where</span>
<a name="line-60"></a>	  <span class='hs-layout'>(</span><span class='hs-varid'>subst'</span><span class='hs-layout'>,</span> <span class='hs-varid'>bndrs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>substBndrs</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>bndrs</span>
<a name="line-61"></a>
<a name="line-62"></a><a name="substVarSet"></a><span class='hs-comment'>------------------</span>
<a name="line-63"></a><span class='hs-definition'>substVarSet</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Subst</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-64"></a><span class='hs-definition'>substVarSet</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>fvs</span> 
<a name="line-65"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldVarSet</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionVarSet</span> <span class='hs-varop'>.</span> <span class='hs-varid'>subst_fv</span> <span class='hs-varid'>subst</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyVarSet</span> <span class='hs-varid'>fvs</span>
<a name="line-66"></a>  <span class='hs-keyword'>where</span>
<a name="line-67"></a>    <span class='hs-varid'>subst_fv</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>fv</span> 
<a name="line-68"></a>	<span class='hs-keyglyph'>|</span> <span class='hs-varid'>isId</span> <span class='hs-varid'>fv</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>exprFreeVars</span> <span class='hs-layout'>(</span><span class='hs-varid'>lookupIdSubst</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>fv</span><span class='hs-layout'>)</span>
<a name="line-69"></a>	<span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Type</span><span class='hs-varop'>.</span><span class='hs-varid'>tyVarsOfType</span> <span class='hs-layout'>(</span><span class='hs-varid'>lookupTvSubst</span> <span class='hs-varid'>subst</span> <span class='hs-varid'>fv</span><span class='hs-layout'>)</span>
</pre>\end{code}
</body>
</html>