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 IdInfo
s 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 defineseqRSR
T10083a.hs
, which defineseqSR
, whose RHS mentionseqRSR
T10083.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 env
to 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
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 IdInfo
s too early:
I think that in
tcIfaceGlobal
ifcur_mod
=nameModule name
then we should jolly well get a hit inif_rec_types
; if not, fail with an error saying you have readif_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.