Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buildDictionaryT fails to find Num and Show dictionaries for Float or Double as superclass constraints. #173

Open
conal opened this issue Feb 18, 2016 · 14 comments

Comments

@conal
Copy link
Contributor

conal commented Feb 18, 2016

buildDictionaryT fails to find Num and Show dictionaries for Float or Double as superclass constraints. (It yields unbound dictionary variables instead.) It can find Eq and Read dictionaries for Float, Double, and Int, and it can find Num and Show dictionaries for Int. The Num and Show instances for Float and Double are from GHC.Float, while the Eq and Read instances are from GHC.Classes and GHC.Read, respectively. The Num and Show instances for Int are from GHC.Num and GHC.Show, respectively. I've tried adding import 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?

@RyanGlScott
Copy link
Member

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.)

@conal
Copy link
Contributor Author

conal commented Feb 18, 2016

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.

@RyanGlScott
Copy link
Member

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.

@xich
Copy link
Member

xich commented Feb 18, 2016

Is it because the Num/Show instances are orphan instances for Float/Double? Have you tried to look up any other orphan instances?

@conal
Copy link
Contributor Author

conal commented Feb 18, 2016

@xich Sounds like a good guess to me. No, I've not tried to find any other orphans.

@xich
Copy link
Member

xich commented Feb 18, 2016

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.

@conal
Copy link
Contributor Author

conal commented Feb 18, 2016

Good idea! I'm poking around now in the typechecker to see what I can figure out.

@RyanGlScott
Copy link
Member

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...

@conal
Copy link
Contributor Author

conal commented Feb 18, 2016

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))

conal added a commit to conal/circat that referenced this issue Feb 18, 2016
@conal
Copy link
Contributor Author

conal commented Feb 18, 2016

Until we figure this one out, I have a workaround in the form of a newtype wrapper around Double.

@conal
Copy link
Contributor Author

conal commented Dec 26, 2016

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.

@RyanGlScott
Copy link
Member

@conal: What would it take to fix it? Is this a HERMIT-specific fix, or could it work for the GHC codebase itself?

@conal
Copy link
Contributor Author

conal commented Dec 27, 2016

@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 } }

@RyanGlScott
Copy link
Member

FWIW, Haddock has solved a similar issue with this patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants