Opened 5 years ago

Last modified 8 months ago

#9693 new bug

Reloading GHCi with Template Haskell names can panic GHC

Reported by: maxs Owned by:
Priority: normal Milestone:
Component: Template Haskell Version: 7.8.3
Keywords: Cc: goldfire
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

First, load the following program into GHCi.

Fun.hs

module Fun where
import Language.Haskell.TH

stuff = do
  -- let x = mkName "X"
  x <- newName "X"
  sequence $ [dataD (return []) x [] [
      normalC x []
    ] []]

thbug.hs

{-# LANGUAGE TemplateHaskell #-}
import Fun

stuff

Then comment out the newName, un comment the mkName and reload GHCi.

ghc: panic! (the 'impossible' happened)
  (GHC version 7.8.3 for x86_64-apple-darwin):
	kcLookupKind APromotionErr RecDataConPE

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

It is important to note this is a valid program, if you then close GHCi and start it again with the modified file, it will load correctly. Reloading after attempting to compile the newName version will cause a panic.

Change History (11)

comment:1 Changed 5 years ago by goldfire

Status: newinfoneeded

I can't reproduce this problem. When I load your original files (that is, with newName, not mkName), I get this:

    Duplicate exact Name ‘X’
      Probable cause: you used a unique Template Haskell name (NameU), 
      perhaps via newName, but bound it multiple times
      If that's it, then -ddump-splices might be useful

The error seems reasonable to me: the name is bound both as a type and as a data constructor. I'm also on GHC 7.8.3 on a Mac. Can you try again to reproduce the problem? Maybe your GHCi state had something else going on... perhaps a ghci.conf file?

comment:2 Changed 5 years ago by thomie

Component: CompilerTemplate Haskell
Status: infoneedednew

I am able to reproduce with 7.8.3 and recent HEAD, on Linux, following these steps:

  • ghci thbug.hs
  • ignore the error
  • comment out the newName, uncomment the mkName in Fun.hs
  • :r

This is the result:

$ ghc-7.9.20141108 --interactive thbug.hs 
GHCi, version 7.9.20141108: http://www.haskell.org/ghc/  :? for help
[1 of 2] Compiling Fun              ( Fun.hs, interpreted )
[2 of 2] Compiling Main             ( thbug.hs, interpreted )

thbug.hs:4:1:
    Duplicate exact Name ‘X’
      Probable cause: you used a unique Template Haskell name (NameU), 
      perhaps via newName, but bound it multiple times
      If that's it, then -ddump-splices might be useful
Failed, modules loaded: Fun.

...
Comment out the newName, uncomment the mkName in Fun.hs.
...

*Fun> :r
[1 of 2] Compiling Fun              ( Fun.hs, interpreted )
[2 of 2] Compiling Main             ( thbug.hs, interpreted )
ghc: panic! (the 'impossible' happened)
  (GHC version 7.9.20141108 for x86_64-unknown-linux):
	kcLookupKind APromotionErr RecDataConPE

So the first 'duplicate exact name X' error leaves GHCi in some inconsistent state.

comment:3 Changed 4 years ago by thomie

Priority: normalhigh

Still reproducible with HEAD. The first error (that you should ignore) is now:

thbug.hs:4:1: error:
    Same exact name in multiple name-spaces:
      type constructor or class ‘X’, declared at: thbug.hs:4:1
      data constructor ‘X’, declared at: thbug.hs:4:1
      Probable cause: you bound a unique Template Haskell name (NameU),
      perhaps via newName, in different name-spaces.
      If that's it, then -ddump-splices might be useful

And the panic:

ghc: panic! (the 'impossible' happened)
  (GHC version 7.11.20151213 for x86_64-unknown-linux):
	kcLookupKind APromotionErr RecDataConPE

Panics are bad, raising priority.

comment:4 Changed 4 years ago by bgamari

Cc: goldfire added

Cc'ing Richard, who is our (very busy) Template Haskell czar.

comment:5 Changed 4 years ago by bollmann

upon a quick look at the code the initial error message is thrown in module rename/RnEnv.hs by function lookupExactOcc_either. But I'm unsure why this leaves ghci in an inconsistent state afterwards.

comment:6 Changed 3 years ago by RyanGlScott

Still reproducible on HEAD, but you'll need a different Fun.hs:

module Fun where
import Language.Haskell.TH

stuff = do
  -- let x = mkName "X"
  x <- newName "X"
  sequence $ [dataD (return []) x [] Nothing [
      normalC x []
    ] []]

And you'll get a slightly different error message:

λ> :r
[1 of 2] Compiling Fun              ( Fun.hs, interpreted )
[2 of 2] Compiling Main             ( thbug.hs, interpreted )
ghc: panic! (the 'impossible' happened)
  (GHC version 8.1.20161010 for x86_64-unknown-linux):
        kcLookupTcTyCon
  APromotionErr RecDataConPE
  Call stack:
      CallStack (from HasCallStack):
        prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1076:58 in ghc:Outputable
        callStackDoc, called at compiler/utils/Outputable.hs:1080:37 in ghc:Outputable
        pprPanic, called at compiler/typecheck/TcHsType.hs:1656:27 in ghc:TcHsType

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

comment:7 Changed 15 months ago by mgsloan

Is this still an issue? I cannot reproduce it with latest GHC master.

comment:8 Changed 15 months ago by RyanGlScott

Indeed, it looks like this was fixed! In that case, we should add a regression test for this in GHC's test suite.

mgsloan, do you want to pick up this task?

comment:9 Changed 15 months ago by mgsloan

@RyanGIScott Sure! It was interesting figuring out a good way to test issues that only reproduce due to reload. The approach I've taken seems pretty clean to me and might be useful for other such recompilation / reload tests. https://phabricator.haskell.org/D4926

It turns out that there is indeed still some funky statefulness going on. Fresh load of the modified version works fine, whereas reload after modification yields Data constructor ‘X’ used as a type constructor. Nice that it's not a panic, but not correct and indicates some spooky statefulness.

comment:10 Changed 15 months ago by Ben Gamari <ben@…>

In fbe162f5/ghc:

Add a broken test for lingering state from TH unique names #9693

The stderr output is

```
Loading with T9693_initial.hs

T9693_main.hs:4:1:
    Same exact name in multiple name-spaces:
      type constructor or class ‘X’, declared at: T9693_main.hs:4:1
      data constructor ‘X’, declared at: T9693_main.hs:4:1
      Probable cause: you bound a unique Template Haskell name (NameU),
      perhaps via newName, in different name-spaces.
      If that's it, then -ddump-splices might be useful
Reloading with T9693_modified.hs

T9693_main.hs:1:1:
    Data constructor ‘X’ used as a type constructor
```

The strange thing is that the modified version uses (mkName "X"), which should
be fine for simultaneous use in both a data constructor and type constructor.
Indeed, on a fresh load, the modified version works fine. So there is some sort
of state left over from the prior load when (newName "X") was used.

Test Plan: testsuite/tests/th/T9693.script

Reviewers: bgamari, sighingnow, RyanGlScott

Reviewed By: sighingnow, RyanGlScott

Subscribers: RyanGlScott, sighingnow, rwbarton, thomie, carter

Differential Revision: https://phabricator.haskell.org/D4926

comment:11 Changed 8 months ago by mpickering

Priority: highnormal
Note: See TracTickets for help on using tickets.