[GHC] #9562: Type families + hs-boot files = unsafeCoerce
GHC
ghc-devs at haskell.org
Sat Sep 6 23:58:21 UTC 2014
#9562: Type families + hs-boot files = unsafeCoerce
-------------------------------------+-------------------------------------
Reporter: goldfire | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.3
Keywords: | Operating System:
Architecture: Unknown/Multiple | Unknown/Multiple
Difficulty: Unknown | Type of failure: GHC
Blocked By: | accepts invalid program
Related Tickets: | Test Case:
| Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Consider the following bundle of modules:
A.hs:
{{{#!hs
{-# LANGUAGE TypeFamilies #-}
module A where
type family F a b
}}}
B.hs-boot:
{{{#!hs
module B where
import A
oops :: F a b -> a -> b
}}}
B.hs:
{{{#!hs
{-# LANGUAGE TypeFamilies #-}
module B where
import A
import C
type instance F a b = b
oops :: F a b -> a -> b
oops = const
}}}
C.hs:
{{{#!hs
module C (oops) where
import {-# SOURCE #-} B
}}}
D.hs:
{{{#!hs
{-# LANGUAGE TypeFamilies #-}
module D where
import A
import C
type instance F a b = a
unsafeCoerce :: a -> b
unsafeCoerce x = oops x x
}}}
Main.hs:
{{{#!hs
module Main where
import D ( unsafeCoerce )
main = print $ (unsafeCoerce True :: Int)
}}}
When loading these into GHCi, we quite reasonably get a type family
instance overlap error. But, separate compilation leads to disaster:
{{{
rae:01:49:47 ~/temp/bug> ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.3
rae:01:49:49 ~/temp/bug> ghc -c A.hs
rae:01:49:53 ~/temp/bug> ghc -c B.hs-boot
rae:01:49:58 ~/temp/bug> ghc -c C.hs
rae:01:50:09 ~/temp/bug> ghc -c B.hs
rae:01:50:13 ~/temp/bug> ghc -c D.hs
rae:01:50:17 ~/temp/bug> ghc Main.hs -o Unsafe
[6 of 6] Compiling Main ( Main.hs, Main.o )
Linking Unsafe ...
rae:01:50:23 ~/temp/bug> ./Unsafe
2882303761534249061
}}}
Yikes!
Proposed (terrible) solution: hs-boot files '''must''' list all type
instance declarations in the corresponding modules. It may also be a good
idea to require all normal instance declarations in the hs-boot file as
well, because this same trick can be used to introduce incoherence (I
think -- haven't tested).
This bug persists even if `Main` declares that it is `Safe`.
I've attached a tarball of the files for ease of testing.
(Credit to Edward Yang and Geoff Mainland, whose discussion provoked the
line of inquiry that led to this discovery.)
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9562>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list