With GHC 7.8.1, compilation failure makes cabal repl exit early #1715

Closed
pikajude opened this Issue Mar 5, 2014 · 16 comments

Comments

Projects
None yet
9 participants

pikajude commented Mar 5, 2014

$ brew switch ghc 7.8.0.20140228
$ cabal repl
Preprocessing library cabal-exit-early-0.0.0...
[1 of 1] Compiling A                ( A.hs, dist/build/A.o )

A.hs:1:11: Not in scope: ‘a’
$ brew switch ghc 7.6.3
$ cabal repl
Preprocessing library cabal-exit-early-0.0.0...
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling A                ( A.hs, interpreted )

A.hs:1:11: Not in scope: `a'
Failed, modules loaded: none.
>>= ^D
Leaving GHCi.
$

Test package is trivial:

name:              cabal-exit-early
version:           0.0.0
cabal-version:     >= 1.8
build-type:        Simple

library
    exposed-modules: A
    build-depends: base
module A (a) where

With GHC 7.8, cabal repl -v3:

Using internal setup method with build-type Simple and args:
["repl","--verbose=3","--builddir=dist"]
Component build order: library
creating dist/build
creating dist/build/autogen
Preprocessing library cabal-exit-early-0.0.0...
("/usr/local/bin/ghc",["--info"])
("/usr/local/bin/ghc",["--info"])
creating dist/build
Environment: (removed)
("/usr/local/bin/ghc",["--make","-v","-fbuilding-cabal-package","-O2","-static","-dynamic-too","-dynosuf","dyn_o","-dynhisuf","dyn_hi","-outputdir","dist/build","-odir","dist/build","-hidir","dist/build","-stubdir","dist/build","-i","-idist/build","-i.","-idist/build/autogen","-Idist/build/autogen","-Idist/build","-optP-include","-optPdist/build/autogen/cabal_macros.h","-package-name","cabal-exit-early-0.0.0","-hide-all-packages","-package-db","dist/package.conf.inplace","-package-id","base-4.7.0.0-fb03bfe8a1f8909585e120bf370d72fb","-XHaskell98","A"])
Glasgow Haskell Compiler, Version 7.8.0.20140228, stage 2 booted by GHC version 7.8.0.20140228
Using binary package database: /usr/local/Cellar/ghc/7.8.0.20140228/lib/ghc-7.8.0.20140228/package.conf.d/package.cache
Using binary package database: /Users/jztaylor/.ghc/x86_64-darwin-7.8.0.20140228/package.conf.d/package.cache
Using package config file: dist/package.conf.inplace
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-956814919b5482edf26ea1fe51da95b9
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-66adabd59b0be9f6df8506b708bbb9ab
wired-in package base mapped to base-4.7.0.0-fb03bfe8a1f8909585e120bf370d72fb
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-5cf2c715c8b93ff285548f30bcc3b8b0
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags: 
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-956814919b5482edf26ea1fe51da95b9
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-66adabd59b0be9f6df8506b708bbb9ab
wired-in package base mapped to base-4.7.0.0-fb03bfe8a1f8909585e120bf370d72fb
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-5cf2c715c8b93ff285548f30bcc3b8b0
wired-in package dph-seq not found.
wired-in package dph-par not found.
*** Chasing dependencies:
Chasing modules from: *A.hs
Stable obj: []
Stable BCO: []
Ready for upsweep
  [NONREC
      ModSummary {
         ms_hs_date = 2014-03-05 17:58:41 UTC
         ms_mod = cabal-exit-early-0.0.0:A,
         ms_textual_imps = [import (implicit) Prelude]
         ms_srcimps = []
      }]
*** Deleting temp files:
Deleting: 
compile: input file A.hs
Created temporary directory: /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80443_0
*** Checking old interface for cabal-exit-early-0.0.0:A:
[1 of 1] Compiling A                ( A.hs, dist/build/A.o )
*** Parser:
*** Renamer/typechecker:

A.hs:1:11: Not in scope: ‘a’
Upsweep partially successful.
*** Deleting temp files:
Deleting: /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80443_0/ghc80443_1.s
Warning: deleting non-existent /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80443_0/ghc80443_1.s
link(batch): upsweep (partially) failed OR
   Main.main not exported; not linking.
*** Deleting temp files:
Deleting: 
*** Deleting temp dirs:
Deleting: /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80443_0
/usr/local/bin/ghc returned ExitFailure 1

With GHC 7.6.3:

Using internal setup method with build-type Simple and args:
["repl","--verbose=3","--builddir=dist"]
Component build order: library
creating dist/build
creating dist/build/autogen
Preprocessing library cabal-exit-early-0.0.0...
("/usr/local/bin/ghc",["--info"])
("/usr/local/bin/ghc",["--info"])
creating dist/build
Environment: (removed)
("/usr/local/bin/ghc",["--interactive","-v","-fbuilding-cabal-package","-O0","-outputdir","dist/build","-odir","dist/build","-hidir","dist/build","-stubdir","dist/build","-i","-idist/build","-i.","-idist/build/autogen","-Idist/build/autogen","-Idist/build","-optP-include","-optPdist/build/autogen/cabal_macros.h","-package-name","cabal-exit-early-0.0.0","-hide-all-packages","-package-db","dist/package.conf.inplace","-package-id","base-4.6.0.1-6c351d70a24d3e96f315cba68f3acf57","-XHaskell98","A"])
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Glasgow Haskell Compiler, Version 7.6.3, stage 2 booted by GHC version 7.4.2
Using binary package database: /usr/local/Cellar/ghc/7.6.3/lib/ghc-7.6.3/package.conf.d/package.cache
Using package config file: dist/package.conf.inplace
wired-in package ghc-prim mapped to ghc-prim-0.3.0.0-d5221a8c8a269b66ab9a07bdc23317dd
wired-in package integer-gmp mapped to integer-gmp-0.5.0.0-2f15426f5b53fe4c6490832f9b20d8d7
wired-in package base mapped to base-4.6.0.1-6c351d70a24d3e96f315cba68f3acf57
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.8.0.0-c2c1b21dbbb37ace4b7dc26c966ec664
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags: -static
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
*** gcc:
'/usr/local/bin/gcc-4.2' '-m64' '-fno-stack-protector' '-m64' '-L/usr/local/Cellar/ghc/7.6.3/lib/ghc-7.6.3/base-4.6.0.1' '--print-file-name' 'libiconv.dylib'
Loading package base ... linking ... done.
*** Chasing dependencies:
Chasing modules from: 
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Ready for upsweep []
Upsweep completely successful.
*** Deleting temp files:
Deleting: 
*** Chasing dependencies:
Chasing modules from: *A.hs
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Ready for upsweep
  [NONREC
      ModSummary {
         ms_hs_date = 2014-03-05 17:58:41 UTC
         ms_mod = cabal-exit-early-0.0.0:A,
         ms_textual_imps = [import (implicit) Prelude]
         ms_srcimps = []
      }]
*** Deleting temp files:
Deleting: 
compile: input file A.hs
Created temporary directory: /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80134_0
*** Checking old interface for cabal-exit-early-0.0.0:A:
[1 of 1] Compiling A                ( A.hs, interpreted )
*** Parser:
*** Renamer/typechecker:

A.hs:1:11: Not in scope: `a'
Upsweep partially successful.
*** Deleting temp files:
Deleting: /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80134_0/ghc80134_0.o
Warning: deleting non-existent /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80134_0/ghc80134_0.o
Failed, modules loaded: none.
Leaving GHCi.
*** Deleting temp files:
Deleting: 
*** Deleting temp dirs:
Deleting: /var/folders/f3/xd2xgjh90dx7t8npycqfd3kjrgnmbn/T/ghc80134_0
Linking...
Prelude>
Member

