This series of blog post aims to give a short weekly glimpse into my (Florian Angeletti) daily work on the OCaml compiler. This week, the focus is on the newly tagged OCaml 5.1 branch.

A branch for OCaml 5.1

Last week, I have mostly worked on preparing the branching of OCaml 5.1. Before creating the new branch I try to check that there are no new features that are really on the fence to be integrated and that there are no bugs that would hinder the CI process on the new branch.

For this new branch, it was the last point that was an unexpected source of delays.

Indeed, during a refactoring of the parsetree AST (Abstract syntax tree) I had introduced a bug in ocamldep that was not caught by CI tests for ocamldep itself. However, once I updated the bootstrapped compiler when cutting the new branch, the bug surfaced when compiling the dependency graph of the compiler itself.

Consequently, I had to interrupt the publication of the new branch to fix this issue in a short pull request. The fix was merged last week, and I have published the fixed OCaml 5.1 branch today.

Retrospective on my work before OCaml 5.1 feature freeze

Now that we have a branch for OCaml 5.1, the branch will only receive bug fixes until the final release in summer (probably in July?). It thus seems a good time to reflect a bit on my work in this first half of OCaml 5.1 release cycle. Beware however that new features can still be released before the first beta of OCaml 5.1.0.

Overall, I have reviewed 19 pull requests, written 9 pull requests implementing new features, and 3 pull requests implementing bug fixes.

Overall, the merged pull requests should provide an incremental but noticeable improvement to error messages which where the main theme of most the pull requests that I reviewed or authored.

Reviewing pull requests

Looking at my reviewed pull requests, I have indeed reviewed 9 pull requests improving error messages. Then with 4 reviews, the type system was another area where my work was focused.

Error messages
  • Most of the improvements for error messages made the messages more explicit by trying to present more contextual information to the user:

    1. #11530: Include kinds in kind mismatch error message. (Leonhard Markert, review by Gabriel Scherer and Florian Angeletti)

    2. #11888: Improve the error message when type variables cannot be deduced from the type parameters. (Stefan Muenzel, review by Florian Angeletti and Gabriel Scherer)

    3. #12051: Improve the error messages when type variables cannot be generalized (Stefan Muenzel, review by Florian Angeletti)

    4. #10818: Preserve integer literal formatting in type hint. (Leonhard Markert, review by Gabriel Scherer and Florian Angeletti)

  • Other pull requests improved the structure of the error messages by making a better use of highlights and locations:

    1. #11679: Improve the error message about too many arguments to a function (Jules Aguillon, review by Gabriel Scherer and Florian Angeletti)

    2. #12116: Don’t suggest to insert a semicolon when the type is not unit (Jules Aguillon, review by Florian Angeletti)

  • There were also two formatting improvements:

    1. #11646: Add colors to error message hints. (Christiana Anthony, review by Florian Angeletti)

    2. #12024: insert a blank line between separate compiler messages (Gabriel Scherer, review by Florian Angeletti, report by David Wong)

  • Finally, there was one improvement on the ability to cross-reference the reference manual within error or warning messages:

    1. #12125: Add Misc.print_see_manual and modify [@manual_ref] to accept lists for simpler printing of manual references (Stefan Muenzel, review by Florian Angeletti)
Type system

On the type system side, I have most reviewed internal refactoring changes that are probably not that user visible (even when they remove some bugs).

  1. #6941, #11187: prohibit using classes through recursive modules inheriting or including a class belonging to a mutually-recursive module would previous behave incorrectly, and now results in a clean error. (Leo White, review by Gabriel Scherer and Florian Angeletti)

  2. #11912: Refactoring handling of scoped type variables (Richard Eisenberg, review by Gabriel Scherer and Florian Angeletti)

  3. #11569: Remove hash type encoding (Hyunggyu Jang, review by Gabriel Scherer and Florian Angeletti)

  4. #11984: Add dedicated syntax for generative functor application. Previously, OCaml did not disinguish between F () and F (struct end), even though the latter looks applicative. Instead, the decision between generative and applicative functor application was made based on the type of F. With this patch, we now distinguish these two application forms; writing F (struct end) for a generative functor leads to new warning 73. (Frederic Bour and Richard Eisenberg, review by Florian Angeletti)

