#5448: GHC stuck in infinite loop compiling with optimizations
-------------------------------+--------------------------------------------
    Reporter:  ronwalf         |        Owner:                    
        Type:  bug             |       Status:  new               
    Priority:  normal          |    Milestone:                    
   Component:  Compiler        |      Version:  7.0.3             
    Keywords:                  |     Testcase:                    
   Blockedby:                  |   Difficulty:                    
          Os:  MacOS X         |     Blocking:                    
Architecture:  x86_64 (amd64)  |      Failure:  Compile-time crash
-------------------------------+--------------------------------------------

Comment(by simonpj):

 Actually, yes, it ''is'' an example of the classic inliner-looping bug.
 Here's a very slightly simpler version (no need for `deriving Eq`):
 {{{
 module GHCLoop where

 newtype Expr f = In (f (Expr f))

 class FuncEq f where
     funcEq :: FuncEq g => f (Expr g) -> f (Expr g) -> Bool

 instance (FuncEq f) => Eq (Expr f) where
     (In x) == (In y) = funcEq x y

 data Not e = Not e

 instance FuncEq Not where
     funcEq (Not x) (Not y) = x == y     -- x,y :: Expr g
                                         -- Needs Eq (Expr g)
                                         --   = $c== (funcEq g)

 foo :: Expr Not -> Bool
 foo x = x == x
 }}}

 The classic bug shows up when you have a type declared with a
 contravariant occurrence of itself. Something like:
 {{{
 data T = MkT (T -> Int)

 get (MkT f) = f
 foo t = get t t    -- Loops
 }}}
 And that is what we get here: the dictionary for `FunEq` looks like this:
 {{{
 data FunEq f = MkD (forall g. FuncEq g -> f (Expr g) -> f (Expr g) ->
 Bool)
 }}}
 When `f` and `g` both get instantiated to the same type, we are in the
 contravariant situation, and that's exactly what happens here.  Here are
 my notes on what happens (mainly for me):
 {{{
 Rule fired: Class op funcEq
 Inlining done: $cfuncEq{v akX} [lid]
 Inlining done: $c=={v alm} [lid]


 $cfuncEq $dfuncEq = ...$c== $dfuncEq...
 $c== $dfuncEq = ...funcEq $dfuncEq $dfuncEq...

 $funcEqNot = MkD $cfuncEq

 $sc== = ...funcEq $funcEqNot $funcEqNot...


 funcEq $funcEqNot $funcEqNot
 --> $cfuncEq $funcEqnot
 --> $c== $funcEqNot
 --> funcEq $funcEqNot $funcEqNot
 }}}
 So this is the first time I've seen a ''real'' example of the bug.  You
 can probably work around it with a judicious NOINLINE pragma.  But really
 we need something better.

 Your example is a more convincing version of #5400.

 See also #3400, #3872.

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

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to