diff options
Diffstat (limited to 'compiler/prelude')
-rw-r--r-- | compiler/prelude/PrelInfo.lhs | 2 | ||||
-rw-r--r-- | compiler/prelude/PrelNames.lhs | 51 | ||||
-rw-r--r-- | compiler/prelude/TysWiredIn.lhs | 5 |
3 files changed, 54 insertions, 4 deletions
diff --git a/compiler/prelude/PrelInfo.lhs b/compiler/prelude/PrelInfo.lhs index f99f9ca292..f3a3930caf 100644 --- a/compiler/prelude/PrelInfo.lhs +++ b/compiler/prelude/PrelInfo.lhs @@ -70,7 +70,7 @@ Notes about wired in things wiredInThings :: [TyThing] -- This list is used only to initialise HscMain.knownKeyNames -- to ensure that when you say "Prelude.map" in your source code, you --- get a Name with the correct known key +-- get a Name with the correct known key (See Note [Known-key names]) wiredInThings = concat [ -- Wired in TyCons and their implicit Ids diff --git a/compiler/prelude/PrelNames.lhs b/compiler/prelude/PrelNames.lhs index 02b67803b5..05e0d94dde 100644 --- a/compiler/prelude/PrelNames.lhs +++ b/compiler/prelude/PrelNames.lhs @@ -35,6 +35,57 @@ Nota Bene: all Names defined in here should come from the base package the uniques for these guys, only their names +Note [Known-key names] +~~~~~~~~~~~~~~~~~~~~~~ + +It is *very* important that the compiler gives wired-in things and things with "known-key" names +the correct Uniques wherever they occur. We have to be careful about this in exactly two places: + + 1. When we parse some source code, renaming the AST better yield an AST whose Names have the + correct uniques + + 2. When we read an interface file, the read-in gubbins better have the right uniques + +This is accomplished through a combination of mechanisms: + + 1. When parsing source code, the RdrName-decorated AST has some RdrNames which are Exact. These are + wired-in RdrNames where the we could directly tell from the parsed syntax what Name to use. For + example, when we parse a [] in a type we can just insert an Exact RdrName Name with the listTyConKey. + + Currently, I believe this is just an optimisation: it would be equally valid to just output Orig + RdrNames that correctly record the module etc we expect the final Name to come from. However, + were we to eliminate isTupleOcc_maybe it would become essential (see point 3). + + 2. The knownKeyNames (which consist of the basicKnownKeyNames from the module, and those names reachable + via the wired-in stuff from TysWiredIn) are used to initialise the "original name cache" in IfaceEnv. + This initialization ensures that when the type checker or renamer (both of which use IfaceEnv) look up + an original name (i.e. a pair of a Module and an OccName) for a known-key name they get the correct Unique. + + This is the most important mechanism for ensuring that known-key stuff gets the right Unique, and is why + it is so important to place your known-key names in the appropriate lists. + + 3. For "infinite families" of known-key names (i.e. tuples, Any tycons and implicit parameter TyCons), we + have to be extra careful. Because there are an infinite number of these things, we cannot add them to + the list of known-key names used to initialise the original name cache. Instead, we have to rely on + never having to look them up in that cache. + + This is accomplished through a variety of mechanisms: + + a) The known infinite families of names are specially serialised by BinIface.putName, with that special treatment + detected when we read back to ensure that we get back to the correct uniques. + + b) Most of the infinite families cannot occur in source code, so mechanism a) sufficies to ensure that they + always have the right Unique. In particular, implicit param TyCon names, constraint tuples and Any TyCons + cannot be mentioned by the user. + + c) Tuple TyCon/DataCon names have a special hack (isTupleOcc_maybe) that is used by the original name cache + lookup routine to detect tuple names and give them the right Unique. You might think that this is unnecessary + because tuple TyCon/DataCons are parsed as Exact RdrNames and *don't* appear as original names in interface files + (because serialization gives them special treatment), so we will never look them up in the original name cache. + + However, there is a subtle reason why this is not the case: if you use setRdrNameSpace on an Exact RdrName + it may be turned into an Orig RdrName. So if the original name was an Exact tuple Name we might end up with + an Orig instead, which *will* lead to an original name cache query. \begin{code} module PrelNames ( Unique, Uniquable(..), hasKey, -- Re-exported for convenience diff --git a/compiler/prelude/TysWiredIn.lhs b/compiler/prelude/TysWiredIn.lhs index bad62a599b..6796102687 100644 --- a/compiler/prelude/TysWiredIn.lhs +++ b/compiler/prelude/TysWiredIn.lhs @@ -116,10 +116,9 @@ names in PrelNames, so they use wTcQual, wDataQual, etc -- Because of their infinite nature, this list excludes tuples, Any and implicit -- parameter TyCons. Instead, we have a hack in lookupOrigNameCache to deal with -- these names. +-- +-- See also Note [Known-key names] wiredInTyCons :: [TyCon] --- It does not need to include kind constructors, because --- all that wiredInThings does is to initialise the Name table, --- and kind constructors don't appear in source code. wiredInTyCons = [ unitTyCon -- Not treated like other tuples, because -- it's defined in GHC.Base, and there's only |