Opened 8 years ago

Last modified 3 months ago

#3872 new bug

New way to make the simplifier diverge

Reported by: simonpj Owned by:
Priority: normal Milestone:
Component: Compiler Version: 6.12.1
Keywords: Cc: anton.nik@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #5400 #5448 Differential Rev(s):
Wiki Page:


GHC's simplifier can go into a loop if you use fixpoints in a funny way, as documented here (12.2.1, third bullet). But GADTs provide new opportunities. This ticket records one, thanks to Ryan Ingram and Matthieu Sozeau:

module Contr where

newtype I f = I (f ())
data R o a where R :: (a (I a) -> o) -> R o (I a)

run :: R o (I (R o)) -> R o (I (R o)) -> o
run x (R f) = f x
rir :: (R o) (I (R o))
rir = R (\x -> run x x)

absurd :: a
absurd = run rir rir

Now the simplifier can loop. Look:

run rir rir

= {inline run}
  case rir of R f -> f rir

= {case of known constructor}
  let { f = \x -> run x x } in f rir

= {inline f}
  run rir rir

Change History (3)

comment:1 Changed 8 years ago by lelf

Cc: anton.nik@… added

comment:2 Changed 7 years ago by simonpj

See also #5400

comment:3 Changed 3 months ago by sgraf

This doesn't loop infinitely anymore with GHC 8.2.1 and instead panics:

ghc.exe: panic! (the 'impossible' happened)
  (GHC version 8.2.1 for x86_64-unknown-mingw32):
        Simplifier ticks exhausted
  When trying UnfoldingDone rir_s1bm
  To increase the limit, use -fsimpl-tick-factor=N (default 100)
  If you need to do this, let GHC HQ know, and what factor you needed
  To see detailed counts use -ddump-simpl-stats
  Total ticks: 11721
  Call stack:
      CallStack (from HasCallStack):
        prettyCurrentCallStack, called at compiler\utils\Outputable.hs:1133:58 in ghc:Outputable
        callStackDoc, called at compiler\utils\Outputable.hs:1137:37 in ghc:Outputable
        pprPanic, called at compiler\simplCore\SimplMonad.hs:199:31 in ghc:SimplMonad

I think this should result in a warning rather than in a crash.

Note: See TracTickets for help on using tickets.