HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

  • Packageghc-9.10.3
  • Exports115
  • LanguageGHC2021
  • LicenceBSD-3-Clause
  • SourceEnv.hs

Var, Id and TyVar environments (maps)

5 declarations

Manipulating these environments

Deterministic Var environments (maps)

3 declarations
typetype DIdEnv elt = UniqDFM Var elt
#

Deterministic Identifier Environment Sadly not always indexed by Id, but it is in the common case.

Manipulating these environments

The InScopeSet type

1 declaration
newtypenewtype InScopeSet
#

A set of variables that are in scope at some point.

Note that this is a superset of the variables that are currently in scope. See Note [The InScopeSet invariant].

"Secrets of the Glasgow Haskell Compiler inliner" Section 3.2 provides the motivation for this abstraction.

Constructors

Instances1Outputable

Operations on InScopeSets

valueuniqAway :: InScopeSet -> Var -> Var
#

uniqAway in_scope v finds a unique that is not used in the in-scope set, and gives that to v. See Note [Local uniques] and Note [The InScopeSet invariant].

The RnEnv2 type

1 declaration
datadata RnEnv2
#

Rename Environment 2

When we are comparing (or matching) types or terms, we are faced with "going under" corresponding binders. E.g. when comparing:

\x. e1     ~   \y. e2

Basically we want to rename [x -> y] or [y -> x], but there are lots of things we must be careful of. In particular, x might be free in e2, or y in e1. So the idea is that we come up with a fresh binder that is free in neither, and rename x and y respectively. That means we must maintain:

  1. A renaming for the left-hand expression

  2. A renaming for the right-hand expressions

  3. An in-scope set

Furthermore, when matching, we want to be able to have an 'occurs check', to prevent:

\x. f   ~   \y. y

matching with [f -> y]. So for each expression we want to know that set of locally-bound variables. That is precisely the domain of the mappings 1. and 2., but we must ensure that we always extend the mappings as we go in.

All of this information is bundled up in the RnEnv2

Operations on RnEnv2s

valuernBndr2 :: RnEnv2 -> Var -> Var -> RnEnv2
#

rnBndr2 env bL bR goes under a binder bL in the Left term, and binder bR in the Right term. It finds a new binder, new_b, and returns an environment mapping bL -> new_b and bR -> new_b

valuernBndr2_var :: RnEnv2 -> Var -> Var -> (RnEnv2, Var)
#

Similar to rnBndr2 but returns the new variable as well as the new environment. Postcondition: the type of the returned Var is that of bR

valuernOccL :: RnEnv2 -> Var -> Var
#

Look up the renaming of an occurrence in the left or right term

valuernOccR :: RnEnv2 -> Var -> Var
#

Look up the renaming of an occurrence in the left or right term

valueanyInRnEnvR :: RnEnv2 -> VarSet -> Bool
#

`anyInRnEnvR env set` == `any (inRnEnvR rn_env) (toList set)` but lazy in the second argument if the right side of the env is empty.

TidyEnv and its operation

4 declarations
typetype TidyEnv = (TidyOccEnv, VarEnv Var)
#

Tidy Environment

When tidying up print names, we keep a mapping of in-scope occ-names (the TidyOccEnv) and a Var-to-Var of the current renamings