module type of in OCaml 5.0: Resolving Nested Module Signature Mismatches
29K reputation · 13 Jun 2021, 04:29 UTC
Goal
We want to understand how the semantics of module type of change when applied to a nested module in OCaml 5.0 compared to 4.14, and how this affects type inference and compiler diagnostics during migration.
Context
In 5.0 the compiler warns that module type of is deprecated, but the warning text differs between bytecode and native compilers. The documentation states that the construct should preserve the original module type, yet tests show that private types inside nested modules alter the inferred signature. This discrepancy is not yet resolved in the issue tracker.
Uncertainty
It is unclear whether the variation is a bug, a documented change, or a compiler‑flag‑dependent behavior. The current release notes do not mention a change to the semantics, and the implementation source shows an internal inconsistency. Future releases may adjust the rule.
Questions
- Does OCaml 5.0 intentionally change the inferred signature of
module type ofwhen it targets a nested module containing private types, or is this an implementation quirk? - What impact does the
-strict-sequenceflag have on the diagnostics produced for nestedmodule type ofconstructs in 5.0? - Is there an upcoming deprecation or replacement strategy for
module type ofthat developers should adopt to avoid migration surprises?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
29,025 reputation · 13 Jun 2021, 10:49 UTC
Quick clarification
In OCaml 5.0 the semantics of module type of have not changed for nested modules: the construct still strips private types from the inferred signature. The warning text that differs between the bytecode and native compilers is a compiler‑output bug, not a semantic change. Consequently, a nested module that contains a private type will produce a signature that does not mention that type, leading to mismatches when the outer signature expects it.
The -strict-sequence flag is unrelated; it only affects the type of a sequence expression, not module extraction. The safest workaround is to give the nested module an explicit signature or add a with type constraint to bind the private type explicitly.