Teo Camarasu pushed to branch wip/T27022 at Glasgow Haskell Compiler / GHC
Commits:
-
9369b573
by Teo Camarasu at 2026-05-02T12:17:42+01:00
4 changed files:
- + changelog.d/T27022
- libraries/ghci/GHCi/TH.hs
- + testsuite/tests/th/T27022.hs
- testsuite/tests/th/all.T
Changes:
| 1 | +section: compiler
|
|
| 2 | +synopsis: Fix a divergence in the interaction between ``recover`` and ``putQ`` between the internal and external interpreter
|
|
| 3 | +description: The ``recover`` method in TemplateHaskell now behaves the same
|
|
| 4 | + with the internal and external interpreter.
|
|
| 5 | + In the past, when an error was encountered in a computation in a ``recover`` block,
|
|
| 6 | + the external interpreter would discard any state changes from ``putQ``,
|
|
| 7 | + whereas the internal interpreter would not.
|
|
| 8 | + This was a long-standing error in the implementation of the external interpreter.
|
|
| 9 | + Both now keep state changes from ``putQ`` in ``recover`` blocks.
|
|
| 10 | +mr: !15994
|
|
| 11 | +issues: #27022 |
| ... | ... | @@ -175,9 +175,7 @@ instance TH.Quasi GHCiQ where |
| 175 | 175 | e <- try $ unmask $ runGHCiQ (a <* ghcCmd FailIfErrs) sRef
|
| 176 | 176 | remoteTHCall (qsPipe s) (EndRecover (isLeft e))
|
| 177 | 177 | case e of
|
| 178 | - Left GHCiQException{} ->
|
|
| 179 | - -- in case of error, restore the state to the start of the `recover` block.
|
|
| 180 | - newIORef s >>= h
|
|
| 178 | + Left GHCiQException{} -> h sRef
|
|
| 181 | 179 | Right r -> return r
|
| 182 | 180 | qLookupName isType occ = ghcCmd (LookupName isType occ)
|
| 183 | 181 | qReify name = ghcCmd (Reify name)
|
| 1 | +{-# LANGUAGE TemplateHaskell #-}
|
|
| 2 | +-- | This tests the behaviour of TH's recover method.
|
|
| 3 | +-- It should behave the same in the internal and external interperter.
|
|
| 4 | +-- In the past, they have diverged, and the external interpreter would roll back the state of putQ/getQ whereas the internal interpreter would not.
|
|
| 5 | +module T27022 where
|
|
| 6 | + |
|
| 7 | +import Language.Haskell.TH.Syntax
|
|
| 8 | +main = print $(putQ "0" >> recover (pure ()) (putQ "42" >> fail "oops") >> getQ @String >>= lift ) |
| ... | ... | @@ -650,3 +650,4 @@ test('GadtConSigs_th_dump1', normal, compile, ['-v0 -ddump-splices -dsuppress-un |
| 650 | 650 | test('T26099', normal, compile_fail, [''])
|
| 651 | 651 | test('T8306_th', only_ways(['ghci']), ghci_script, ['T8306_th.script'])
|
| 652 | 652 | test('T26862_th', only_ways(['ghci']), ghci_script, ['T26862_th.script'])
|
| 653 | +test('T27022', normal, compile, ['']) |