Brian

Thanks for reporting this grievous bug.  It's now fixed and there's a
test in the regression suite for it (cg055).   Particular thanks for
boiling it down to such a small case.

Simon

| -----Original Message-----
| From: [EMAIL PROTECTED]
[mailto:glasgow-haskell-bugs-
| [EMAIL PROTECTED] On Behalf Of Brian Alliet
| Sent: 20 January 2005 13:13
| To: glasgow-haskell-bugs@haskell.org
| Subject: succ optimization bug with derived Eq and Enum
| 
| GHC 6.2.2 (and a few older 6.2.x versions I tried) seems to improperly
| optimize the expression "succ x == y" when using the derived Eq and
Enum
| instances. Using the data declaration below "isFive Five" will be
False.
| 
| data Digit = Zero | One | Two | Three | Four | Five
|            | Six | Seven | Eight deriving (Eq,Enum)
| isFive x = succ x == Six
| 
| This only happens when using the derived Eq and Enum. If either of
| them are replaced with a hand written instance everything works fine.
It
| also has something to do with the number constructors the datatype
has. If
| there are less than 9 constructors everything works fine. Finally, the
bug
| only shows up when the -O flag is used.
| 
| Plenty more details (including a self contained test case) are below.
| 
| -Brian
| 
| transam:~/tmp$ cat GHCBug.lhs
| \begin{code}
| import System (getArgs)
| 
| -- NOTE: When if you remove Eight (or any other constructor)
everything works
| -- Having at least 9 constructors has something to do with the bug
| data Digit = Zero | One | Two | Three | Four | Five | Six | Seven |
Eight
|     deriving (Eq,Enum)
| 
| instance Show Digit where
|     show Five = "Five"
|     show Six = "Six"
|     show _ = undefined
| 
| -- Use either of these instances (instead of derived) and everything
works
| {-instance Enum Digit where
|     fromEnum Five = 5
|     fromEnum _ = undefined
|     toEnum 6 = Six
|     toEnum _ = undefined-}
| 
| {-instance Eq Digit where
|     Five == Five = True
|     Six == Six = True
|     _ == _ = undefined-}
| 
| isFive :: Digit -> Bool
| isFive a = succ a == Six
| 
| main :: IO()
| main = do
|     putStrLn ("======")
|     -- These next two lines are just here to keep ghc from optimizing
away stuff
|     args <- getArgs
|     let x = if length args == -1 then undefined else Five
|     putStrLn ("x: " ++ show x)
|     let y = succ x
|     putStrLn ("let y = succ x")
|     putStrLn ("y: " ++ show y)
|     putStrLn ("y == Six: " ++ show (y == Six))
|     putStrLn ("succ x == Six: " ++ show (succ x == Six))
|     putStrLn ("isFive x: " ++ show (isFive x))
| \end{code}
| transam:~/tmp$ ghc -no-recomp -o GHCBug GHCBug.lhs && ./GHCBug
| ======
| x: Five
| let y = succ x
| y: Six
| y == Six: True
| succ x == Six: True
| isFive x: True
| transam:~/tmp$  ghc -O -no-recomp -o GHCBug GHCBug.lhs && ./GHCBug
| ======
| x: Five
| let y = succ x
| y: Six
| y == Six: True
| succ x == Six: False
| isFive x: False
| transam:~/tmp$ ghci GHCBug.lhs
|    ___         ___ _
|   / _ \ /\  /\/ __(_)
|  / /_\// /_/ / /  | |      GHC Interactive, version 6.2.2, for Haskell
98.
| / /_\\/ __  / /___| |      http://www.haskell.org/ghc/
| \____/\/ /_/\____/|_|      Type :? for help.
| 
| Loading package base ... linking ... done.
| Skipping  Main             ( GHCBug.lhs, GHCBug.o )
| Ok, modules loaded: Main.
| Prelude Main> isFive Five
| Loading package haskell98 ... linking ... done.
| False
| Prelude Main> :q
| Leaving GHCi.
| _______________________________________________
| Glasgow-haskell-bugs mailing list
| Glasgow-haskell-bugs@haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to