[GHC] #9380: ghc generates seemingly incorrect code

GHC ghc-devs at haskell.org
Thu Jul 31 12:20:16 UTC 2014


#9380: ghc generates seemingly incorrect code
-------------------------------------+-------------------------------------
              Reporter:  qnikst      |            Owner:
                  Type:  bug         |           Status:  infoneeded
              Priority:  normal      |        Milestone:
             Component:  Compiler    |          Version:  7.8.3
            Resolution:              |         Keywords:
      Operating System:              |     Architecture:  Unknown/Multiple
  Unknown/Multiple                   |       Difficulty:  Unknown
       Type of failure:  Incorrect   |       Blocked By:
  result at runtime                  |  Related Tickets:
             Test Case:              |
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I think I know what is going on.  Consider `test0`:
 {{{
 test0 = let s = cast A (SomeS (S 0))
         in case viewV0 s of
                V0A{} -> putStrLn "test0 - A"
                V0B{} -> putStrLn "test0 - B"
 }}}
 Remember that `cast :: forall a. M -> SomeS -> S a`, so that `s` is a
 polymorphic value: `s :: forall (x::M). S x`.

 Now at the occurrence of `s` on the next line, GHC has to choose what type
 to instantiate `s` at; that is, what to instantiate `x` with.  The calling
 context is no help, so GHC simply has to guess any old type, of kind `M`.
 It could randomly choose `A` or `B`, but that seems arbitrary.  So it
 chooses `Any M`, where `Any :: forall k. k` is a built-in type family that
 has no equations.  It's as if it was declared with
 {{{
 type family Any :: k
 }}}
 So now `(viewV0 s)` has type `V0 (Any M)`.

 The trouble is that in GHC 7.8, `Any` was a ''data type'' not a type
 family.  That was wrong for many reasons, but this ticket exposes a new
 one.  In a `case` expression, GHC discards any patterns that can't
 possibly match the scrutinee.  The two patterns in the case expression in
 `test0` have types `V0 A` and `V0 B`.  Since `A` and `Any M` are different
 (if `Any` is a data type) GHC discarded that alternative, and the same for
 the other one.

 In HEAD, `Any` is a type family (see #9097), so GHC (rightly) does not
 know that `Any M` and `A` are distinct.  So the alternative is not
 discarded.

 I have not followed through all the other cases, but I bet that it's all
 attributable to that one fix.

 I will add this as regression test, despite the unsavoury use of
 `unsafeCoerce`.

 I don't propose to fix 7.8.4. I think there were various reasons that
 `Any` was not made a type family earlier.


 Simon

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9380#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list