
#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... 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