Skip to content

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.

Edited by Ryan Scott
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information