[GHC] #15824: Prefix/infix distinction in TemplateHaskell types is lost
GHC
ghc-devs at haskell.org
Sun Oct 28 18:49:01 UTC 2018
#15824: Prefix/infix distinction in TemplateHaskell types is lost
-------------------------------------+-------------------------------------
Reporter: int-index | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Template | Version: 8.6.1
Haskell |
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets: #15815, #15760
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
Consider `data T a b = a :. b`.
In the declaration, `:.` is mapped to `InfixC`:
{{{
ghci> putStrLn $(reify ''T >>= stringE . show)
TyConI (DataD [] T [KindedTV a StarT,KindedTV b StarT] Nothing [InfixC
(Bang NoSourceUnpackedness NoSourceStrictness,VarT a) :. (Bang
NoSourceUnpackedness NoSourceStrictness,VarT b)] [])
}}}
In expressions, `a :. b` is mapped to `InfixE`:
{{{
ghci> runQ [e| 1 :+ 2 |] >>= print
InfixE (Just (LitE (IntegerL 1))) (ConE :+) (Just (LitE (IntegerL 2)))
}}}
In patterns, `a :. b` is mapped to `InfixP`:
{{{
ghci> runQ [p| 1 :. 2 |] >>= print
InfixP (LitP (IntegerL 1)) :. (LitP (IntegerL 2))
}}}
In types, `a :. b` is mapped to `InfixT`:
{{{
ghci> runQ [t| 1 :. 2 |] >>= print
InfixT (LitT (NumTyLit 1)) (PromotedT :.) (LitT (NumTyLit 2))
}}}
That last one was a lie. In reality, in types `a :. b` is mapped to nested
`AppT`:
{{{
ghci> runQ [t| 1 :. 2 |] >>= print
AppT (AppT (PromotedT :.) (LitT (NumTyLit 1))) (LitT (NumTyLit 2))
}}}
This is despite the existence of `InfixT`.
The same issue can be observed when reifying types:
{{{
ghci> type A = 1 :. 2
ghci> putStrLn $(reify ''A >>= stringE . show)
TyConI (TySynD A [] (AppT (AppT (PromotedT :.) (LitT (NumTyLit 1))) (LitT
(NumTyLit 2))))
}}}
This is not specific to infix constructors and can be observed with any
infix (type) operators.
It's best to change this in the same release as we fix #15760, as there is
code in the wild that is prepared to face neither `InfixT` nor `ParensT`,
and it would break silently. RyanGlScott gives an example of such code:
[https://github.com/glguy/th-
abstraction/blob/5123c6d054d0949cb444590269f13e5d44699ab2/src/Language/Haskell/TH/Datatype.hs#L1156-L1160
decomposeType from th-desugar].
This issue is in part responsible for #15815, see comment:5:ticket:15815.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15824>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list