Opened 3 years ago

Closed 3 years ago

#10666 closed task (invalid)

Distinguish between semantic module / identity module in TcGblEnv, ModIface and ModGuts

Reported by: ezyang Owned by: ezyang
Priority: normal Milestone:
Component: Package system Version: 7.10.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


When we write a signature like

package p where
  signature H where
    data T

and compile it to an interface file, there are two ways we might say what the Module of this interface is:

  1. The identity module uniquely identifies an interface file, and is used for dependency analysis and tracking. In the example above, the identity module is p(H -> HOLE:H):H.
  1. The semantic module tells us what the Names of the entities defined in the module are supposed to be; e.g., it's used for generating new names when type-checking hs files or interfaces. In the example above, the semantic module is hole:H, since this signature exports one entity named hole:H.T. The semantic module can always be derived from the identity module.

For normal Haskell modules, the semantic and identity module coincide. However, for signatures they differ: we may have many signatures for the same module; they all share their semantic module but have differing identity modules.

By in large, when GHC manipulates Module directly it is interested in the identity module. However, when a Module is used with reference to a Name (primarily nameIsLocalOrFrom), we want to use the SEMANTIC module. (Another example: when we filter out the type environment before making a ModIface, need to filter against the semantic module.)

I tried a few ways of factoring GHC's code so we'd be less likely to confuse these two Modules when typechecking signatures: the big problem is if you're adding a getModule call to TcRn, you're probably not going to think too hard whether or not you actually wanted the semantic module or the identity module. But if you pick the wrong thing that will break all sorts of things for signatures.

Here are some things we could do:

  1. My initial attempt was to change tcg_mod, mg_module and mi_module to record a new data type TopModule which recorded both the semantic and identity module, with getModule in TcRn continuing to return a semantic module, but mi_module returning an identity module. However, the resulting patch was pretty ugly and it's not altogether clear that getModule returning the semantic module is always correct.
  1. My other idea is to say that these entries always are IDENTITY modules (this will result on fail fast behavior for signatures if you get it wrong), and then rewrite nameIsLocalOrFrom, externaliseAndTidyId, initIfaceTcRn, newGlobalBinder so that they always do the right thing (i.e. use the semantic module); thus, the only time you can get it wrong is if you're creating some new functionality that's not these functions that needs to use semantic modules.

Pretty delicate.

Change History (2)

comment:1 Changed 3 years ago by simonpj

Can you give some examples (starting with the Backpack file I suppose) of when the behaviour of the two differs. In particular, I don't know what "dependency analysis and tracking" means. What shows up in interface files, for example?

comment:2 Changed 3 years ago by ezyang

Resolution: invalid
Status: newclosed

There's some examples on the wiki page: wiki:Backpack

But I've figured out how to do this non-invasively, so this will just be part of the Backpack omnibus patch, when it lands.

Note: See TracTickets for help on using tickets.