|
succ optimization bug with derived Eq and Enum: msg#00058lang.haskell.glasgow.bugs
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.
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | [ ghc-Bugs-1071030 ] internal error: update_fwd: unknown/strange object 12238336, SourceForge.net |
|---|---|
| Next by Date: | [ ghc-Bugs-1106171 ] GHCi does not find instances, SourceForge.net |
| Previous by Thread: | [ ghc-Bugs-1071030 ] internal error: update_fwd: unknown/strange object 12238336, SourceForge.net |
| Next by Thread: | [ ghc-Bugs-1106171 ] GHCi does not find instances, SourceForge.net |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |