[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