[GHC] #14521: Infinite loop at runtime

GHC ghc-devs at haskell.org
Tue Nov 28 17:02:32 UTC 2017


#14521: Infinite loop at runtime
-------------------------------------+-------------------------------------
        Reporter:  OlivierSohn       |                Owner:  (none)
            Type:  bug               |               Status:  closed
        Priority:  high              |            Milestone:  8.2.3
       Component:  Compiler          |              Version:  8.2.2
      Resolution:  invalid           |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Incorrect result  |  Unknown/Multiple
  at runtime                         |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I took a quick look.  To me it looks as if it should definitely loop.
 Look at the code
 {{{
 animatedNumber n = animate' (mkAnimator animateNumberPure animatedNumber
 n)

 mkAnimator pure_ io_ params = Animator (applyAnimation (pure_ params))
 (io_ params)

 animate' (Animator pure_ io_) = animate pure_ io_
 }}}
 If we just inline `mkAnimator` we see:
 {{{
 animatedNumber n = animate' (Animator blah (animatedNumber n))
 }}}
 Now
 * `Aminator` is declared to be strict in its second argument
 * `animate'` is certainly strict
 So of course `animatedNumber n` will just return bottom.

 The mystery is not why it diverges -- it should! -- but rather why it
 sometimes fails to diverge.  The answer is that GHC allows itself a bit of
 leeway in making a divergent program into one that converges, in the
 interests of improving runtimes generally by allowing more optimisations.
 You can switch off this behaviour by using `-fpedantic-bottoms`, and then
 sure enough it always diverges.

 In this case the relevant optimisation is eta-expansion.  If you do manual
 eta-expansion on
 `animate'`, then it converges, always:
 {{{
 animate' :: Animator a -> Tree -> Animation  -> IO (Maybe Animation)
 animate' (Animator pure_ io_) t a = animate pure_ io_ t a
 }}}

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


More information about the ghc-tickets mailing list