Float-in bug
Consider
let m = e
foo = \(s:State) (x:Int). body
in ...(foo s x)...
Then loatIn.noFloatIntoRhs
will say False
, because the top-level lambda is oneshot
But the attempt to float into the lambda-group will fail, leaving
foo = let m = e in \s x. body
That changes foo’s arity, which is bad.
Moreover, m might have been marked “demanded” in the original program, by the clever strictness analyser. Then the Simplifier will not float the m-binding back out of ‘foo’, because it thinks that might make it lazier.
So then the Simplifier leaves the m-binding in foo’s RHS, and then eta-expands it, giving
foo = \s. let m = e in \x. body
which is very bad:
*** Core Lint errors : in result of Simplifier ***
{-# LINE 11 "Float.hs #-}: Warning:
[RHS of f_snv :: GHC.Prim.State# GHC.Prim.RealWorld
-> GHC.Types.Int
-> (# GHC.Types.Int, GHC.Prim.State# GHC.Prim.RealWorld #)]
Demand type has 2 arguments, rhs has 1 arguments, f_snv
Binder's strictness signature: DmdType LL
*** Offending Program ***
It's hard to trigger this bug but Geoff managed to, and this code does it:
{-# LANGUAGE MagicHash, UnboxedTuples #-}
module Float where
import GHC.Prim
foo vs
= let w = if length (reverse vs) > 10 then Just (length vs) else Nothing
f :: State# RealWorld -> Int -> (# Int, State# RealWorld #)
f s x | Just 0 <- w = case f s (x+1) of
(# r, s' #) -> (# r, s' #)
| otherwise = (# x, s #)
in f realWorld# 1
Trac metadata
Trac field | Value |
---|---|
Version | 7.4.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |