Ticket #2739 (closed bug: fixed)

Opened 5 years ago

Last modified 4 years ago

GHC API crashes on template haskell splices

Reported by: waern Owned by: nominolo
Priority: normal Milestone: 6.10.2
Component: Compiler Version: 6.10.1
Keywords: Cc: david.waern@…, leather@…, sanzhiyan@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

The GHC API crashes when type checking these two modules:

TH.hs:

{-# LANGUAGE TemplateHaskell #-}

module TH where

import Language.Haskell.TH

decl = [d| f x = x]

TH2.hs:

{-# LANGUAGE TemplateHaskell #-}

module TH2 where

import TH

$( decl )

The crash happens in HscMain.compileExpr, when compiling and linking the spliced-in code. The crash is due to a fromJust: Nothing. I don't have the error message at hand.

It would be nice if this could be fixed in 6.10.* since it makes Haddock crash when processing several packages on Hackage.

I will add both TH.hs and TH2.hs to the test suite in the code.haskell.org/haddock repository later. (I thought I had done this, but I apparently forgot to add TH.hs). You can the use test/runtests.hs to invoke the crash.

Change History

  Changed 4 years ago by simonpj

  • difficulty set to Unknown

This stuff compiles fine using the compiler alone (see below) so it must be something to do with the GHC API.

ghc -c TH.hs
bash-3.2$ ghc -c TH2.hs
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Loading package syb ... linking ... done.
Loading package array-0.2.0.0 ... linking ... done.
Loading package packedstring-0.1.0.1 ... linking ... done.
Loading package containers-0.2.0.0 ... linking ... done.
Loading package pretty-1.0.1.0 ... linking ... done.
Loading package template-haskell ... linking ... done.
bash-3.2$ rm *.o
rm: remove regular file `TH2.o'? y
rm: remove regular file `TH.o'? y
bash-3.2$ ghc --make TH2.hs
[1 of 2] Compiling TH               ( TH.hs, TH.o )
[2 of 2] Compiling TH2              ( TH2.hs, TH2.o )
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Loading package syb ... linking ... done.
Loading package array-0.2.0.0 ... linking ... done.
Loading package packedstring-0.1.0.1 ... linking ... done.
Loading package containers-0.2.0.0 ... linking ... done.
Loading package pretty-1.0.1.0 ... linking ... done.
Loading package template-haskell ... linking ... done.
bash-3.2$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.10.1
bash-3.2$ 

  Changed 4 years ago by nominolo

  • owner set to nominolo
  • status changed from new to assigned

I cannot reproduce a fromJust error, however, when compiling with the GHC API with HscNothing as target, I get a message explaining that the closure for decl could not be found. This makes sense since in nothing-mode we fake a bytecode object to avoid recompilation of that module when its source hasn't changed.

So we have to decide how to deal with this. We could probably detect dependency whether TH is being used during dependency analysis and either fail or force the target to HscInterpreted or HscC since the former may fail if, for example, unboxed tuples are used anywhere in the source.

Using HEAD's haddock it consequently fails in Linker.getLinkDeps:

$ ../../ghc/utils/haddock/install-inplace/bin/haddock.exe -B ../../ghc/ TH2.hs
haddock: internal Haddock or GHC error: expectJust getLinkDeps

I have to think about what a reasonable solution would be.

  Changed 4 years ago by igloo

  • milestone set to 6.10.2

  Changed 4 years ago by waern

I tried to fix this issue in Haddock, by using needsTemplateHaskell from the GHC API, and checking this right after doing the depanal, and then setting the target to HscC before going ahead with typechecking. This works.

However, since HscC is a bit heavy, I also tried HscInterpreted. But then another Haddock test fail, namely TypeFamilies.hs:

{-# LANGUAGE TypeFamilies #-}

module TypeFamilies where

-- | Type family G
type family G a :: *

-- | A class with an associated type
class A a where
  -- | An associated type
  data B a :: * -> *
  -- | A method
  f :: B a Int

-- | Doc for family
type family F a


-- | Doc for G Int
type instance G Int = Bool
type instance G Float = Int


instance A Int where
  data B Int x = Con x
  f = Con 3

g = Con 5

The error message is:

During interactive linking, GHCi couldn't find the following symbol:
  g
This may be due to you not asking GHCi to load extra object files,
archives or DLLs needed by your current session.  Restart GHCi, specifying
the missing library using the -L/path/to/object/dir and -lmissinglibname
flags, or simply by naming the relevant files on the GHCi command line.
Alternatively, this link failure might indicate a bug in GHCi.
If you suspect the latter, please send a bug report to:
  glasgow-haskell-bugs@haskell.org

Is this an orthogonal TypeFamilies? bug I've stumbled upon?

If HscIntepreted would work, I was thinking we could use it instead of HscC and eventually try to find some way to work around the problem exemplified by unboxed tuples (stuff for which HscInterpreted doesn't help).

Or perhaps a more fine-grained check could be provided by the GHC API to check exactly which modules need to use which flag. In that case, using HscC may not be so bad.

  Changed 4 years ago by waern

  • cc david.waern@… added

follow-up: ↓ 7   Changed 4 years ago by simonpj

Maybe you have stumbled on a type-families bug. But I can't tell unless I can reproduce it. Can you make it happen with GHCi? If not, how can I reproduce it?

Simon

in reply to: ↑ 6   Changed 4 years ago by waern

Replying to simonpj:

Maybe you have stumbled on a type-families bug. But I can't tell unless I can reproduce it. Can you make it happen with GHCi? If not, how can I reproduce it? Simon

I tried to reproduce it by loading the (above) TypeFamilies? module in GHCi, but that didn't do it. I'll see if I can come up with a test case using the GHC API later.

Regarding the original problem, I discovered that it is still present when using the 6.10.2 branch of GHC. I think the reason may be the lack of this patch:

Fri Nov 28 17:44:12 CET 2008  Thomas Schilling <nominolo@googlemail.com>
  * Let 'loadModule' generate proper code depending on the 'hscTarget'.
  
  With this change it should be possible to perform something similar to
  'load' by traversing the module graph in dependency order and calling
  '{parse,typecheck,load}Module' on each.  Of course, if you want smart
  recompilation checking you should still use 'load'.

Thomas has agreed to try to back-port this fix.

  Changed 4 years ago by spl

  • cc leather@… added

  Changed 4 years ago by guest

  • cc sanzhiyan@… added

  Changed 4 years ago by waern

Hi,

I'd just like to point out that it's pretty important that we try to back-port the above patch to GHC 6.10.2 since Haddock will continue to be broken on packages that uses TH otherwise.

  Changed 4 years ago by nominolo

  • status changed from assigned to closed
  • resolution set to fixed

The above patched has been back-ported and appears to work. Re-open this bug if you encounter any problems.

Note: See TracTickets for help on using tickets.