Internal refactoring
  1. #11745: Debugger and toplevels: embed printer types rather than reading their representations from topdirs.cmi at runtime]. (Sébastien Hinderer, review by Florian Angeletti, Nicolás Ojeda Bär and Gabriel Scherer)
CLI interface
  1. #11653: Add the -no-absname option to ocamlc, ocamlopt and ocamldep. (Abiola Abdulsalam, review by Sébastien Hinderer and Florian Angeletti)

  2. #11696: Add the -no-g option to ocamlc and ocamlopt. (Abiola Abdulsalam, review by Sébastien Hinderer, Nicolás Ojeda Bär and Florian Angeletti)

Standard library
  1. #11128: Add In_channel.isatty, Out_channel.isatty. (Nicolás Ojeda Bär, review by Gabriel Scherer and Florian Angeletti)

  2. #12103, #12104: fix a concurrency memory-safety bug in Buffer (Gabriel Scherer, review by Florian Angeletti, report by Samuel Hym)

  1. #11676: Fix missing since annotation in the Sys and Format modules (Github user Bukolab99, review by Florian Angeletti)

Authored feature pull requests

As it is was the case before the OCaml 5.0 multicore freeze, my personal contribution was focused on error messages during the last month with 5 pull requests on this thematic for a total of 9 pull requests.

Error messages
  • In particular, the new release will hopefully see an improvement in the way that types are printed in error messages, both when identifiers collide

    1. #11286, #11515: disambiguate identifiers by using how recently they have been bound in the current environment (Florian Angeletti, review by Gabriel Scherer)

    2. #11910: Simplify naming convention for shadowed or ephemeral identifiers in error messages (eg: Illegal shadowing of included type t/2 by t) (Florian Angeletti, review by Jules Aguillon)

  • or when a weak row type variable rears its head:

    1. #12107: use aliases to mark weak row variables: _[< ... ], < _..>, _#ct are now rendered as [< ...] as '_weak1 , < .. > as '_weak1, and #ct as '_weak1. (Florian Angeletti, suggestion by Stefan Muenzel, review by Gabriel Scherer)
  • I also implemented or participated to two relatively small improvement on warnings:

    1. #11235, #11864: usage warnings for constructors and fields can now be disabled on field-by-field or constructor-by-constructor basis (Florian Angeletti, review by Gabriel Scherer)

    2. #10931: Improve warning 14 (illegal backslash) with a better explanation of the causes and how to fix it. (David Allsopp, Florian Angeletti, Lucas De Angelis, Gabriel Scherer, review by Nicolás Ojeda Bär, Florian Angeletti, David Allsopp and Gabriel Scherer)

OCamldoc maintenance

I still keep maintaining ocamldoc in a minimal working state, but I hope to switch to odoc for the manual in time for the release of OCaml 5.1 .

  1. #11889, #11978: ocamldoc: handle injectivity annotations and wildcards in type parameters. (Florian Angeletti, report by Wiktor Kuchta, review by Jules Aguillon)

  2. #12165: ocamldoc, use standard doctype to avoid quirk mode. (Florian Angeletti, review by Gabriel Scherer)

  1. #12028: Update format documentation to make it clearer that pp_print_newline flushes its newline (Florian Angeletti, review by Gabriel Scherer)
Internal refactoring
  1. #12119: mirror type constraints on value binding in the parsetree: the constraint typ in let pat : typ = exp is now directly stored in the value binding node in the parsetree. (Florian Angeletti, review by Richard Eisenberg)

Authored bug fixes:

  • Least but not last, I have fixed two of my mistakes in previous pull requests

    1. #11450, #12018: Fix erroneous functor error messages that were too eager to cast struct end functor arguments as unit modules in F(struct end). (Florian Angetti, review by Gabriel Scherer)

    2. #12061, #12063: don’t add inconsistent equalities when computing high-level error messages for functor applications and inclusions. (Florian Angeletti, review by Gabriel Scherer)

  • and fixed what was maybe one of the fastest bug to trigger in OCaml history

    1. #11824: Fix a crash when calling ocamlrun -b (Florian Angeletti, review by Sébastien Hinderer)

since the bug did not require any code source to trigger.