TH quotes drop local fixity declarations
Haskell permits local fixity declarations, such as in the following code:
f :: Bool
f = g () () where
infixl 4 `g`
g :: () -> () -> Bool
g _ _ = True
However, Template Haskell seems to drop them, as this code demonstrates:
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Bug where
$([d| infixl 4 `f`
f :: Bool
f = g () () where
infixl 4 `g`
g :: () -> () -> Bool
g _ _ = True
|])
$ /opt/ghc/8.8.1/bin/ghci Bug.hs -dsuppress-uniques
GHCi, version 8.8.1: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:(5,3)-(11,6): Splicing declarations
[d| infixl 4 `f`
f :: Bool
f = g () ()
where
infixl 4 `g`
g :: () -> () -> Bool
g _ _ = True |]
======>
infixl 4 `f`
f :: Bool
f = (g ()) ()
where
g :: () -> () -> Bool
g _ _ = True
Notice that the top-level fixity declaration for f
is quoted properly, but the local fixity declaration for g
is dropped.
The reason for this unusual discrepancy is the fact that the GHC AST stores fixity declarations in two separate places. One place handles top-level fixity declarations:
data HsGroup p
= HsGroup {
...
hs_fixds :: [LFixitySig p],
-- Snaffled out of both top-level fixity signatures,
-- and those in class declarations
This is handled properly in DsMeta
:
repTopDs :: HsGroup GhcRn -> DsM (Core (TH.Q [TH.Dec]))
repTopDs group@(HsGroup { ...
, hs_fixds = fixds
, ... })
= do { ...
decls <- addBinds ss (
do { ...
; fix_ds <- mapM repFixD fixds
Another place handles local fixity declarations:
data Sig pass
= ...
| FixSig (XFixSig pass) (FixitySig pass)
In contrast to top-level fixity declarations, DsMeta
doesn't seem to handle these at all:
rep_sig :: LSig GhcRn -> DsM [(SrcSpan, Core TH.DecQ)]
...
rep_sig (dL->L _ (FixSig {})) = return [] -- fixity sigs at top level
As far as I can tell, there is no good reason why rep_sig
shouldn't be able to handle FixSig
s, as the code in repFixD
works just as well for top-level names as local names. I plan to do just that in an incoming patch.