GHC (with -O, as always) tries to inline (or “unfold”) functions/values that are “small enough,” [...]
The major effect of an INLINE pragma is to declare a function’s “cost” to be very low. The normal unfolding machinery will then be very keen to inline it. [...]
I take this to mean that without optimizations enabled, even {-# INLINE ... #-} functions / values will not be inlined, since the "normal unfolding machinery" will not even be run to notice the function's cost has been reduced.
Is that correct?
The reason this happens is that
-O0still invokes a single pass of the "simplifier", which is the optimization pass responsible for, among other things, inlining.You can't prevent the simplifier from being called, but you can set the number of simplifier iterations to zero, which should cause it to bail out before doing anything:
For your
handleThingexample, this prevents the inlining you've observed.The inlining that occurs with
-O0is limited to what can be accomplished by inlining fully saturated calls with no eta expansion/reduction. This means that your example:will inline, but the variation:
won't, since the call to
handleThinginmainis no longer fully saturated.On the other hand, this will inline both
numberandhandleThing:into
main, resulting in:Here, "inlining"
numberinvolves the de-optimization of giving it an extra name and using that.