[GHC] #15783: Quoting an internal variable causes an error when splicing
GHC
ghc-devs at haskell.org
Sat Oct 20 14:58:33 UTC 2018
#15783: Quoting an internal variable causes an error when splicing
-------------------------------------+-------------------------------------
Reporter: mpickering | Owner: (none)
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Template Haskell | Version: 8.6.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D5248
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by RyanGlScott):
* status: new => patch
* differential: => Phab:D5248
Comment:
I figured out what's causing this. See Phab:D5248 for a fix.
It turns out that occurrence analysis was dropping the binding for `d`
during desugaring (this explains why this bug didn't surface in GHCi, as
occurrence analysis does not run there). So why was occurrence analysis
dropping bindings for top-level things referenced from typed TH quotes,
but not from untyped TH quotes? It turns out that two functions called
`checkCrossStageLifting` are to blame.
...No seriously, there are two completely separate functions named
`checkCrossStageLifting` in GHC. One exists in `RnSplice`, and only
handles untyped quotes, and the other exists in `TcExpr`, and only handles
typed quotes. And wouldn't you know it, `RnSplice.checkCrossStageLifting`
was doing something that `TcExpr.checkCrossStageLifting` wasn't doing. In
particular,
[http://git.haskell.org/ghc.git/blob/879db5595208fb665ff1a0a2b12b9921d3efae0e:/compiler/rename/RnSplice.hs#l800
these lines] of `RnSplice.checkCrossStageLifting` are crucial:
{{{#!hs
| isTopLevel top_lvl
-- Top-level identifiers in this module,
-- (which have External Names)
-- are just like the imported case:
-- no need for the 'lifting' treatment
-- E.g. this is fine:
-- f x = x
-- g y = [| f 3 |]
= when (isExternalName name) (keepAlive name)
-- See Note [Keeping things alive for Template Haskell]
}}}
That call to `keepAlive` ensures that the binding for `f` (from the
example in the comments) doesn't get discarded during occurrence analysis.
`TcExpr.checkCrossStageLifting` wasn't doing anything like this, which
explains why this bug exists.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15783#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list