PUBLIC
What I’ve found out is that this was because I was registering the ModDetails as it comes out of tidyProgram. If instead I recreate the ModDetails form the ModIface via initModDetails,
the class op rules show up properly and everything works as expected.
Is this documented somewhere, that the ModDetails from tidyProgram is not good for all purposes? Should its type be different, then, from an all-purpose ModDetails?
From: ghc-devs <ghc-devs-bounces@haskell.org>
On Behalf Of Erdi, Gergo via ghc-devs
Sent: Monday, October 17, 2022 6:33 PM
To: ghc-devs@haskell.org
Subject: [External] Missing class op rules when using API
Hi,
I'm trying to compile the following two modules:
```
{-# LANGUAGE NoImplicitPrelude #-}
module MiniMonad where
class Functor f where
fmap :: (a -> b) -> f a -> f b
class (Functor f) => Applicative f where
pure :: a -> f a
class (Applicative m) => Monad m where
return :: a -> m a
return = pure
(>>=) :: m a -> (a -> m b) -> m b
infixl 1 >>=
```
```
{-# LANGUAGE NoImplicitPrelude #-}
module SpecMain where
import MiniMonad
data Identity a = MkIdentity a
instance Functor Identity where
fmap f (MkIdentity x) = MkIdentity (f x)
instance Applicative Identity where
pure x = MkIdentity x
instance Monad Identity where
run :: Identity a -> a
run (MkIdentity x) = x
foo :: ()
foo = run (return ())
```
If I compile these from the CLI, I see three rules firing:
```
./_build/stage1/bin/ghc -debug -fforce-recomp -dno-typeable-binds input/SpecMain.hs -iinput -O0 -ddump-rule-rewrites -dsuppress-all
```
```
[1 of 2] Compiling MiniMonad ( input/MiniMonad.hs, input/MiniMonad.o )
[2 of 2] Compiling SpecMain ( input/SpecMain.hs, input/SpecMain.o )
tc_iface_decl/2 Monad
input/SpecMain.hs:14:10: warning: [-Wmissing-methods]
• No explicit implementation for
‘>>=’
• In the instance declaration for ‘Monad Identity’
|
14 | instance Monad Identity where
| ^^^^^^^^^^^^^^
Rule fired
Rule: Class op $p1Monad
Module: (BUILTIN)
Before: MiniMonad.$p1Monad
TyArg SpecMain.Identity ValArg SpecMain.$fMonadIdentity
After: SpecMain.$fApplicativeIdentity
Cont: StrictArg MiniMonad.pure
ApplyToTy a_avS
Stop[RhsCtxt(Recursive)] a_avS -> SpecMain.Identity a_avS
Rule fired
Rule: Class op pure
Module: (BUILTIN)
Before: MiniMonad.pure
TyArg SpecMain.Identity ValArg SpecMain.$fApplicativeIdentity
After: $cpure_aw8
Cont: ApplyToTy a_avS
Stop[RhsCtxt(Recursive)] a_avS -> SpecMain.Identity a_avS
Rule fired
Rule: Class op return
Module: (BUILTIN)
Before: MiniMonad.return
TyArg SpecMain.Identity ValArg SpecMain.$fMonadIdentity
After: $creturn_avP
Cont: ApplyToTy ()
ApplyToVal nodup hole () -> SpecMain.Identity () GHC.Tuple.Prim.()
Select nodup wild_X1
Stop[RhsCtxt(NonRecursive)] ()
```
However, if I try this via the API (see attached `main.hs`), then only `Class op return` fires:
```
Processing module MiniMonad
Processing module SpecMain
input/SpecMain.hs:14:10: warning: [-Wmissing-methods]
• No explicit implementation for
‘>>=’
• In the instance declaration for ‘Monad Identity’
|
14 | instance Monad Identity where
| ^^^^^^^^^^^^^^
Rule fired
Rule: Class op return
Module: (BUILTIN)
Before: MiniMonad.return
TyArg SpecMain.Identity ValArg SpecMain.$fMonadIdentity
After: $creturn_aqm
Cont: ApplyToTy ()
ApplyToVal nodup hole () -> SpecMain.Identity () GHC.Tuple.Prim.()
Select nodup wild_X1
Stop[RhsCtxt(NonRecursive)] ()
All done.
```
This of course leads to much worse code further downstream (and is catastrophic for my use case where I rely on extensive specialisation).
Why is that? What is missing from my `main.hs` that only one of the three method rules is correctly used when compiling the second module?
Thanks,
Gergo