Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Consider replication definitions when refining types #6348
Original bug ID: 6348
I'm not sure whether this use case is intended to be supported, so I've marked the issue as 'feature'.
It's sometimes useful to make interfaces (cmis) visible only when building a library, excluding them from the installation. The distinction between the build-time interfaces and the installed interfaces makes it possible for the library to use type equalities that are not available to clients. Installing only a subset of the cmi files for a library seems to work pretty well, but sometimes breaks down in some cases involving type refinement and type replication. Here's a working piece of code that involves replicating a GADT definition from the module A in the module B:
$ cat a.mli
However, if we hide A's interface when compiling C, the type checker doesn't use the replicated GADT for refinement:
$ rm a.cmi
Of course, refinement starts working again if we remove the type equality from the definition of B.t:
$ sed -i 's!=.*=!=!' b.mli
It'd be useful to have refinement use whichever definitions are visible, not just the last definition in a chain of replications.
Comment author: @garrigue
You are striking a dark corner of the type system: what happens when one removes a .cmi.
This should be fixed, but this is not so easy, as one would need some kind of back mapping relating expanded types to their original form. This is what is done for the -short-paths option, but this is costly in general.
Comment author: @lpw25
Without investigating the issue fully, I suspect the problem is that during pattern unification the type is being expanded to the (now abstract)
The same issue can happen with open types, since you can have GADT constructors in scope for types which are abstract. I fixed this in my open types patch, and indeed Jeremy's examples compile without error using that patch.