Skip to content

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 defines eqRSR
  • T10083a.hs, which defines eqSR, whose RHS mentions eqRSR
  • T10083.hs, which defines eqRSR, whose RHS mentions eqSR.

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 mentions eqRSR, 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 for eqRSR; 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 env to get an IO action get_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 tcIfaceGlobal will 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 tcIfaceGlobal if cur_mod = nameModule name then we should jolly well get a hit in if_rec_types; if not, fail with an error saying you have read if_rec_types too 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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information