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 |