Original bug ID: 7152 Reporter: bobot Assigned to:@garrigue Status: closed (set by @xavierleroy on 2017-09-24T15:33:20Z) Resolution: fixed Priority: normal Severity: major Target version: 4.03.0+dev / +beta1 Fixed in version: 4.03.0+dev / +beta1 Category: typing Related to:#6752#7313 Monitored by:@hcarty
The file variable.ml compile with 4.02.3 but not with 4.02.3.
ocamlc -o /tmp/dumb -c variable.ml
File "variable.ml", line 5, characters 6-667:
Error: Signature mismatch:
Values do not match:
val add_dec : dec:Data.t -> unit
is not included in
val add_dec : dec:make_dec -> unit
File "src/variable.ml", line 3, characters 2-35: Expected declaration
File "src/variable.ml", line 63, characters 4-11: Actual declaration
I'm not able to minimize it more (except in fact the label can be removed...).
I'm not 100% clear of why it worked before, because non-generalized variables inside submodules have always been strange.
I think this fix does the right thing, as it lowers their levels when one adds a module to the environment, putting them at most at the binding level of this module, so that all references inside this module will be expanded to an external path.
You should instantiate '_a by either Data.t or Dem.Data.t, depending on whether you are looking at the type from inside Dem or outside Dem. Since the variable is shared between the two, actually both are invalid. So the solution to #7152 solved this by forcing the expansion, and instantiating by make_dec, which is correct. But this also means that you cannot instantiate such a non-generalizable type variable by an internal abstract type (except when you are coercing before adding the module definition to the environment, since the locking is only done afterward).
I understand that all this kind of worked until 4.02.3, but my feeling is that this was purely by chance. Something like lazyness allowing one to instantiate with an internal reference before the exporting substitution occurs, so that the internal-external conflict is avoided.
The cause this started to fail is probably a change in evaluation order somewhere, but I'm not sure it's worth tracking it down, because it is bound to be fragile.
Just to give you an idea of how the original approach was fragile, it was sufficient to add the line
let _ =Dem.key
just after the definition of Dem above to break it in all versions up to 4.02.
It worked in 4.03, but only by making things more laxist, and there were other problems.
The more restrictive approch implemented here fixes it once and for all, but introduces some regressions, as seen in #7313.