Inconsistent parsing of symbolic names in `ANN` versus `ANN type`
While investigating #19363 (closed), I came across a curiosity in the way that GHC parses symbolic names in ANN
versus ANN type
. GHC will parse this program without issue:
{-# LANGUAGE TypeOperators #-}
module Bug where
(%%) :: [a] -> [a] -> [a]
(%%) = (++)
{-# ANN (%%) "This is an annotation" #-}
If you do something similar with ANN type
, however:
data (%%%)
{-# ANN type (%%%) "This is also an annotation" #-}
Then GHC will fail to parse it:
$ /opt/ghc/8.10.3/bin/ghc Bug.hs
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
Bug.hs:9:14: error: parse error on input ‘(’
|
9 | {-# ANN type (%%%) "This is also an annotation" #-}
| ^
This seems inconsistent. Moreover, I think this discrepancy is due to a simple oversight in the parser. Here are the relevant lines of Happy code:
-- Annotations
annotation :: { LHsDecl GhcPs }
: '{-# ANN' name_var aexp '#-}' {% runPV (unECP $3) >>= \ $3 ->
ams (sLL $1 $> (AnnD noExtField $ HsAnnotation noExtField
(getANN_PRAGs $1)
(ValueAnnProvenance $2) $3))
[mo $1,mc $4] }
| '{-# ANN' 'type' tycon aexp '#-}' {% runPV (unECP $4) >>= \ $4 ->
ams (sLL $1 $> (AnnD noExtField $ HsAnnotation noExtField
(getANN_PRAGs $1)
(TypeAnnProvenance $3) $4))
[mo $1,mj AnnType $2,mc $5] }
Notice that ANN
uses the name_var
production to parse term-level names, which permits symbolic names surrounded in parentheses (e.g., (%%)
). On the other hand, ANN type
uses the tycon
production to parse type-level names, which does not permit symbolic names.