Open conal opened 8 years ago
FWIW, I believe this is a GHC issue, not a HERMIT one. Haddock also has trouble locating the Num
and Show
instances for Float
/Double
for some inconspicuous reason. (Here's the Haddock ticket.)
Thanks for the tip, @RyanGlScott. This is the first time I've tried examples with Double
or Float
in a HERMIT-based plugin since upgrading from GHC 7.8.2 to 7.10.3.
Thank makes sense, since the issue probably arose somewhere between 7.8 and 7.10, as GHC has no trouble locating the Num
/Show
instances for Float
in these GHC 7.8-compiled docs for Prelude
.
Unfortunately, I never did get a follow-up on that Haddock ticket almost a year later. It might be worth filing as a proper GHC bug now that we've found code outside of Haddock that breaks because of it.
Is it because the Num/Show instances are orphan instances for Float/Double? Have you tried to look up any other orphan instances?
@xich Sounds like a good guess to me. No, I've not tried to find any other orphans.
I'm not sure the fact that they are orphans should mean it is impossible... the typechecker must have some way to deal with orphans, I'm just not sure what it is. It is possible we just aren't initializing the typechecker state from the modguts correctly in HERMIT/GHC/Typechecker.hs.
Figuring out how the typechecker tracks orphans and looking at that file might reveal a fix.
Good idea! I'm poking around now in the typechecker to see what I can figure out.
Indeed, it doesn't appear to be the case that all orphan instances are affected. Two other modules in base
(GHC.Base
and GHC.Real
) export widely used orphan instances like Monoid [a]
, but they seem to show up just fine in Haddock. I'm not sure what' different about GHC.Float
...
tcg_visible_orphan_mods
seems to be key. It's set to mkModuleSet [mod]
in HERMIT.GHC.Typechecker
's initTcFromModGuts
. In GHC's TcRnDriver
module, I see a couple of more complex initializations:
tcg_visible_orphan_mods = foldl extendModuleSet
(tcg_visible_orphan_mods gbl)
(imp_orphs imports),
, tcg_visible_orphan_mods = mkModuleSet ic_visible_mods
where
; ic_visible_mods <- fmap concat . forM (ic_imports icxt) $ \i ->
case i of
IIModule n -> getOrphans n
IIDecl i -> getOrphans (unLoc (ideclName i))
Until we figure this one out, I have a workaround in the form of a newtype
wrapper around Double
.
I'm no longer using HERMIT, but I've continued to run into this problem. Finally, I think I know how to fix it. If it's still an important issue for someone else, I can help.
@conal: What would it take to fix it? Is this a HERMIT-specific fix, or could it work for the GHC codebase itself?
@RyanGlScott I don't know whether there's a fix needed to GHC. In HERMIT.GHC.Typechecker
, I think the problem is in the following:
tcg_imports = emptyImportAvails,
When I add the module GHC.Float
, I'm able to find instances/dictionaries for Num Float
etc. For HERMIT, I think you can use
tcg_imports = emptyImportAvails { imp_orphs = [ mkModule baseUnitId (mkModuleName "GHC.Float") ] },
where
import Module ( moduleName, mkModule, mkModuleName, baseUnitId )
I tested this tweak in a copy of HERMIT.GHC.Typechecker
, and it fixes the issue for me.
What I'm really doing instead is using GHC's runTcInteractive
from TcRnDriver
in place of HERMIT's initTcFromModGuts
, but first tweaking the given HscEnv
env0
to env
, defined as follows:
imports0 = ic_imports (hsc_IC env0)
orphNames = mkModuleName <$> ["GHC.Float"]
env = env0 { hsc_IC = (hsc_IC env0) { ic_imports = map IIModule orphNames ++ imports0 } }
FWIW, Haddock has solved a similar issue with this patch.
buildDictionaryT
fails to findNum
andShow
dictionaries forFloat
orDouble
as superclass constraints. (It yields unbound dictionary variables instead.) It can findEq
andRead
dictionaries forFloat
,Double
, andInt
, and it can findNum
andShow
dictionaries forInt
. TheNum
andShow
instances forFloat
andDouble
are fromGHC.Float
, while theEq
andRead
instances are fromGHC.Classes
andGHC.Read
, respectively. TheNum
andShow
instances forInt
are fromGHC.Num
andGHC.Show
, respectively. I've tried addingimport GHC.Float ()
in a module of my plugin and in the examples module given to hermit, but no luck.Any guesses about what's going wrong here (and possibly all instances from
GHC.Float
)? Any suggestions for workarounds to try?