Skip to content

Instantly share code, notes, and snippets.

@maksbotan
Created December 8, 2019 13:33
Show Gist options
  • Save maksbotan/146b250ad295c0f5896a2313ce918cd0 to your computer and use it in GitHub Desktop.
Save maksbotan/146b250ad295c0f5896a2313ce918cd0 to your computer and use it in GitHub Desktop.
GHC bug with TemplateHaskell + DuplicateRecordFields

This is a minimal reproducing example for bug in GHC. It is observed in 8.6.3 (Stack LTS-13.6), 8.6.5 (nix) and 8.8.1 (nix).

$ ghc Exp.hs -ddump-splices
[1 of 2] Compiling TH               ( TH.hs, TH.o )
[2 of 2] Compiling Exp              ( Exp.hs, Exp.o )
Exp.hs:11:1-10: Splicing declarations make ''Bar ======>

Exp.hs:11:1: error:
    Ambiguous occurrence ‘Exp.foo’
    It could refer to
       either the field ‘foo’, defined at Exp.hs:9:18
           or the field ‘foo’, defined at Exp.hs:8:18
   |
11 | make ''Bar
   | ^^^^^^^^^^

TH function make only calls reify and does nothing, as is seen from -ddump-splices. However, reify on record fields triggers a very weird error with DuplicateRecordFields.

{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TemplateHaskell #-}
module Exp where
import TH
-- Define two records with the same field
data Foo = Foo { foo :: String, bla :: Int}
data Bar = Bar { foo :: String, bar :: Bool }
-- Call TH function that calls reify and returns nothing
make ''Bar
module TH where
import Language.Haskell.TH
make :: Name -> Q [Dec]
make name = do
-- reify type name to get record constructor and fields
TyConI (DataD _ _ _ _ [RecC con fields'] _) <- reify name
let fields = [ field | (field, _, _) <- fields' ]
-- now suppose we need to reify fields to get their types...
fieldInfos <- mapM reify fields
-- and do nothing more
return []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment