[GHC] #14521: Infinite loop at runtime

GHC ghc-devs at haskell.org
Tue Nov 28 16:45:23 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:                    |
-------------------------------------+-------------------------------------
Changes (by bgamari):

 * status:  new => closed
 * resolution:   => invalid


Comment:

 So I'm not certain why the program runs successfully without optimization,
 but it seems to me like the compiler indeed  loop. The gist of the program
 (eliminating some irrelevant bits) is
 {{{#!hs
 data Animator a = Animator {
   _animatorIO   :: !(Tree -> Animation  -> IO (Maybe Animation))
 }

 mkAnimator :: (t -> Tree -> Animation -> IO (Maybe Animation))
            -> t
            -> Animator a
 mkAnimator io_ params = Animator (io_ params)


 animatedNumber :: Int -> Tree -> Animation  -> IO (Maybe Animation)
 animatedNumber n =
   animate' (mkAnimator animatedNumber n)
 }}}

 After inlining `mkAnimator` into `animatedNumber` and expressing the
 constructor's strictness explicitly we have,
 {{{#!hs
 animatedNumber :: Int -> Tree -> Animation  -> IO (Maybe Animation)
 animatedNumber n =
   animate' (let x = animatedNumber n
             in x `seq` Animator x)
 }}}
 Consequently if `animate'` demands its argument the program will loop.
 This function is defined as,
 {{{#!hs
 animate' :: Animator a -> Tree -> Animation  -> IO (Maybe Animation)
 animate' (Animator pure_ io_) = animate pure_ io_
 }}}
 Which indeed does demand its argument. Moreover, this is consistent with
 your observation that adding an `INLINE` on `animate'` eliminates the loop
 (since in the real program `Animator` contains two fields, only the first,
 which I elided above, is needed).

 Given this, it seems like looping is a completely valid compilation of
 this program. I would remove the bang from the constructor if laziness is
 needed (which it seems it is).

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


More information about the ghc-tickets mailing list