Ocamlc -i, ocamldep, and _[> `Foo of 'weak1 ] cause problems with dune running menhir

While updating a personal project to use dune, I started to get syntax errors in the .ml files generated by menhir. The problem occurs because dune calls menhir with the --infer-read-only option, which causes menhir to infer types by running ocamlc -i. If those types have the form _[> `Foo of 'weak1] then later calls by dune to ocamldep fail.

A more direct way to replicate the problem is to create the following file.

(* test.ml *)
let foo_only = List.filter_map (function `Foo e -> Some e | _ -> None)

and then run

ocamlc -i test.ml > test.mli; ocamldep test.mli

which fails with

File "test.mli", line 1, characters 16-18:
1 | val foo_only : _[> `Foo of '_weak1 ] list -> '_weak1 list
Error: Syntax error

In this form, a simple fix is easy to see. Eta expanding to let foo_only x = ... x produces a signature without a weak type variable.

The problem is harder to diagnose, however, in the original context. E.g., it can be reproduced by editing merlin/demos/calc/parser.mly:

 %{ let foo_only = List.filter_map (function `Foo e -> Some e | _ -> None) %}
| e = foo EOL
    { List.hd (foo_only [e]) }
| e = expr
    { `Foo e }

My question is: where is the best place to fix this problem? Could/should ocamlc -i fail or eliminate the weak type variables?

The output of the -i flag is intended to be used as a starting point before human editing.

It is not guarantee to output a syntactically valid module type. Indeed, there are instances of inferred module types that cannot be mapped to a syntactic module type. Weakly polymorphic types are one of those instances.

There is unfortunately no easy generic fix since there is currently no stable API for querying information about the typed tree.

In your specific case, it should be mostly a matter of avoiding weakly polymorphic types at the toplevel. The general advices to avoid those are:

  • no point-free style
  • annotate global mutable states

I understand. I agree that avoiding weakly polymorphic types at the toplevel bypasses the problem. I just found the resulting error to be a bit obscure. I guess menhir could possibly grep in the inferred type for _[>, although that would seem a bit of a hack. Anyway, if someone else has the same problem in the future, may they quickly find this discussion and move on to more interesting things!

Thanks for your response.