Assert that we don't try to look up an Id too early (Occurrence is GlobalId, but binding is LocalId)
It is not always OK to look up the IdInfo of an Id in the presence of hs-boot files. An example test case is T10083: if one tries to inspect IdInfos early on in the typechecker (e.g. in the GHC.Tc.Gen namespace), one can get a Occurrence is GlobalId, but binding is LocalId Core Lint error.
@simonpj diagnoses the problem in #20200 (comment 378625):
We have:
T10083.hs-boot, which defineseqRSRT10083a.hs, which defineseqSR, whose RHS mentionseqRSRT10083.hs, which defineseqRSR, whose RHS mentionseqSR.Now when compiling T10083.hs,
- we typecheck the defn of
eqRSR- so we need the Id (and hence Type) for
eqSR- but
eqSR's unfolding mentionseqRSR, whose Id doesn't yet exist, because we havn't typechecked it.If we aggressively suck in that unfolding for
eqSR, we'll be forced to find an Id foreqRSR; since it hasn't yet been built, we'll get it from the Iface from the hs-boot file ... a GlobalId. And that is the problem.Supppose we have finished typechecking and now we force that unfolding. How come we now get the typechecked defn of the Id? Answer: see GHC.IfaceToCore.tcIfaceGlobal:
- It looks in
if_rec_types envto get an IO actionget_type_env- That in turn reads a ref-cell which contains the bindings for locally-defined Ids. (These will be LocalIds.
- Somehow we update the ref-cell after typechecking. I can't see exactly where that happens. There is a maze of twisty little passages concerning
KnotVars, and my brain exploded.- But if we read that ref-cell too early it'll be empty.
- And so
tcIfaceGlobalwill look in the Iface for the hi-boot file instead.Or something like that.
Simon recommends adding an assertion to ensure we don't accidentally look up IdInfos too early:
I think that in
tcIfaceGlobalifcur_mod=nameModule namethen we should jolly well get a hit inif_rec_types; if not, fail with an error saying you have readif_rec_typestoo early. Or... hmm.... maybe A.hs-boot has exported something that A.hs doesn't actually define... that might happen too.
This ticket tracks this task.