Name
type
The Every entity (type constructor, class, identifier, type variable) has a Name
. The Name type is pervasive in GHC, and is defined in compiler/GHC/Types/Name.hs. Here is what a Name
looks like, though it is private to the Name module:
data Name = Name {
n_sort :: NameSort, -- What sort of name it is
n_occ :: !OccName, -- Its occurrence name
n_uniq :: Int#, -- Its identity
n_loc :: !SrcLoc -- Definition site
}
- The
n_sort
field says what sort of name this is: see NameSort below. - The
n_occ
field gives the "occurrence name", or OccName, of the Name. - The
n_uniq
field allows fast tests for equality of Names. - The
n_loc
field gives some indication of where the name was bound.
NameSort
of a Name
The There are four flavours of Name:
data NameSort
= External Module (Maybe Name)
-- (Just parent) => this Name is a subordinate name of 'parent'
-- e.g. data constructor of a data type, method of a class
-- Nothing => not a subordinate
| WiredIn Module (Maybe Name) TyThing BuiltInSyntax
-- A variant of External, for wired-in things
| Internal -- A user-defined Id or TyVar
-- defined in the module being compiled
| System -- A system-defined Id or TyVar. Typically the
-- OccName is very uninformative (like 's')
-
Internal
,System
An
Internal
Name has only an occurrence name. DistinctInternal
Names may have the same occurrence name; then_uniq
distinguishes them.There is only a tiny difference between
Internal
andSystem
; the former simply remembers that the name was originally written by the programmer, which helps when generating error messages. -
External
An
External
Name has a globally-unique (module, occurrence name) pair, namely the original name of the entity, that describes where the thing was originally defined. So for example, if we havemodule M where f = e1 g = e2 module A where import qualified M as Q import M a = Q.f + g
then in module
A
, the functionQ.f
has an External NameM.f
.- During any invocation of GHC, each (module, occurrence-name) gets one, and only one,
Unique
, stored in then_uniq
field of theName
. This association remains fixed even when GHC finishes one module and starts to compile another. This association between (module, occurrence-name) pairs and the correspondingName
(with itsn_uniq
field) is maintained by the Name Cache.
- During any invocation of GHC, each (module, occurrence-name) gets one, and only one,
-
WiredIn
A
WiredIn
Name is a special sort ofExternal
Name, one that is completely known to the compiler (e.g. theBool
type constructor). See Commentary/Compiler/WiredIn.- The
BuiltInSyntax
field is just a boolean yes/no flag that identifies entities that are denoted by built-in syntax, such as[]
for the empty list. TheseNames
aren't "in scope" as such, and we occasionally need to know that.
- The
Names
Entities and Here are the sorts of Name an entity can have:
-
Class: always has an
External
Name. -
TyCon: always has an
External
orWiredIn
Name. -
TyVar: can have
Internal
, orSystem
Names; the former are ones arise from instantiating programmer-written type signatures. -
Ids: can have
External
,Internal
, orSystem
Names.- Before CoreTidy, the Ids that were defined at top level in the original source program get
External
Names, whereas extra top-level bindings generated (say) by the type checker getInternal
Names. This distinction is occasionally useful for filtering diagnostic output; e.g. for-ddump-types
. - After CoreTidy: An Id with an
External
Name will generate symbols that appear as external symbols in the object file. An Id with anInternal
Name cannot be referenced from outside the module, and so generates a local symbol in the object file. The CoreTidy pass makes the decision about which names should be External and which Internal.
- Before CoreTidy, the Ids that were defined at top level in the original source program get