diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2021-06-19 21:09:47 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-07-02 00:27:04 -0400 |
commit | 6ac9ea86c339489e692730e849a88e86da730837 (patch) | |
tree | e73e63a68e7b722390a105b363c2f20c35a99290 /compiler | |
parent | a3c451beefadc8018c1987f8f66c760671bb66ff (diff) | |
download | haskell-6ac9ea86c339489e692730e849a88e86da730837.tar.gz |
One-shot changes (#20008)
I discovered that GHC.Core.Unify.bindTv was getting arity 2,
rather than 3, in one of my builds. In HEAD it does get the right
arity, but only because CallArity (just) manages to spot it. In my
situation it (just) failed to discover this.
Best to make it robust, which this patch does. See
Note [INLINE pragmas and (>>)] in GHC.Utils.Monad.
There a bunch of other modules that probably should have the same
treatment:
GHC.CmmToAsm.Reg.Linear.State
GHC.Tc.Solver.Monad
GHC.Tc.Solver.Rewrite
GHC.Utils.Monad.State.Lazy
GHC.Utils.Monad.State.Strict
but doing so is not part of this patch
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/GHC/Core/Unify.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Utils/Monad.hs | 19 |
2 files changed, 21 insertions, 0 deletions
diff --git a/compiler/GHC/Core/Unify.hs b/compiler/GHC/Core/Unify.hs index fdf4d05068..bd54ecee39 100644 --- a/compiler/GHC/Core/Unify.hs +++ b/compiler/GHC/Core/Unify.hs @@ -1393,6 +1393,8 @@ instance Applicative UM where (<*>) = ap instance Monad UM where + {-# INLINE (>>=) #-} + -- See Note [INLINE pragmas and (>>)] in GHC.Utils.Monad m >>= k = UM (\state -> do { (state', v) <- unUM m state ; unUM (k v) state' }) diff --git a/compiler/GHC/Utils/Monad.hs b/compiler/GHC/Utils/Monad.hs index a65947e59e..056651bdde 100644 --- a/compiler/GHC/Utils/Monad.hs +++ b/compiler/GHC/Utils/Monad.hs @@ -355,6 +355,25 @@ function might be required. For example in FCode we use: where FCode m = FCode' $ oneShot (\cgInfoDown -> oneShot (\state ->m cgInfoDown state)) +INLINE pragmas and (>>) +~~~~~~~~~~~~~~~~~~~~~~~ +A nasty gotcha is described in #20008. In brief, be careful if you get (>>) via +its default method: + + instance Applicative M where + pure a = MkM (\s -> (s, a)) + (<*>) = ap + + instance Monad UM where + {-# INLINE (>>=) #-} + m >>= k = MkM (\s -> blah) + +Here we define (>>), via its default method, in terms of (>>=). If you do this, +be sure to put an INLINE pragma on (>>=), as above. That tells it to inline +(>>=) in the RHS of (>>), even when it is applied to only two arguments, which +in turn conveys the one-shot info from (>>=) to (>>). Lacking the INLINE, GHC +may eta-expand (>>), and with a non-one-shot lambda. #20008 has more discussion. + Derived instances ~~~~~~~~~~~~~~~~~ One caveat of both approaches is that derived instances don't use the smart |