[GHC] #5722: GHC inlines class method forever

GHC cvs-ghc at haskell.org
Wed Dec 28 15:00:11 CET 2011


#5722: GHC inlines class method forever
---------------------------------+------------------------------------------
    Reporter:  benmachine        |       Owner:  simonpj           
        Type:  bug               |      Status:  new               
    Priority:  normal            |   Milestone:  _|_               
   Component:  Compiler          |     Version:  7.2.1             
    Keywords:                    |          Os:  Unknown/Multiple  
Architecture:  Unknown/Multiple  |     Failure:  Compile-time crash
  Difficulty:  Unknown           |    Testcase:                    
   Blockedby:                    |    Blocking:                    
     Related:                    |  
---------------------------------+------------------------------------------
Changes (by simonpj):

  * milestone:  7.6.1 => _|_


Comment:

 Thanks.  This is almost identical to #5448, but even simpler.  For the
 record, here's an even simpler example
 {{{
 class C a b where
    discord :: C a b => a b () -- Remove the constraint and it works

 instance C (,) b => C (,) [b] where
    discord = discord

 foo :: C (,) b => (,) [b] ()
 foo = discord
 }}}
 Here is how it plays out.  We get this code (in reality the `MkC` stuff is
 a newtype, but that's irrelevant):
 {{{
 $cd d1 d2 = discord d2 d2
 discord d = case d of MkC x -> x
 $fC d = MkC ($cd d)

 foo d = discord ($fC d) ($fC d)
 }}}
 None of these definitions are recursive. So when we simplify `foo` we get
 {{{
 discord ($fC d) ($fC d)
 --> (case ($fC d) of MkC x -> x) ($fC d)
 --> (case (MkC ($cd d)) of MkC x -> x) ($fC d)
 --> $cd d ($fC d)
 --> discord ($fC d) ($fC d)
 }}}
 and there is the loop.

 The culprit is, as usual, the data type for the dictionary, which has
 itself appearing contravariantly:
 {{{
 data C a b = MkC (C a b => a b ())
 }}}

 The tick-count thing means that with 5.4 we get `Simplifier ticks
 exhausted`, and adding `-ddump-simpl-stats` points fairly clearly to the
 culprit.  It's fixable by adding `{-# NOINLINE discord #-}` on the
 instance declaration.

 None of this is satisfactory.  The difficulty is that I do not know how to
 solve the problem in general -- at least not without hobbling the
 optimiser.  I suppose that we could spot the special case of a class that
 mentions itself in the context of a class method, but that is a very
 special case.

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



More information about the Glasgow-haskell-bugs mailing list