Skip to content

String inlining is inconsistent

I have the following code:

A.hs:

module A where

foo :: String
{-# INLINE foo #-}
foo = "foo"

B.hs:

import A

main = if foo == "foo" then return () else putStrLn "Wrong"

Compiling this with -O2 shows the if-statement has not been eliminated ("Wrong" is still part of the output with -ddump-simpl).

However, if I rewrite the code to:

A.hs:

module A where

foo :: () -> String
{-# INLINE foo #-}
foo () = "foo"

B.hs:

import A

main = if foo () == "foo" then return () else putStrLn "Wrong"

Then the if-statement disappears and the generated Core has no string literals left.

Even when the literal can not be eliminated from B it seems GHC is fine with duplicating it accross two modules if it occurs somewhere inside a function. But once I make it a top-level expression of type String, inlining it does not happen. I can not think of how this could be working as intended.

(The case where A.foo is "" seems to work differently, but also does not get optimized away.)

(This happened to me when rewriting some code that previously used CPP for conditional compilation to using if System.Info.os == "darwin" then ... else ... and expecting the other OS cases to get optimized away.)

Trac metadata
Trac field Value
Version 7.10.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information