Note [Binders in Template Haskell]
Consider this TH term construction:
do { x1 <- TH.newName "x" -- newName :: String -> Q TH.Name
; x2 <- TH.newName "x" -- Builds a NameU
; x3 <- TH.newName "x"
; let x = mkName "x" -- mkName :: String -> TH.Name
Builds a NameS
; return (LamE (..pattern [x1,x2]..) $
LamE (VarPat x3) $
..tuple (x1,x2,x3,x)) }
It represents the term \[x1,x2]. \x3. (x1,x2,x3,x)
a) We don't want to complain about "x" being bound twice in
the pattern [x1,x2]
b) We don't want x3 to shadow the x1,x2
c) We *do* want 'x' (dynamically bound with mkName) to bind
to the innermost binding of "x", namely x3.
d) When pretty printing, we want to print a unique with x1,x2
etc, else they'll all print as "x" which isn't very helpful
When we convert all this to HsSyn, the TH.Names are converted with
thRdrName. To achieve (b) we want the binders to be Exact RdrNames.
Achieving (a) is a bit awkward, because
- We must check for duplicate and shadowed names on Names,
not RdrNames, *after* renaming.
See Note [Collect binders only after renaming] in GHC.Hs.Utils
- But to achieve (a) we must distinguish between the Exact
RdrNames arising from TH and the Unqual RdrNames that would
come from a user writing \[x,x] -> blah
So in Convert.thRdrName we translate
TH Name RdrName
NameU (arising from newName) --> Exact (Name{ System })
NameS (arising from mkName) --> Unqual
Notice that the NameUs generate *System* Names. Then, when
figuring out shadowing and duplicates, we can filter out
System Names.
This use of System Names fits with other uses of System Names, eg for
temporary variables "a". Since there are lots of things called "a" we
usually want to print the name with the unique, and that is indeed
the way System Names are printed.
There's a small complication of course; see Note [Looking up Exact
RdrNames] in GHC.Rename.Env. References 1
- Collect binders only after renaming GHC.Hs.Utils
Referenced by 9
- GHC.Rename.Utils call site ×4
- Internal used_names GHC.HsToCore.Usage
- GHC.Rename.Env call site
- Looking up Exact RdrNames GHC.Rename.Env
- Auxiliary binders GHC.Tc.Deriv.Generate
- GHC.ThToHs call site