External Publication
Visit Post

Can NOINLINE fail to prevent inlining?

Haskell Community [Unofficial] July 1, 2026
Source

brandonchinn178:

If NOINLINE intentionally doesnt prevent inlining with regard to worker/wrapper, then there’s a semantic difference (not a bug) where NOINLINE might inline an unsafePerformIO CAF but OPAQUE doesnt.

No, the wrapper getting inlined only means that unsafePerformIO can get inlined if unsafePerformIO ends up in the wrapper, not the worker. And it doesn’t, since the wrapper only handles coercions and unboxings, and should not do any actual computation.

Over at your GHC proposal thread you mentioned

My immediate motivation for this thread is me wanting to use top-level unsafePerformIO + NOINLINE at work, and hearing concerns about “we’ve seen it inlined in the past, so we don’t trust it”.

I was going to ask: do we have actual evidence for this? Cargo-culting is not particularly helpful. But then I read the documentation for unsafePerformIO, which, in addition to requiring you add NOINLINE and set -fno-cse -fno-full-laziness, also says:

Note that these precautions are necessary for GHC, but may not be sufficient , and other compilers may require different precautions

(emphasis mine). Since we’re entering GHC-specific land with unsafe functions anyway the latter part of the sentence is not so surprising, but the documentation clearly states that GHC will not guarantee the expected behaviour for this pattern even if you do all of these things!

This surprised me a lot, since I have multiple uses of this pattern in various places. Can a GHC expert chime in what this remark refers to? If it is the state hack, perhaps -fno-state-hack should be added to the unsafePerformIO documentation too!

Discussion in the ATmosphere

Loading comments...