简体   繁体   English

GHC在编译时崩溃

[英]GHC crashes while compiling

module Main where

newtype Rec a b = Rec {deRec :: Rec a b -> a}

infixl 1 >|>
infixl 1 <|<
(>|>) = Rec
(<|<) (Rec x) = x

fix f = (\x -> f (x <|< x)) (Rec (\x -> f (x <|< x)))
factorial = fix (\f x -> if x<=1 then 1 else x*f(x-1))

main = do 
   x <- getLine
   putStrLn (show (factorial (read x)))

GHC response: GHC回应:

ghc: panic! (the 'impossible' happened)
  (GHC version 7.6.3 for x86_64-apple-darwin):
    Simplifier ticks exhausted
    When trying UnfoldingDone a_sMx{v} [lid]
    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: 7121

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

What's wrong? 怎么了?

I think this is related to a known bug. 我认为这与已知的bug有关。 See Section 14.2 of the ghc manual: 参见ghc手册的14.2节:

http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/bugs.html http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/bugs.html

I'll reproduce the relevant section here: 我将在这里重现相关部分:

GHC's inliner can be persuaded into non-termination using the standard way to encode recursion via a data type: 使用标准方法通过数据类型编码递归,可以将GHC的inliner说服为非终止:

data U = MkU (U -> Bool)

russel :: U -> Bool
russel u@(MkU p) = not $ p u

x :: Bool
x = russel (MkU russel)

We have never found another class of programs, other than this contrived one, that makes GHC diverge, and fixing the problem would impose an extra overhead on every compilation. 我们从来没有发现过另一类程序,除了这个程序之外,它使GHC发散,修复问题会给每次编译带来额外的开销。 So the bug remains un-fixed. 所以bug仍然是不固定的。 There is more background in Secrets of the GHC inliner . GHC内衬的秘密有更多背景。

In other words, this bug arises when you use recursion in the negative position (ie the argument of a function). 换句话说,当您在负位置(即函数的参数)使用递归时会出现此错误。 From the manual, it appears that they have no intention of fixing this. 从手册中可以看出,他们无意解决这个问题。

As it was mentioned earlier, the problem arises when GHC's inliner working with function with parameters of recursive types. 正如前面提到的那样,当GHC内联使用具有递归类型参数的函数时,会出现问题。 This can be workarounded with NOINLINE pragma. 这可以与NOINLINE pragma一起使用。 In your case: 在你的情况下:

{-# NOINLINE (<|<) #-}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM