enumFrom error thwarts checkOldIface's exception handling
This bug needs a bit of jiggery-pokery to reproduce.
First, we need to create a malformed hi file that we will feed checkOldIface
. First, have a fresh build of GHC. Apply the following diff to your tree:
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index 7a585f3..4e41887 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -1033,7 +1033,8 @@ instance Binary ModIface where
put_ bh vect_info
put_ bh hpc_info
put_ bh trust
- put_ bh trust_pkg
+ putByte bh 3
+ -- put_ bh trust_pkg
get bh = do
mod <- get bh
Next, rebuild ONLY the stage 2 compiler using cd ghc; make stage=2 -j12 fast
. Now, use the new stage2 compiler to compile some module (it can be empty):
[ezyang@hs01 ghc-backpack]$ inplace/bin/ghc-stage2 -c A.hs
[ezyang@hs01 ghc-backpack]$ inplace/bin/ghc-stage2 -c A.hs
ghc-stage2: panic! (the 'impossible' happened)
(GHC version 8.1.20161006 for x86_64-unknown-linux):
Prelude.Enum.Bool.toEnum: bad argument
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
With -v3
, we see that this error occurred when checking the old interface:
[ezyang@hs01 ghc-backpack]$ inplace/bin/ghc-stage2 -c A.hs -v3
Glasgow Haskell Compiler, Version 8.1.20161006, stage 2 booted by GHC version 8.0.1
Using binary package database: /home/hs01/ezyang/ghc-backpack/inplace/lib/package.conf.d/package.cache
package flags []
loading package database /home/hs01/ezyang/ghc-backpack/inplace/lib/package.conf.d
wired-in package ghc-prim mapped to ghc-prim-0.5.0.0
wired-in package integer-gmp mapped to integer-gmp-1.0.0.1
wired-in package base mapped to base-4.9.0.0
wired-in package rts mapped to rts
wired-in package template-haskell mapped to template-haskell-2.11.0.0
wired-in package ghc mapped to ghc-8.1
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags:
*** Checking old interface for A:
Dastardly. We've choked checking the old interface!
The problem seems to be that the toEnum
exception is not an IOException
, so we don't catch it in tryMost
(which readIface
uses to catch errors). Funnily enough, the comment above says precisely, TODO: I'm not entirely sure if this is catching what we really want to catch
. But to catch these, we'll have to catch all UserError
s (because that is what is being thrown in this case.) Maybe a bridge too far? Another possibilty is to use some home-baked toEnum
which catches errors of this sort. Anyway, the fix should be simple, we just have to decide what to do.
Trac metadata
Trac field | Value |
---|---|
Version | 8.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | bgamari |
Operating system | |
Architecture |