23Skidoo commented Mar 5, 2014

Does cabal repl work with GHC 7.8 if you fix the compilation error? I see that ghc is not invoked with --interactive for some reason.

pikajude commented Mar 5, 2014

Yeah, it enters the REPL normally if there are no compilation errors. It also successfully stays in the REPL (as it should) if I introduce a compilation error, then :r.

Member

23Skidoo commented Mar 5, 2014

OK, I'll look into this.

@23Skidoo 23Skidoo self-assigned this Mar 5, 2014

@23Skidoo 23Skidoo added this to the cabal-install-1.20 milestone Mar 5, 2014

👍

spl commented Jun 5, 2014

I just switched 7.8.2 and ran into this problem as well. Any updates?

spl commented Jun 5, 2014

I see what you mean about not using --interactive. Unfortunately, it's not possible to work around this:

cabal repl --ghc-option=--interactive
Resolving dependencies...
[...]
ghc: on the commandline: cannot use `--make' with `--interactive'
Member

23Skidoo commented Jun 5, 2014

/cc @dcoutts

spl commented Jun 5, 2014

So I looked into it a bit. cabal repl runs ghc --make and, if it succeeds, then ghc --interactive:

("/opt/ghc/7.8.2/bin/ghc",["--make","-v","-fbuilding-cabal-package","-O","-static","-dynamic-too", ...
...
("/opt/ghc/7.8.2/bin/ghc",["--interactive","-v","-fbuilding-cabal-package","-O0", ...

I wonder if that is due to the line if isGhcDynamic then do shared; vanilla in Distribution.Simple.GHC.buildOrReplLib with the context:

unless (null (libModules lib)) $
  do let vanilla = whenVanillaLib forceVanillaLib (runGhcProg vanillaOpts)
         shared  = whenSharedLib  forceSharedLib  (runGhcProg sharedOpts)
         useDynToo = dynamicTooSupported &&
                     (forceVanillaLib || withVanillaLib lbi) &&
                     (forceSharedLib  || withSharedLib  lbi) &&
                     null (ghcSharedOptions libBi)
     if useDynToo
         then runGhcProg vanillaSharedOpts
         else if isGhcDynamic then do shared;  vanilla
                              else do vanilla; shared
     whenProfLib (runGhcProg profOpts)
Member

Philonous commented Jun 7, 2014

replacing

if useDynToo 

with

 if useDynToo && not forRepl

seems to fix the issue

Collaborator

ivan-m commented Jul 10, 2014

@Philonous's solution seems to work for me.

Member

23Skidoo commented Jul 11, 2014

It looks like fixing this is not as simple as skipping the ghc --make phase in buildOrReplLib when we're running repl.

The comment before the runGhcProg replOpts line says:

-- TODO: problem here is we need the .c files built first, so we can load them
-- with ghci, but .c files can depend on .h files generated by ghc by ffi
-- exports.

So the ghc --make step is there on purpose: ghc --interactive requires .c files (if any) to be built, which in turn may depend on auto-generated .h files, for producing which we need to run ghc --make first. Note to self: would be nice to add a test case.

Member

23Skidoo commented Jul 27, 2014

Looking at this again, it seems like the original intention was to skip the compile step completely for repl and leave the .c -> .h dependency issue as a TODO.

whenVanillaLib and whenSharedLib are defined as:

      whenVanillaLib forceVanilla =
        when (not forRepl && ...)

      whenSharedLib forceShared =
        when (not forRepl && ...)

Which is why @Philonous's fix works: the

else if isGhcDynamic then do shared;  vanilla
                          else do vanilla; shared

branch is a no-op when forRepl is True.

But since for GHC 7.8 isGhcDynamic is True and it supports -dynamic-too, we just run the runGhcProg vanillaSharedOpts branch, which doesn't check the value of forRepl. Which is why @joelteon was seeing different behaviour with GHC 7.8 and 7.6.

@23Skidoo 23Skidoo closed this in 6e6ec02 Jul 27, 2014

A workaround is to use --ghc-options="-fdefer-type-errors"

Not for, for example, names that aren't in scope.

Any progress on this? I'm affected by it very regularly. That is, if I've correctly identified this is the reason for haskell/haskell-mode#349.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment