Opened 4 years ago

Last modified 17 months ago

#11774 new bug

Regression on GHC 8 branch (vs 7.10.3) when using the GHC API to parse code that uses TH

Reported by: SimonHengel Owned by:
Priority: normal Milestone:
Component: GHC API Version: 8.0.1-rc2
Keywords: RemoteGHCi Cc: simonmar
Operating System: Linux Architecture: Unknown/Multiple
Type of failure: Incorrect result at runtime Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


If you use the GHC API to parse code that uses TH, the code does not work after a :reload in ghci anymore.

Steps to reproduce

Given the following three modules

module Extract where
import Prelude hiding (mod)
import Data.Generics
import DynFlags
import FastString
import GHC
import GHC.Paths
import Control.Monad
import Digraph (flattenSCCs)

extractDocStrings :: IO [String]
extractDocStrings = do
  concatMap (extract . pm_parsed_source . tm_parsed_module) <$> do
    runGhc (Just libdir) $ do
      _ <- getSessionDynFlags >>= setSessionDynFlags . setHaddockMode
      guessTarget "Foo.hs" Nothing >>= setTargets . return
      mods <- depanal [] False >>= enableCompilation
      let sortedMods = flattenSCCs (topSortModuleGraph False mods Nothing)
      mapM (parseModule >=> typecheckModule >=> loadModule) sortedMods
    setHaddockMode :: DynFlags -> DynFlags
    setHaddockMode dynflags = (gopt_set dynflags Opt_Haddock)

    extract :: ParsedSource -> [String]
    extract m = [unpackFS s | HsDocString s <- everything (++) ([] `mkQ` return) m]

enableCompilation :: ModuleGraph -> Ghc ModuleGraph
enableCompilation modGraph = do
  let enableComp d = let platform = targetPlatform d
                      in d { hscTarget = defaultObjectTarget platform }
  modifySessionDynFlags enableComp
  let upd m = m { ms_hspp_opts = enableComp (ms_hspp_opts m) }
  let modGraph' = map upd modGraph
  return modGraph'

modifySessionDynFlags :: (DynFlags -> DynFlags) -> Ghc ()
modifySessionDynFlags f = do
  dflags <- getSessionDynFlags
  let dflags' = case lookup "GHC Dynamic" (compilerInfo dflags) of
        Just "YES" -> gopt_set dflags Opt_BuildDynamicToo
        _          -> dflags
  _ <- setSessionDynFlags (f dflags')
  return ()
{-# LANGUAGE TemplateHaskell #-}
module Foo where

import Bar

-- | some documentation
foo :: Int
foo = $(bar)
{-# LANGUAGE TemplateHaskell #-}
module Bar where

bar = [|23|]

Expected (GHC 7.10.2 behavior)

$ ghci Extract.hs 
GHCi, version 7.10.2:  :? for help
*Extract> extractDocStrings 
[" some documentation"]
*Extract> :reload 
*Extract> extractDocStrings 
[" some documentation"]

Actual (GHC behavior)

$ ghci Extract.hs 
GHCi, version  :? for help
*Extract> extractDocStrings 
[" some documentation"]
*Extract> :reload
*Extract> extractDocStrings 
/tmp/ghc24970_1/ file not recognized: File truncated
collect2: error: ld returned 1 exit status
*** Exception: `gcc' failed in phase `Linker'. (Exit code: 1)

Change History (4)

comment:1 Changed 4 years ago by SimonHengel

Type of failure: None/UnknownIncorrect result at runtime

comment:2 Changed 3 years ago by thomie

Component: CompilerGHC API

Reproducible with HEAD (ghc-8.1.20160515). First run cabal install ghc-paths syb. Then run ghci -package ghc Extract.hs

Solution / workaround: use ghci -fexternal-interpreter.

comment:3 Changed 2 years ago by RyanGlScott

Cc: simonmar added

The workaround is what broke this, ironically enough, since this regression was caused by commit 4905b83a2d448c65ccced385343d4e8124548a3b (Remote GHCi, -fexternal-interpreter).

comment:4 Changed 17 months ago by simonmar

Keywords: RemoteGHCi added
Note: See TracTickets for help on using tickets.