TH improperly converts promoted data cons in ConT
If you compile the following program:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Bug where
import Language.Haskell.TH
$([d| type AbsoluteUnit1 = '() |])
$(pure [TySynD (mkName "AbsoluteUnit2") [] (ConT '())])
$ /opt/ghc/8.6.1/bin/ghci Bug.hs
GHCi, version 8.6.0.20180810: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:8:3-33: Splicing declarations
[d| type AbsoluteUnit1_a1HN = '() |]
======>
type AbsoluteUnit1_a4qs = '()
Bug.hs:9:3-54: Splicing declarations
pure [TySynD (mkName "AbsoluteUnit2") [] (ConT '())]
======>
type AbsoluteUnit2 = ()
You'll notice an unusual discrepancy between the two -ddump-splices
logs. In the first one:
type AbsoluteUnit1_a4qs = '()
The '()
constructor is properly preceded with a single quote. In the second one, however:
type AbsoluteUnit2 = ()
'()
incorrectly appears without a single quote! The culprit is in the way Convert
handles ConT
:
ConT nm -> do { nm' <- tconName nm
; mk_apps (HsTyVar noExt NotPromoted (noLoc nm')) tys'}
This code naïvely assumes that ConT
will never contain a promoted data constructor name by hardcoding NotPromoted
. We really ought to be checking if nm'
is a data con RdrName
here and using Promoted
if so, and NotPromoted
otherwise.
Patch incoming.
Trac metadata
Trac field | Value |
---|---|
Version | 8.4.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Template Haskell |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |