Opened 6 years ago

Closed 6 years ago

#5665 closed bug (fixed)

Duplicate asm symbols for record fields when TH is used in the module

Reported by: mikhail.vorozhtsov Owned by: simonpj
Priority: normal Milestone:
Component: Compiler Version: 7.3
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: th/T5665
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


$ cat TH.hs
module TH where

import Language.Haskell.TH

doSomeTH s tp = return [NewtypeD [] n [] (NormalC n [(NotStrict, ConT tp)]) []]
  where n = mkName s
$ cat Bug.hs
{-# LANGUAGE TemplateHaskell #-}

module Bug where

import TH

data Record = Record { recordField :: Int }

$(doSomeTH "SomeType" ''Int)
$ ghc-7.3.20111128 -fforce-recomp TH.hs Bug.hs 
[1 of 2] Compiling TH               ( TH.hs, TH.o )
[2 of 2] Compiling Bug              ( Bug.hs, Bug.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package pretty- ... linking ... done.
Loading package array- ... linking ... done.
Loading package deepseq- ... linking ... done.
Loading package containers- ... linking ... done.
Loading package template-haskell ... linking ... done.
/tmp/ghc29791_0/ghc29791_0.s: Assembler messages:

     Error: symbol `Bug_recordField_closure' is already defined

     Error: symbol `Bug_recordField_info' is already defined

Change History (3)

comment:1 Changed 6 years ago by simonpj

Owner: set to simonpj

Urk! I know just what is going on here... a regrettable oversight. Will fix.

comment:2 Changed 6 years ago by simonpj@…

commit ac11b1f14c3d0d507cf11eade1855ffc440d3b7b

Author: Simon Peyton Jones <>
Date:   Tue Nov 29 15:49:24 2011 +0000

    Refactor (again) the treatment of record-selector bindings
    We were generating them from the tcg_tcs field of the TcGblEnv,
    but that goes badly wrong when there are top-level Template
    Haskell splices, because the tcg_tcs field grows successively.
    If we generate record-selector binds for all the TyCons in the
    accumulated list, we generate them multiple times for TyCons
    earlier in the program.  This what was happening in Trac #5665:
      data T = T { x :: Int }
      $(f 4)  -- Top level splice
      ..more code..
    Here the record selector bindings for T were being generated
    Better instead to generate the record-selector bindings in
    TcTyClsDecls, right where the new TyCons are being declared (as indeed
    they were some time ago).  This pushed me into doing some refactoring:
    instead of returning the record bindings, tcTyAndClassDecls adds them
    to the tcg_binds field of the TcGblEnv.  I think the result is a bit
    nicer, and it has the additional merit of working.

 compiler/typecheck/TcBinds.lhs      |   66 +++++++++++++++++++++--------------
 compiler/typecheck/TcDeriv.lhs      |    2 +-
 compiler/typecheck/TcInstDcls.lhs   |   20 ++++++-----
 compiler/typecheck/TcRnDriver.lhs   |   36 +++++--------------
 compiler/typecheck/TcRnMonad.lhs    |   15 +++++---
 compiler/typecheck/TcTyClsDecls.lhs |   34 ++++++++++-------
 6 files changed, 91 insertions(+), 82 deletions(-)

comment:3 Changed 6 years ago by simonpj

Resolution: fixed
Status: newclosed
Test Case: th/T5665

Thanks, regression test added.

Note: See TracTickets for help on using tickets.