GHC reports an exact Name is not in scope when quoting ANN
If you compile the following program:
{-# LANGUAGE TemplateHaskell #-}
module Bug where
$([d| x :: Int
x = 42
{-# ANN x "blah" #-}
|])
You'll get:
$ /opt/ghc/8.10.3/bin/ghc Bug.hs
[1 of 1] Compiling Bug ( Bug.hs, Bug.o, Bug.dyn_o )
Bug.hs:4:3: error:
• The exact Name ‘x’ is not in scope
Probable cause: you used a unique Template Haskell name (NameU),
perhaps via newName, but did not bind it
If that's it, then -ddump-splices might be useful
• In the annotation: {-# ANN x "blah" #-}
|
4 | $([d| x :: Int
| ^^^^^^^^^^^^...
Which probably shouldn't happen. If you compile with -ddump-splices
, it's more obvious what is happening:
Bug.hs:(4,3)-(7,6): Splicing declarations
[d| {-# ANN x_age "blah" #-}
x_age :: Int
x_age = 42 |]
======>
x_a25M :: Int
x_a25M = 42
{-# ANN x_age "blah" #-}
The name mentioned in the ANN
(x_age
) is not the same name mentioned in the function declaration (x_a25M
). As for why this happens, I believe this code is responsible:
repAnnProv :: AnnProvenance Name -> MetaM (Core TH.AnnTarget)
repAnnProv (ValueAnnProvenance (L _ n))
= do { MkC n' <- lift $ globalVar n -- ANNs are allowed only at top-level
; rep2_nw valueAnnotationName [ n' ] }
repAnnProv (TypeAnnProvenance (L _ n))
= do { MkC n' <- lift $ globalVar n
; rep2_nw typeAnnotationName [ n' ] }
repAnnProv ModuleAnnProvenance
= rep2_nw moduleAnnotationName []
This turns the Core Name
inside an ANN
to a Template Haskell Name
by way of globalVar
, which allocates a fresh Template Haskell Name
regardless of what other Name
s are in scope. I think that globalVar
should actually be lookupLOcc
instead. Indeed, this patch appears to fix the issue locally:
diff --git a/compiler/GHC/HsToCore/Quote.hs b/compiler/GHC/HsToCore/Quote.hs
index 767914127a..a6e1100419 100644
--- a/compiler/GHC/HsToCore/Quote.hs
+++ b/compiler/GHC/HsToCore/Quote.hs
@@ -848,11 +848,11 @@ repAnnD (L loc (HsAnnotation _ _ ann_prov (L _ exp)))
; return (loc, dec) }
repAnnProv :: AnnProvenance Name -> MetaM (Core TH.AnnTarget)
-repAnnProv (ValueAnnProvenance (L _ n))
- = do { MkC n' <- lift $ globalVar n -- ANNs are allowed only at top-level
+repAnnProv (ValueAnnProvenance n)
+ = do { MkC n' <- lookupLOcc n -- ANNs are allowed only at top-level
; rep2_nw valueAnnotationName [ n' ] }
-repAnnProv (TypeAnnProvenance (L _ n))
- = do { MkC n' <- lift $ globalVar n
+repAnnProv (TypeAnnProvenance n)
+ = do { MkC n' <- lookupLOcc n
; rep2_nw typeAnnotationName [ n' ] }
repAnnProv ModuleAnnProvenance
= rep2_nw moduleAnnotationName []
The comment says "ANNs are allowed only at top-level", but I don't think that's relevant here. After all, standalone kind signatures are also allowed only at the top level, but repKiSigD
still uses lookupLOcc
.