GeezerVison is showing ocaml.org — OCaml Changelog
Official stable release announcements and updates from the OCaml compiler,
OCaml infrastructure and the OCaml Platform Tools.
CHANGES:
Fixed
-
Fix crashes when expanding module artifact pforms (%{cmi:...} etc.) with
(include_subdirs qualified). Qualified modules can now be referenced by
dotted logical paths such as %{cmi:Sub_a.Foo}.
(#14498, #16214, fixes #14496, @Alizter, @anmonteiro)
-
dune show targets now accepts build-only directories such as
_build/default/.simple.objs. (#14664, fixes #13782, @Alizter)
-
Reword the error raised when %{target} is used in a rule that omits the
(target ...) (or (targets ...)) field, so it points at the missing
field instead of mentioning "inferred rules". (#14668, fixes #12439,
@Alizter)
-
Fix watch mode on Windows by creating the file-watcher sync directory before
using it, avoiding open(_build/.sync\0): No such file or directory when an
RPC client requests a build. (#14678, fixes #14632, @rgrinberg)
-
Add file watcher trace events for the Mac and Windows backends (#14722, @rgrinberg)
-
Fix decoding coalesced MacOS file notification events. (#14725, @rgrinberg)
-
Handle directory invalidations correctly in watch mode on MacOS (#14756, @rgrinberg)
-
Update ctime when restoring from the shared cache in copy mode. This prevents
the trimmer from deleting the file. (#14777, @rgrinberg)
-
Allow the use of all the available variables in the (enabled_if) field in
(executable ...) and (install ...) stanzas, similar to other stanzas like
(library ...). (#14860, fixes #14789, @punchagan)
-
Linux: dune will now wait for the process group to be dead after the group
leader is dead. This tightens dune's policy for what constitutes
a successful action. Actions for which dune cannot be clean up the process
group will now fail. (@rgrinberg, #14868)
-
Fix caching of package sources with symlinks by resolving symlinks after
fetching the sources, similar to the directory symlinks resolution introduced
in #13792 (#14871, fixes #14509, @punchagan)
-
Fixed wrong suggestion for duplicate entries in conflicts field (#14956,
fixes #14903, @Leonidas-from-XIV)
-
Fix building Dune on Solaris/illumos by handling its wait4 semantics
and retrying interrupted reads when spawning processes. (#14980, fixes #14182,
@jperkin)
-
Fix dune-rpc-lwt clients so disconnecting shuts down socket output
without invalidating pending input reads, avoiding EBADF errors. (#14983,
fixes #7624, @rgrinberg)
-
Dune now restores dependency cutoffs concurrently when they were originally
computed in parallel, instead of recomputing them one at a time. The
cutoffs_that_reduce_concurrency_in_watch_mode setting, which existed to
avoid this serialisation, is no longer needed and has been removed.
(#15012, @snowleopard)
-
Validate project module names before creating the project directory in
dune init project, so aborted initializations no longer leave empty
directories behind. (#15014, fixes #9963, @rgrinberg)
-
Fix cram test output sanitization when the project path contains a space.
Absolute paths are now rewritten to $TESTCASE_ROOT even when the path
contains spaces, and lines with multiple paths have every path sanitized.
(#15017, fixes #14943, @yussypu)
-
Improve the error message for private libraries that cannot be dependencies of
public libraries by mentioning the (package ...) field as an alternative to
giving the private library a public name (#15070, fixes #10230, @rgrinberg).
-
Clarify the module conflict error shown when a module is used in multiple
stanzas. The message now explains implicit module ownership and lists all
relevant stanza kinds (#15072, fixes #6598, @rgrinberg).
-
Emit relative artifact references in installed dune-package files when using
an absolute external DUNE_BUILD_DIR, avoiding build-directory-dependent
archive and module paths (#15077, fixes #11774, @rgrinberg).
-
Simplify away (when false _) expressions (encoded Nils) that previously
survived inside concat and when forms, producing cleaner generated lock
directories. (#15092, fixes #15090, @chizy7)
-
Drop (when false _) arguments from run actions in generated lock
directories instead of keeping them as no-op entries that were re-encoded as
(when false ""). (#15128, fixes #15099, @chizy7)
-
Make dune-configurator pass --personality to pkgconf only for
version 1.7.0 and later. (#15142, fixes #11536, @dra27)
-
dune utop now accepts an absolute path to a workspace directory instead of
crashing with an internal error. (#15272, fixes #15108, @chizy7)
-
Fix watch-mode status lines after source changes interrupt a build. Dune now
shows the restart status while cancelling the current build and resumes the
normal progress counter when the next build starts. (#15289, fixes #11134,
@rgrinberg)
-
Short-circuit AND and OR expressions in blang. This makes their evaluation
lazy by default.
(#15291, @Sudha247)
-
Fix the %{ppx:ppx1+..+ppxn} form. Previously, it was just broken
and pointed at the wrong binary (#15361, @rgrinberg)
-
Remove ppx runtime dependencies from the list of dependencies provided via
the root_module field. If such a runtime dependency is needed, it should be
written in the libraries field. (#15419, @rgrinberg)
-
Avoid rebuilding js_of_ocaml library archives on every invocation for
interface-only and empty libraries. (#15427, @anmonteiro)
-
Do not crash when ~/.config/dune is a file instead of a directory. Just
pretend it doesn't exist (#15475, fixes #15406, @rgrinberg)
-
Dune will now terminate all launched sub-processes even if it received
SIGKILL itself (#15483, @rgrinberg)
-
Account for ctime in stat based digest cache (#15495, @rgrinberg)
-
$ dune install --dry-run now checks for non empty directories as part of its
validation (#15501, @rgrinberg)
-
Fix a target-less rule attached to multiple aliases ((rule (aliases a b) ...)) leaking unrelated contributions between those aliases. Building one
alias no longer pulls in actions or dependencies that were added only to
another of the rule's aliases. (#15581, @NatKarmios)
-
Make dune pkg enabled query a running Dune RPC server, so it observes
transient server-side --pkg enabled and --pkg disabled settings without
trying to acquire the build lock (#15589, fixes #15587, @Alizter)
-
Make generated MDX executables inherit link_flags from env stanzas.
(#15614, fixes #15613, @Alizter)
-
Return Unix errors from Fs_io.read_file rather than raising them. (#15641,
@rgrinberg)
-
Correct filesystem trace metrics for file writes and directory scans.
(#15686, @rgrinberg)
-
Preserve runtime-event ring IDs in Dune traces so consumers can distinguish
interleaved event streams. (#15687, @rgrinberg)
-
BREAKING CHANGE: in dune-project, (warnings (duplicate_deps ..)) requires
a dune lang version of 3.22, instead of 3.18 (#15696, @v-gb).
-
Preserve spaces in unquoted filenames when applying Git patches instead of
truncating paths at the first space (#15781, @rgrinberg)
-
Respect enabled_if on install stanzas when adding their files and
directories to the @all alias. (#15895, fixes #15825, @aryemans)
-
Fix Melange emission with installed libraries whose .cmj and .cmi files
are stored in the melange object directory (#15949, fixes #14820,
@anmonteiro)
-
Reject package dependencies in named dependency bindings while decoding
dependency fields, including for disabled stanzas. (#15966, @rgrinberg)
-
Fix Merlin definition lookup for libraries with private modules
(#15977, fixes #4892, @anmonteiro)
-
Fix a crash when generating install rules for a Melange-only implementation
of an installed virtual library (#16033, @anmonteiro)
-
Prevent build cancellation from crashing Dune when macOS reports EPERM
while signaling a process group (#16059, fixes #16053, @rgrinberg)
-
Fix dune pkg outdated so it fails early with a clear user message if it is
run when package management is not enabled. (#16065, @shonfeder)
-
Fix watch mode builds remaining stale after the file watcher event queue
overflows (#16068, fixes #16052, @rgrinberg)
-
Reject Windows path separators in validated filename components (#16076,
@rgrinberg)
-
Preserve output following malformed ANSI escape sequences and erase-line
controls (#16116, @rgrinberg).
-
Resolve relative paths passed to dune ocaml top-module from the directory
where Dune was started, allowing use from workspace subdirectories. (#16135,
@rgrinberg)
-
Allow dune ocaml top to accept absolute directory paths inside the
workspace. (#16142, @rgrinberg)
-
Allow Dune promotion commands to accept absolute source paths inside the
workspace. (#16143, @rgrinberg)
-
Allow dune describe workspace to accept absolute directory filters inside
the workspace. (#16144, @rgrinberg)
-
Reject empty module_systems fields in melange.emit stanzas instead of
silently producing no JavaScript files (#16162, @anmonteiro)
-
Sandbox PPX lint actions starting with Dune language 3.25 so linters cannot
observe undeclared build targets. (#16176, @rgrinberg)
-
Prevent diagnostic source locations at compact-position field boundaries from
being truncated (#16180, @rgrinberg)
-
Sandbox ocaml-mdx deps when using MDX extension 0.6 so dependency
discovery cannot observe undeclared workspace inputs. (#16183, @rgrinberg)
-
Fix missing Odoc generation of OxCaml parameter implementations (#16200, @art-w)
-
Make Dune_rpc_lwt.V1.Action_plugin.read_directory_with_glob return an empty listing
for absent directories (#16207, fixes #4445, @rgrinberg)
-
Fix compiling Melange implementations of installed virtual libraries, both
with and without binary annotations, including transitive private module
dependencies (#16211, #16212, #16272, @anmonteiro)
-
Run Ctypes stub generation in a sandbox and honor its declared dependencies.
(#16223, @rgrinberg)
-
Fix @opam failing to promote a generated opam file after it is deleted
(#16234, fixes #16233, @Alizter)
-
Rebuild generated Ctypes helpers when headers from Ctypes' implicit include
directories change (#16243, @rgrinberg)
-
Collect action-provided trace events when an action fails instead of dropping
them during result validation. (#16250, @rgrinberg)
-
Report the usual program-not-found error when a dynamic-run executable is
missing instead of failing with an assertion. (#16251, @rgrinberg)
-
Prevent rules with duplicate lock declarations from deadlocking by acquiring
each lock only once. (#16252, @rgrinberg)
-
Prevent concurrent action children from closing shared redirections before
their siblings use them (#16257, @rgrinberg)
-
Resolve relative paths in forwarded build, runtest, and exec commands from
the client's directory instead of the RPC server's directory (#16267,
@rgrinberg)
-
(env (env-vars ...)) in a (context ...) stanza of dune-workspace now
takes precedence over the root env stanza, as documented. This affects
commands such as dune exec; rules already used the documented order.
(#16290, @punchagan)
-
Fix a crash when an opam filter is not a boolean (#16313, @art-w)
-
Correct module paths for generated interfaces of nested qualified module
groups. (#16322, @anmonteiro)
-
Resolve %{cmi:...}, %{cmt:...}, and %{cmti:...} against Melange
module sets when no OCaml module is selected, while preferring OCaml for
modules selected in both modes. (#16339, @anmonteiro)
-
Reject . and .. as melange.emit targets instead of raising an internal
error (#16371, @anmonteiro)
-
Validate custom toplevel names as filenames, reporting an error for empty
names and avoiding crashes for names containing paths (#16373, @anmonteiro)
-
Fix Menhir type inference with package-managed relocatable compilers on macOS
by making the compiler standard library available in the sandbox (#16374,
fixes #15642, @Alizter, @shonfeder)
-
Reject invalid Menhir merge_into names during parsing to prevent internal
errors (#16387, @anmonteiro)
-
Reject conflicting module sources in unqualified directory groups,
including generated sources, instead of silently discarding one
(#16414, @anmonteiro)
-
fix copying of directory targets on windows (#16434, @kentookura)
-
Track local module dependencies used by Menhir's type inference so generated
parsers and dependent modules build and rebuild correctly
(#16447, fixes #14450, @anmonteiro)
-
Fix Menhir type inference for qualified module group interfaces while keeping
dependency lookup in terms of logical module names (#16464, #16489, #16497,
fixes #8989, @anmonteiro)
-
Fix intermittent crashes on Windows caused by unstable file descriptor
hashing (#16476, fixes #16459, @Alizter)
-
Explain that forwarded build requests require a watch-mode Dune server instead
of reporting an internal RPC error. (#16486, fixes #16219, @Alizter)
-
(deps (package ...)) now tracks installed files of lock-built packages
and their package dependencies, rebuilding actions when they change.
(#16507, @Alizter)
-
Share Rocq plugin layout dependencies between discovery and compilation
rules, reducing repeated dependency processing in unchanged builds.
(#16622, @Alizter)
-
Support directory dependencies in hardlink sandboxes by linking their files
rather than the directories themselves (#16675, @Alizter).
-
Fix recursive copy actions rejecting symbolic links, including file links
created by symlink sandboxes (#16686, @rgrinberg).
-
Fix copy sandbox failures caused by overlapping directory and file
dependencies (#16806, fixes #16547, @Alizter)
-
Fix Menhir inference producing invalid module paths for types imported from
other modules (#16952, @anmonteiro)
Added
-
Add (dirs ...) to (include_subdirs (mode qualified) ...), allowing
qualified source directories to be renamed in the module path, including
when bootstrapping. Mappings can use variables, including reads from generated
files outside the qualified group (#13691, #16418, #16420, fixes #7605,
@anmonteiro).
-
Add opt-in action runners via --action-runner, and add
--sandbox-actions to run eligible process-spawning actions in a
bubblewrap-wrapped worker. (#14240, @rgrinberg)
-
Add platform support for DragonFly BSD (#14774, fixes same issue with lev
as seen on NetBSD in #14484, @mneumann).
-
Added command, subcommand, and flag completion in the command line.
Supported shells are bash, zsh, and pwsh.
See dune completion [shell] --help.
(#14779, @ElectreAAS)
-
Add %{git-sha} variable that expands to the short git SHA of the current
HEAD commit, or the empty string when git is unavailable or the workspace is
not inside a git repository (#14810, @toots).
-
Add a ?static optional argumentin Configurator.V1.Pkg_config.get to instruct pkg-config to get static linking options. (#14947, @raphael-proust)
-
Only generate Melange rule for multi-mode libraries if melc is installed
(#15021, @anmonteiro)
-
Add Configurator.V1.Pkg_config.query_variable to query package variables
through pkg-config --variable (#15078, fixes #3332, @rgrinberg).
-
Add env_vars as an alias for the env-vars field in env stanzas
(#15187, fixes #11424, @rgrinberg).
-
Add @rocqproject alias to generate all `_RocqProject files
(#15221, @rlepigre-skylabs-ai).
-
Tab completion for dune promote now lists pending promotion files.
(#15338, fixes #7254, @Alizter).
-
Add build time information to watch mode (#15384, @rgrinberg)
-
Added the missing dune tools exec utop and dune tools exec odoc options.
(#15388, @Leonidas-from-XIV)
-
Display build parallelism in watch mode. (#15390, @rgrinberg)
-
Add process counts, system cpu, user cpu, and wall clock cpu times to trace
events (#15401, @rgrinberg)
-
Support --sandbox-actions on macOS using sandbox-exec. (#15500,
@rgrinberg)
-
Add fish to the shells supported by dune completion, enabling
command, subcommand, and flag completion in the fish shell (#15515,
fixes #15334, @chizy7)
-
Display build duration and average process parallelism in the status line for
batch builds. (#15564, @rgrinberg)
-
Add a --split-public-names flag to dune describe workspace and dune describe external-lib-deps. When enabled, the name/names fields report
only private names and a new public_name/public_names field reports the
public names. (#15582, @NatKarmios)
-
Add a --include-empty flag to dune describe external-lib-deps to also
print libraries that have no internal or external dependencies (#15585,
@NatKarmios)
-
Support qualified module references in fields such as per_module when using
(include_subdirs qualified) (#15633, fixes #15578, @anmonteiro)
-
Display the current build run at the end of watch-mode status lines.
(#15673, @rgrinberg)
-
Record per-build Memo compute, restore, and cycle-detection metrics in Dune
traces. (#15698, @rgrinberg)
-
Record discovered, validated, and failed rule counts in Dune traces.
(#15701, @rgrinberg)
-
Add %{melange.emit:...} to reference a Melange output directory and
depend on its emitted files (#15751, @anmonteiro)
-
Add (flags ...) to the ocamllex and ocamlyacc stanzas to pass custom
options to parser generators. (#15907, @rgrinberg)
-
Added an opt-in sat trace category emitting a sat/solve event with
the SAT solver's stats (variables, clauses, decisions, conflicts) and
duration. Enable with DUNE_TRACE=+sat. (#15923, @Alizter)
-
Add dune ocaml inferred-mli to infer an interface with a module's build
configuration and register it for promotion. (#16111, fixes #12727,
@rgrinberg)
-
Add --no-actions and --only-actions to dune trace cat to filter
events collected from actions. (#16245, @rgrinberg)
Changed
-
BREAKING CHANGE: Actions no longer see the shared install staging area
(_build/install/<context>/{bin,lib,lib/stublibs}) on PATH, OCAMLPATH and
CAML_LD_LIBRARY_PATH. An action's environment only contains the packages it
declares with (deps (package <pkg>)) (and their library closure, see below).
Actions that rely on packages being visible (such as tests that #require the
package under test from an mdx block, steps that run ocamlfind, a nested dune
build, or load a bytecode stub library) must now declare the package
dependency explicitly.
(#14373, #16617, @Alizter)
-
(package <pkg>) now also includes the packages owning the library closures
of libraries in workspace and installed packages. Installed packages reached
through those closures also work with Dune language versions older than 2.9.
(#14373, #16362, #16529, @Alizter, @anmonteiro)
-
Extract the structural-hash accumulator into a new Stdune.Hash
module and route Stdune.Tuple.T2.hash, Stdune.Tuple.T3.hash,
Stdune.List.hash, Stdune.Result.hash, and Resolve.error_hash
through it. Hashing these structural shapes no longer allocates per
call.
(#14542, @robinbb)
-
Remove (using melange 0.1) in Dune 3.25 in favor of version 1.0 of the
extension. (#14574, @anmonteiro)
-
$ dune rpc build invocations no longer queue. All build requests are built
in parallel. Watch servers started by $ dune exec --watch can now also
handle forwarded build and runtest requests (#14954, @rgrinberg)
-
Report rule build progress as the number of rules built against the total
number of live rules, rather than rules executed against rules discovered
during the current run. This affects both the status line and the progress
reported over RPC. (#14985, @snowleopard, @pWhite)
-
With --error-reporting=twice, print an ==== Error Summary ==== separator
before the deterministic list of errors reported at the end of the build. The
separator is omitted when there are no errors to report.
(#15016, fixes #14757, @yussypu)
-
Enable fuzzy patch application by default for Dune. This is similar to OPAM's
behaviour, and this makes it easier for packages like OxCaml to build.
(#15146, fixes #15145, @Sudha247)
-
Odoc rules are now sandboxed (#15190, @rgrinberg)
-
In watch mode, $ dune rpc build requests now complete as soon as their
requested build finishes, instead of waiting for unrelated concurrent RPC build
requests in the same build iteration. (#15191, fixes #13788, @rgrinberg)
-
Cleanup all build processes spawned by dune before starting a fresh build on
Linux. (#15239, #15274, @rgrinberg)
-
Show partial output timed out cram tests (#15269, @rgrinberg)
-
In watch mode, $ dune rpc build now exits with status 1 when the
requested build fails. (#15341, @rgrinberg)
-
Debounce file change events in watch mode (#15344, @rgrinberg)
-
Align dune's C compiler vendor detection with the OCaml compiler's own
identifiers (msvc, icc, mingw, clang, gcc, xlc, sunc), so more C
compilers are recognized without emitting a spurious warning. (#15423,
fixes #14870, @chizy7)
-
Never use $ lsof for counting file descriptors, as it is not allowed
to reap processes outside of the scheduler. We have better mechanisms
on MacOS and Linux for counting file descriptors. So this is only an
issue on other Unices. (#15477, @rgrinberg)
-
dune describe workspace now reports an origin field for every module,
indicating whether its source was written by hand (source), generated by a
rule stanza (dune, with the generating dune file), produced by ocamllex,
ocamlyacc, or menhir, or synthesised by dune itself for wrapping
(wrapper). Generated modules point at the responsible file. The
--with-origin-deps and --with-origin-deps-expanded flags additionally
report the dependencies of a rule-generated module, as declared and expanded
to concrete files respectively.
(#15478, @nat-karmios)
-
Numbers with unit now allow dropping the unit if the number is zero ("0").
For example, dune cache trim --trimmed-size 0 and dune cache trim --trimmed-size 0TiB are now both accepted and equivalent. (#15498, @reynir)
-
Run artifact substitution in background workers. (#15559, @anmonteiro)
-
dune describe now reports the public name of an executable (from
public_name/public_names) instead of its private name when one is
available, falling back to the private name otherwise. (#15582, @NatKarmios)
-
Calculate status-line build parallelism from process CPU time rather than
wall-clock action time; Windows continues to use wall-clock time.
(#15685, @rgrinberg)
-
Use sha256 instead of md5 for source archives that lack a checksum
(#15824, @shunueda)
-
Starting with Dune language 3.25, restrict sandboxed actions on Linux
systems with Landlock ABI 3 or newer from writing outside their sandbox,
temporary directory, action-trace directory, and /dev. Set
DUNE_CONFIG__LANDLOCK=disabled to opt out. (#15858, @rgrinberg)
-
dune pkg lock now fails without writing a lock directory when any platform
requested by solve_for_platforms cannot be solved, instead of producing a
partial lock directory containing only the successful platforms. (#15981,
@Alizter)
-
Portable lock directories now select one package version across all requested
platforms, and fail when no common version exists. (#15982, fixes #13645,
fixes #13647, @Alizter)
-
BREAKING CHANGE: Reject : in context names so they remain portable path
components (#16085, @rgrinberg)
-
Keep .t suffixes in cram test names, including aliases and applies_to,
starting with Dune language 3.25 (#16146, @rgrinberg)
-
Sandbox ocaml-mdx dune-gen when using MDX extension 0.6, available from
Dune 3.25. (#16177, @rgrinberg)
-
Sandbox pkg-config queries starting with Dune language 3.25 so they cannot
observe undeclared workspace inputs. (#16178, @rgrinberg)
-
Remove the experimental OCamlFDO integration, including the (fdo ...)
workspace field (#16198, @rgrinberg)
-
BREAKING CHANGE: Generated files are now read-only even with Dune language
versions before 2.4, regardless of whether the shared cache is enabled.
Executable permissions are preserved. (#16388, @rgrinberg)
-
Make newly written shared-cache metadata files read-only to guard against
accidental modification. (#16393, @rgrinberg)
Bug fixes release with 6 security fixes, and 2 ordinary bug fixes:
- Security fix OSEC-2026-18:
Marshal.from_{string,bytes}
- Security fix OSEC-2026-21:
Str.string_partial_match
- Security fix OSEC-2026-22:
Unix.map_file
- Security fix OSEC-2026-23: multiple issues in demarshaling
- Security fix OSEC 2026-24: multiple issues in command quoting on Windows
- Security fix OSEC-2026-30: ephemeron runtime fix
- Bug fix for pattern compilation
- Bug fix for new version of macOS.
See detailed list of changes
CHANGES:
Added
Changed
- Require dune 3.14 to build. (#532, @samoht)
- Declare the maintenance intent of the opam package, so that opam-repository
can archive its older releases. (#507, #533, @samoht, reported by @hannesm)
- The pull request to opam-repository no longer links to the
doc field of
the opam file: dune-release stopped publishing the documentation in
2.1.0, so the link was often broken. (#511, #534, @samoht, reported by
@talex5)
Fixed
dune-release publish now respects the --dev-repo or
DUNE_RELEASE_DEV_REPO CLI inputs. (#521, #522, @shonfeder, reviewed by
@Leonidas-from-XIV)
- Fix
distrib and check on Windows: the temporary clone copies the git
objects instead of hardlinking them, which git refuses there, and their
read-only attribute is cleared before the clone is deleted. Warnings and
errors show the executable name without its .exe suffix.
(#378, #529, @emillon, @samoht)
- A yes or no question with no input left to read takes its default answer
instead of failing with an uncaught End_of_file. (#525, @samoht)
- On a terminal, answers are typed on the line of their question, instead of
on the next line. (#526, @samoht, reported and reviewed by @xvw)
dune-release opam submit always prints the URL of the pull request it
opened, and no longer shows the errors of xdg-open when there is no
browser to open it with. (#306, #535, @samoht, reported by @mato)
- Build with the opam 2.6 libraries. (#524, #527, @vbgl, @samoht)
- The README no longer lists
opam and ocamlfind as runtime dependencies,
which dune-release lint stopped calling in 2.2.0. (#430, #509, #528,
@samoht, reviewed by @Leonidas-from-XIV)
- The README explains how to publish through an ssh alias. (#440, @pbaudin)
- When the change log cannot be parsed,
dune-release says what it expects
of its first heading, and no longer prints a raw debug line. (#207, #537,
@samoht, reported by @Drup)
dune-release distrib skips dune subst when dune-project disables it
with (subst disabled), instead of failing. (#496, #538, @samoht, reported
by @talex5)
dune-release publish no longer aborts when the release asset was already
uploaded, or when its upload is declined: the asset on the release is used
instead. (#513, #539, @samoht, reported by @davesnx)
dune-release publish accepts a dev-repo that names a branch with
#branch: the fragment is dropped from the URL used to push the tag and to
find the GitHub repository. (#203, #540, @samoht, reported by @hannesm)
dune-release opam pkg run without publish now infers the right archive
URL for an https GitHub dev-repo. (#541, @samoht)
- The
lint man page describes the checks lint performs today. (#542,
@samoht)
CHANGES:
Features
- Offer parenthesized application snippets for constructors with payloads, with
independent argument slots, while retaining name-only completions. (#2212, @rgrinberg)
- Make generated destruct branch bodies interactive for clients with snippet edit
support. (#2204, @rgrinberg)
- Offer whole-call completions for OCaml functions with multiple labelled or
optional arguments, with editable slots for all arguments. (#2199, @rgrinberg)
- Make generated construct completions interactive for clients with snippet support.
(#2198, @rgrinberg)
- Support
ocp-indent as an alternative for document and range formatting.
(#2148, @rgrinberg)
- Support
textDocument/onTypeFormatting through the optional, persistent
ocp-indent-rpc helper. (#1986, @rgrinberg)
- Report Dune RPC, build progress, and Merlin configuration process activity
through LSP trace notifications. (#1899, @rgrinberg)
- Add a code action to open the closest Dune file for the current document.
(#1817, fixes #1491, @rgrinberg)
- Distinguish operators from functions in semantic highlighting. (#1831, @rgrinberg)
- Support
textDocument/implementation for type declarations in interface files,
including nested modules, functor results, includes, and aliases.
(#2074, fixes #1163, @rgrinberg)
- Classify function parameters and labels in semantic highlighting.
(#1857, @rgrinberg)
- Distinguish built-in from user-defined types in semantic highlighting.
(#1858, fixes #1139, @rgrinberg)
- Topiary formatter added (#2226, toastal)
- Add custom
ocamllsp/completePrefixAtPos
request, which completes a given prefix at a given position and returns
function argument labels separately from the completions.
This will be used by Emacs via the
ocaml-eglot package. (#2230, @spwhitton)
Fixes
- Avoid overlapping semantic tokens in
with type constraints and destructive
substitutions. (#2206, @rgrinberg)
- Preserve nested or-patterns when formatting destruct-line case-analysis
replies. (#2194, @rgrinberg)
- Clear stale Dune diagnostics and promotion actions when an RPC instance exits,
without removing a replacement instance for the same root. (#2189, @rgrinberg)
- Ensure recovered selection ranges contain the requested position. (#2170,
@rgrinberg)
- Suppress function extraction when a constructor would move out of scope or
resolve to a shadowing declaration. (#2169, @rgrinberg)
- Clamp recovered selection ranges to the document bounds. (#2061, @rgrinberg)
- Exclude symbol declarations from reference results when requested by the
client. (#2164, @rgrinberg)
- Convert related locations parsed from Merlin diagnostic messages to zero-based
LSP line numbers. (#2163, fixes #2145, @rgrinberg)
- Preserve trailing newlines when computing post-edit ranges. (#2159,
@rgrinberg)
- Return only inlay hints within the range requested by the client. (#2155,
@rgrinberg)
- Return document symbol kinds the client supports, falling back to
Constructor and Class when it does not advertise the newer kinds.
(#2122, fixes #2121, @dayangac)
- Offer the unused-code quick fixes again: they matched diagnostic messages the
server does not emit, and marking an unused open! produced open!!.
(#2117, fixes #2116, @dayangac)
- Offer to create a missing implementation or interface counterpart only when
the client supports the create resource operation. (#2115, fixes #2114,
@dayangac)
- Tag unused and deprecated values in diagnostics, so clients can grey them out
or strike them through. (#2110, fixes #2109, @dayangac)
- Honor client support for deprecation tags in workspace-symbol results.
(#2113, @rgrinberg)
- Respect the client's folding range capabilities: omit character positions for
lineFoldingOnly clients, omit unsupported folding range kinds, and honor
rangeLimit. (#2099, fixes #911, @dayangac)
- Classify module names in
with constraints and in signature opens in
semantic highlighting. (#2098, fixes #808, @dayangac)
- Report a type when hovering a variant constructor or an exception where it is
declared. (#2102, fixes #1300, @dayangac)
- Return no location instead of failing the request when a definition,
declaration or type definition cannot be found, so clients that request them
eagerly no longer surface spurious errors. (#2100, fixes #1161, @dayangac)
- Prefer a same-document related location when a Dune diagnostic has an empty
primary range, such as ml/mli mismatches. (#2093, @rgrinberg)
- Stop offering the inferred-interface code action when the interface already
declares everything the implementation exports. (#2096, fixes #347, @dayangac)
- Unregister Dune promotion code actions when an RPC instance finishes.
(#2076, @rgrinberg)
- Avoid unregistering promotion code actions when clearing the last promotion
for an already open document. (#2075, @rgrinberg)
- Find destruct-line cases after module-type constraints in match scrutinees.
(#2072, @rgrinberg)
- Keep Dune RPC registry polling responsive while connected instances are
running. (#1919, @rgrinberg)
- Fix the build on FreeBSD, where
statfs(2) is declared in <sys/mount.h>
rather than <sys/statfs.h>. (#2070, fixes #1069, @dayangac)
- Deduplicate identical rename text edits returned by Merlin recovery.
(#2064, @rgrinberg)
- Reject cross-line destruct recovery locations before applying line-local
source offsets. (#2063, @rgrinberg)
- Use consistent document snapshots and versions when converting rename
occurrences into workspace edits. (#2062, @rgrinberg)
- Reject malformed destruct-line recovery replies and find match separators
lexically instead of treating identifier substrings as with. (#2043, @rgrinberg)
- Skip inline edit construction for bindings without applicable uses, avoiding
stack exhaustion when printing deeply recovered expressions. (#2041, @rgrinberg)
- Keep construct-completion text edits on the request line when Merlin recovery
returns a multiline location. (#2034, @rgrinberg)
- Advertise Dune promotion code actions using their returned
quickfix kind.
(#2055, @rgrinberg)
- Reject interface documents passed to the
ocamllsp/inferIntf custom request
with InvalidParams. (#2051, @rgrinberg)
- Report malformed type-enclosing custom-request parameters as
InvalidParams
instead of an internal error. (#2050, @rgrinberg)
- Return
null from the refactor-extract custom request for empty ranges.
(#2049, @rgrinberg)
- Return
null from the destruct custom request for inapplicable ranges.
(#2048, @rgrinberg)
- Return
null from the construct custom request when the cursor is not at a
typed hole. (#2047, @rgrinberg)
- Preserve deprecation status in workspace-symbol results. (#2044, @rgrinberg)
- Render empty odoc tables in hover documentation without raising an internal
error. (#2038, @rgrinberg)
- Enable function parameter inlay hints when the client sends no configuration.
(#2097, fixes #1371, @dayangac)
- Respect client support for signature-help parameter-label offsets. (#2009,
@rgrinberg)
- Keep Merlin diagnostic ranges within document bounds. (#2008, @rgrinberg)
- Suppress triggered completion and signature help inside comments after Unicode.
(#1994, @rgrinberg)
- Emit semantic tokens in source order so their relative positions remain valid.
(#1992, @rgrinberg)
- Stop stale signature help at expression boundaries. (#1987, fixes #1162,
@rgrinberg)
- Suppress signature help for completed applications. (#1982, #1162, @rgrinberg)
- Encode remove-unused code-action edits using the client's negotiated position
encoding. (#1969, @rgrinberg)
- Exclude surrounding parentheses from infix operator rename placeholders and
edits. (#1966, fixes #1190, @rgrinberg)
- Suppress signature help for applications after the cursor. (#1965, #1162,
@rgrinberg)
- Use each document's current version in multi-file rename edits. (#1958, @rgrinberg)
- Handle zero-work Dune build progress updates. (#1896, @rgrinberg)
- Do not report Dune build progress when the client disables work-done progress.
(#2082, @rgrinberg)
- Reject malformed Dune promotion commands. (#2084, @rgrinberg)
- Keep Dune promotion registrations balanced when diagnostics share a source.
(#2089, @rgrinberg)
- Reject negative JSON-RPC
Content-Length headers. (#1873, @rgrinberg)
- Report unsupported LSP request methods as unavailable instead of internal
server errors. (#1862, @rgrinberg)
- Advertise semantic-token support only to clients that declare the capability.
(#1851, @rgrinberg)
- Advertise semantic-token support only to clients that support the relative
token format. (#1853, @rgrinberg)
- Advertise semantic-token support only to clients that support full-document
requests. (#1856, @rgrinberg)
- Advertise semantic-token delta support only to clients that request it.
(#1859, @rgrinberg)
- Advertise and encode only semantic token types supported by the client.
(#1860, @rgrinberg)
- Advertise and encode only semantic token modifiers supported by the client.
(#1978, @rgrinberg)
- Offer the
destruct-line code action on inline match expressions with
incomplete cases. (#1829, fixes #1595, @rgrinberg)
- Replace a lone polymorphic-variant backtick when applying completions.
(#1823, fixes #1427, @rgrinberg)
- Report a missing project build-system executable as a diagnostic without
discarding the opened document. (#1814, @rgrinberg)
- Advertise all code-action kinds that the server may return. (#1803, @rgrinberg)
- Respect hierarchical code-action kind filters from clients. (#1802, @rgrinberg)
- Ensure
textDocument/documentSymbol returns a selectionRange contained
within its range, so clients no longer reject the document outline.
(#1775, fixes #1560, @Leonard013)
- Recompute Merlin diagnostics when diagnostic shortening changes. (#1804, @rgrinberg)
- Avoid eagerly computing inline code-action edits when clients support lazy
resolution. (#1808, @rgrinberg)
- Keep URI query parameters separate from filesystem paths. (#1776, @rgrinberg)
- Preserve URI paths beginning with two slashes across serialization. (#1798, @rgrinberg)
- Preserve percent-encoded URI fragments across parsing and serialization. (#1801, @rgrinberg)
- Preserve URI paths whose first segment resembles a non-letter Windows drive. (#1800, @rgrinberg)
- Preserve unescaped Unicode in URI query components. (#1799, @rgrinberg)
- Preserve document offsets across incremental text edits. (#1777, @rgrinberg)
- Respect the client's preferred completion documentation format. (#1885, @rgrinberg)
- Parse non-ASCII completion prefixes and whitespace in CRLF input. (#1886, @rgrinberg)
- Use constructor completion kinds when clients do not support enum members. (#1887, @rgrinberg)
- Use completion deprecation tags when supported by the client. (#1903, @rgrinberg)
- Keep completion sort keys lexically ordered beyond 9,999 items. (#1883, @rgrinberg)
- Replace incorrect identifier suffixes when applying completions. (#1964, fixes #838, @rgrinberg)
- Give synthetic completion items stable ordering metadata. (#1882, @rgrinberg)
- Preserve dotted operators in completion prefixes and resolve requests. (#1890, @rgrinberg)
- Correct code-action ranges after multiline text insertions. (#1748, @rgrinberg)
- Allow clients to add their first workspace folder dynamically. (#1747, @rgrinberg)
- Unregister Dune promotion commands after their diagnostics are cleared. (#1746, @rgrinberg)
- Point workspace symbols for generated sources to their files in the build
directory. (#1742, @tatchi)
- Stop workspace symbol searches from warning when a workspace has not been
built yet. (#1769, @smorimoto)
- Prevent whole-document formatting requests for OCamllex, Menhir, and Cram
files from being routed through Dune's S-expression formatter.
- Refactor ppx hover to use merlin directly (#1606, fixes #1614)
CHANGES:
Wed Nov 04 15:27:42 CET 2026
- merlin library
- Fix a caching issue making inconsistant units stale (#2141)
- ocaml index
- Fix a regression due to the new "pointing indexes" mechanism (#2144)
- Fix an issue when using absolute output paths for the indexer (#2144)
CHANGES:
Added
Fixed
- Avoid relying on
ocamllex raising Failure for an unescaped '{', which
OCaml 5.6's ocamllex warns about (@Leonidas-from-XIV, #1494)
- Remove requirement for ppx_expect in tests (@jonludlam, #1445)
We have the pleasure of celebrating the anniversary of the first
powered flight in Europe by announcing the release of OCaml 5.5.2.
OCaml 5.5.2 fixes various minor security issues, two rare miscompilations, a
configuration issue with future versions of macOS, and one runtime
events library issue.
Overall, if you were already using any versions of OCaml 5.5,
we are advising you to switch to OCaml 5.5.2 .
The full list of changes can be found in the full changelog.
Installation Instructions
The base compiler can be installed as an opam switch with the following
commands:
opam update
opam switch create 5.5.2
The source code for the release is also directly available on:
Fine-Tuned Compiler Configuration
If you want to tweak the configuration of the compiler, you can switch to the
option variant with:
opam update
opam switch create <switch_name> ocaml-variants.5.5.2+options <option_list>
where <option_list> is a space separated list of ocaml-option-* packages.
For instance, for a flambda and no-flat-float-array switch:
opam switch create 5.5.2+flambda+nffa ocaml-variants.5.5.2+options ocaml-option-flambda ocaml-option-no-flat-float-array
See full changelog
Bug fixes
-
#15045: Atomic loads whose results are unused should not be removed
during dead-code elimination.
(Xavier Clerc, review by Steven Dolan and KC Sivaramakrishnan)
-
#15067, #15071: Fix detection of functions available in the future on macOS.
(Antonin Décimo, review by Nicolás Ojeda Bär and Damien Doligez)
-
#15112, OSEC-2026-22: Unix.map_file: protect against overflow
when computing the data size.
(Xavier Leroy and Nicolás Ojeda Bär, review by Nicolás Ojeda Bär
and Edwin Török)
-
#15113, OSEC-2026-21: Str.string_partial_match: make sure captured groups
are valid.
(Xavier Leroy, review by Nicolás Ojeda Bär and Edwin Török)
-
#15115, OSEC-2026-23: Fix multiple issues in demarshaling
(Marshal.from_{channel,string,bytes})
(Xavier Leroy, review by Nicolás Ojeda Bär)
-
#15133, OSEC 2026-24: Multiple issues in command quoting on Windows
(Xavier Leroy and Nicolás Ojeda Bär, review by Nicolás Ojeda Bär)
-
#15119, OSEC-2026-25: Harden decoding of runtime events messages from
ring buffers.
(Sadiq Jaffer, report by Hannes Mehnert, review by Olivier Nicole and
Edwin Török)
-
#15177, OSEC-2026-26: Maintain custom events cache integrity.
(Sadiq Jaffer, report by Hannes Mehnert, review by Edwin Török)
-
#15043, #15076: runtime events library, fix an infinite loop when a user
event is larger than half the ring buffer.
(Tim McGilchrist, review by Sadiq Jaffer)
-
#15185, #15187: fix a pattern-matching miscompilation on certain
combinations of immediate ranges and redundant patterns
(Gabriel Scherer, report by Alperer Keleş,
review by Vincent Laviron and Florian Angeletti)
CHANGES:
Features
- Offer parenthesized application snippets for constructors with payloads, with
independent argument slots, while retaining name-only completions. (#2212, @rgrinberg)
- Make generated destruct branch bodies interactive for clients with snippet edit
support. (#2204, @rgrinberg)
- Offer whole-call completions for OCaml functions with multiple labelled or
optional arguments, with editable slots for all arguments. (#2199, @rgrinberg)
- Make generated construct completions interactive for clients with snippet support.
(#2198, @rgrinberg)
- Support
ocp-indent as an alternative for document and range formatting.
(#2148, @rgrinberg)
- Support
textDocument/onTypeFormatting through the optional, persistent
ocp-indent-rpc helper. (#1986, @rgrinberg)
- Report Dune RPC, build progress, and Merlin configuration process activity
through LSP trace notifications. (#1899, @rgrinberg)
- Add a code action to open the closest Dune file for the current document.
(#1817, fixes #1491, @rgrinberg)
- Distinguish operators from functions in semantic highlighting. (#1831, @rgrinberg)
- Support
textDocument/implementation for type declarations in interface files,
including nested modules, functor results, includes, and aliases.
(#2074, fixes #1163, @rgrinberg)
- Classify function parameters and labels in semantic highlighting.
(#1857, @rgrinberg)
- Distinguish built-in from user-defined types in semantic highlighting.
(#1858, fixes #1139, @rgrinberg)
Fixes
- Avoid overlapping semantic tokens in
with type constraints and destructive
substitutions. (#2206, @rgrinberg)
- Preserve nested or-patterns when formatting destruct-line case-analysis
replies. (#2194, @rgrinberg)
- Clear stale Dune diagnostics and promotion actions when an RPC instance exits,
without removing a replacement instance for the same root. (#2189, @rgrinberg)
- Ensure recovered selection ranges contain the requested position. (#2170,
@rgrinberg)
- Suppress function extraction when a constructor would move out of scope or
resolve to a shadowing declaration. (#2169, @rgrinberg)
- Clamp recovered selection ranges to the document bounds. (#2061, @rgrinberg)
- Exclude symbol declarations from reference results when requested by the
client. (#2164, @rgrinberg)
- Convert related locations parsed from Merlin diagnostic messages to zero-based
LSP line numbers. (#2163, fixes #2145, @rgrinberg)
- Preserve trailing newlines when computing post-edit ranges. (#2159,
@rgrinberg)
- Return only inlay hints within the range requested by the client. (#2155,
@rgrinberg)
- Return document symbol kinds the client supports, falling back to
Constructor and Class when it does not advertise the newer kinds.
(#2122, fixes #2121, @dayangac)
- Offer the unused-code quick fixes again: they matched diagnostic messages the
server does not emit, and marking an unused open! produced open!!.
(#2117, fixes #2116, @dayangac)
- Offer to create a missing implementation or interface counterpart only when
the client supports the create resource operation. (#2115, fixes #2114,
@dayangac)
- Tag unused and deprecated values in diagnostics, so clients can grey them out
or strike them through. (#2110, fixes #2109, @dayangac)
- Honor client support for deprecation tags in workspace-symbol results.
(#2113, @rgrinberg)
- Respect the client's folding range capabilities: omit character positions for
lineFoldingOnly clients, omit unsupported folding range kinds, and honor
rangeLimit. (#2099, fixes #911, @dayangac)
- Classify module names in
with constraints and in signature opens in
semantic highlighting. (#2098, fixes #808, @dayangac)
- Report a type when hovering a variant constructor or an exception where it is
declared. (#2102, fixes #1300, @dayangac)
- Return no location instead of failing the request when a definition,
declaration or type definition cannot be found, so clients that request them
eagerly no longer surface spurious errors. (#2100, fixes #1161, @dayangac)
- Prefer a same-document related location when a Dune diagnostic has an empty
primary range, such as ml/mli mismatches. (#2093, @rgrinberg)
- Stop offering the inferred-interface code action when the interface already
declares everything the implementation exports. (#2096, fixes #347, @dayangac)
- Unregister Dune promotion code actions when an RPC instance finishes.
(#2076, @rgrinberg)
- Avoid unregistering promotion code actions when clearing the last promotion
for an already open document. (#2075, @rgrinberg)
- Find destruct-line cases after module-type constraints in match scrutinees.
(#2072, @rgrinberg)
- Keep Dune RPC registry polling responsive while connected instances are
running. (#1919, @rgrinberg)
- Fix the build on FreeBSD, where
statfs(2) is declared in <sys/mount.h>
rather than <sys/statfs.h>. (#2070, fixes #1069, @dayangac)
- Deduplicate identical rename text edits returned by Merlin recovery.
(#2064, @rgrinberg)
- Reject cross-line destruct recovery locations before applying line-local
source offsets. (#2063, @rgrinberg)
- Use consistent document snapshots and versions when converting rename
occurrences into workspace edits. (#2062, @rgrinberg)
- Reject malformed destruct-line recovery replies and find match separators
lexically instead of treating identifier substrings as with. (#2043, @rgrinberg)
- Skip inline edit construction for bindings without applicable uses, avoiding
stack exhaustion when printing deeply recovered expressions. (#2041, @rgrinberg)
- Keep construct-completion text edits on the request line when Merlin recovery
returns a multiline location. (#2034, @rgrinberg)
- Advertise Dune promotion code actions using their returned
quickfix kind.
(#2055, @rgrinberg)
- Reject interface documents passed to the
ocamllsp/inferIntf custom request
with InvalidParams. (#2051, @rgrinberg)
- Report malformed type-enclosing custom-request parameters as
InvalidParams
instead of an internal error. (#2050, @rgrinberg)
- Return
null from the refactor-extract custom request for empty ranges.
(#2049, @rgrinberg)
- Return
null from the destruct custom request for inapplicable ranges.
(#2048, @rgrinberg)
- Return
null from the construct custom request when the cursor is not at a
typed hole. (#2047, @rgrinberg)
- Preserve deprecation status in workspace-symbol results. (#2044, @rgrinberg)
- Render empty odoc tables in hover documentation without raising an internal
error. (#2038, @rgrinberg)
- Enable function parameter inlay hints when the client sends no configuration.
(#2097, fixes #1371, @dayangac)
- Respect client support for signature-help parameter-label offsets. (#2009,
@rgrinberg)
- Keep Merlin diagnostic ranges within document bounds. (#2008, @rgrinberg)
- Suppress triggered completion and signature help inside comments after Unicode.
(#1994, @rgrinberg)
- Emit semantic tokens in source order so their relative positions remain valid.
(#1992, @rgrinberg)
- Stop stale signature help at expression boundaries. (#1987, fixes #1162,
@rgrinberg)
- Suppress signature help for completed applications. (#1982, #1162, @rgrinberg)
- Encode remove-unused code-action edits using the client's negotiated position
encoding. (#1969, @rgrinberg)
- Exclude surrounding parentheses from infix operator rename placeholders and
edits. (#1966, fixes #1190, @rgrinberg)
- Suppress signature help for applications after the cursor. (#1965, #1162,
@rgrinberg)
- Use each document's current version in multi-file rename edits. (#1958, @rgrinberg)
- Handle zero-work Dune build progress updates. (#1896, @rgrinberg)
- Do not report Dune build progress when the client disables work-done progress.
(#2082, @rgrinberg)
- Reject malformed Dune promotion commands. (#2084, @rgrinberg)
- Keep Dune promotion registrations balanced when diagnostics share a source.
(#2089, @rgrinberg)
- Reject negative JSON-RPC
Content-Length headers. (#1873, @rgrinberg)
- Report unsupported LSP request methods as unavailable instead of internal
server errors. (#1862, @rgrinberg)
- Advertise semantic-token support only to clients that declare the capability.
(#1851, @rgrinberg)
- Advertise semantic-token support only to clients that support the relative
token format. (#1853, @rgrinberg)
- Advertise semantic-token support only to clients that support full-document
requests. (#1856, @rgrinberg)
- Advertise semantic-token delta support only to clients that request it.
(#1859, @rgrinberg)
- Advertise and encode only semantic token types supported by the client.
(#1860, @rgrinberg)
- Advertise and encode only semantic token modifiers supported by the client.
(#1978, @rgrinberg)
- Offer the
destruct-line code action on inline match expressions with
incomplete cases. (#1829, fixes #1595, @rgrinberg)
- Replace a lone polymorphic-variant backtick when applying completions.
(#1823, fixes #1427, @rgrinberg)
- Report a missing project build-system executable as a diagnostic without
discarding the opened document. (#1814, @rgrinberg)
- Advertise all code-action kinds that the server may return. (#1803, @rgrinberg)
- Respect hierarchical code-action kind filters from clients. (#1802, @rgrinberg)
- Ensure
textDocument/documentSymbol returns a selectionRange contained
within its range, so clients no longer reject the document outline.
(#1775, fixes #1560, @Leonard013)
- Recompute Merlin diagnostics when diagnostic shortening changes. (#1804, @rgrinberg)
- Avoid eagerly computing inline code-action edits when clients support lazy
resolution. (#1808, @rgrinberg)
- Keep URI query parameters separate from filesystem paths. (#1776, @rgrinberg)
- Preserve URI paths beginning with two slashes across serialization. (#1798, @rgrinberg)
- Preserve percent-encoded URI fragments across parsing and serialization. (#1801, @rgrinberg)
- Preserve URI paths whose first segment resembles a non-letter Windows drive. (#1800, @rgrinberg)
- Preserve unescaped Unicode in URI query components. (#1799, @rgrinberg)
- Preserve document offsets across incremental text edits. (#1777, @rgrinberg)
- Respect the client's preferred completion documentation format. (#1885, @rgrinberg)
- Parse non-ASCII completion prefixes and whitespace in CRLF input. (#1886, @rgrinberg)
- Use constructor completion kinds when clients do not support enum members. (#1887, @rgrinberg)
- Use completion deprecation tags when supported by the client. (#1903, @rgrinberg)
- Keep completion sort keys lexically ordered beyond 9,999 items. (#1883, @rgrinberg)
- Replace incorrect identifier suffixes when applying completions. (#1964, fixes #838, @rgrinberg)
- Give synthetic completion items stable ordering metadata. (#1882, @rgrinberg)
- Preserve dotted operators in completion prefixes and resolve requests. (#1890, @rgrinberg)
- Correct code-action ranges after multiline text insertions. (#1748, @rgrinberg)
- Allow clients to add their first workspace folder dynamically. (#1747, @rgrinberg)
- Unregister Dune promotion commands after their diagnostics are cleared. (#1746, @rgrinberg)
- Point workspace symbols for generated sources to their files in the build
directory. (#1742, @tatchi)
- Stop workspace symbol searches from warning when a workspace has not been
built yet. (#1769, @smorimoto)
- Prevent whole-document formatting requests for OCamllex, Menhir, and Cram
files from being routed through Dune's S-expression formatter.
- Refactor ppx hover to use merlin directly (#1606, fixes #1614)
CHANGES:
Mon Oct 01 15:31:42 CEST 2026
- merlin library
- destruct: allow to destruct let-bindings's patterns (#2117)
- Fix detection of expression at cursor in case of type-constrained
expression (#2120)
- enclosing: drastically improve the ranges! (#2121)
- Fix oversharing in Parsetree cache (#2131)
- Add
PPX_DEPS to advertise PPX dependencies in Merlin configuration
(#2127)
- Stop printing ghost bindings in outline (#2135)
- merlin binary
- Use c library flags from
ocamlc -config. Fixes Haiku build (#2124)
- test suite
- Add a test case illustrating
case-analysis command fails to load module
in issue #1786 (#2002)
- Add a test reproducing the locate command failure when editor position is
in another declaration (#2033)
- Add a test to ensure the behavior showed in issue #1980
Feedback on this post is welcome on Discuss!
We are pleased to announce the release of opam 2.6.1 fixing a couple of regressions and minor annoyances.
We advise everyone to upgrade. Please read on for installation and upgrade instructions.
Regression fixes
- Fix the depexts installation on
opam install --deps-only when the system packages already exist in a repository (#7153)
Improvements
-
Add support for using git repositories owned by another local user (common in docker containers) (#6963)
-
Since 2.6.0, to make git calls more deterministic, opam doesn't take into account the user git config. In 2.6.1, it now uses /dev/null on both Unix and Windows when setting GIT_CONFIG_* instead of NUL on Windows to work around a bug in Git-for-Windows 2.56.0.windows.1 (#7085)
Try it!
The upgrade instructions are unchanged:
-
Either from binaries: run
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.6.1"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.6.1"
or download manually from the Github "Releases" page to your PATH.
-
Or from source, manually: see the instructions in the README.
You should then run:
opam init --reinit -ni
Please report any issues to the bug-tracker.
Happy hacking!
CHANGES:
Added
Changed
- Paths are normalized to drop the directory prefix ("./" on macOS and Linux)
before pretty printing them (#482, @shonfeder).
Feedback on this post is welcome on Discuss!
We're happy to announce the release of opam 2.6.0 and encourage all users to upgrade.
Please read on for installation and upgrade instructions.
Try it!
The upgrade instructions are unchanged:
-
Either from binaries: run
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.6.0"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.6.0"
or download manually from the Github "Releases" page to your PATH.
-
Or from source, manually: see the instructions in the README.
You should then run:
opam init --reinit -ni
Note: the following section will recap the various major changes in opam 2.6.0 for anyone who haven't already read the previous pre-release announcements. For those who did, note that nothing changed between 2.6.0~rc1 and the final 2.6.0.
Major change: in-place env hook
For people using the shell hooks, this release changed the way PATH is kept up-to-date. Previously, opam took priority over any other elements of PATH by making sure to always be in front.
However this causes problem for users expecting manual export PATH=some-custom-bindir:$PATH to prioritise their directory.
To resolve this problem, the shell hook now instead replaces the directory managed by opam in-place, keeping the order asked by the user.
To benefit from this, make sure opam init --reinit -ni was ran once after upgrading to this version (automatically done by our install script if it detects an existing opam installation).
Thanks to @gridbugs for this contribution.
Major change: reduce the disk space usage of opam
When installing a package, opam doesn't exactly go easy on disk usage. For people with limited disk space it is a problem which can result in a "no space left on device" type error.
While no-one really can get rid of this type of error completely, this release comes with some quite substential improvements to the disk space used during installs.
In particular the build directory is now deleted as soon as possible during a build instead of waiting until the end.
We also used to cache both the extracted sources and the original archive of packages. However this is redundant and inefficient on some file-systems, thus opam no longer keep the extracted sources when installing the package.
While the disk usage used by opam can be reduced over time while simply reinstalling packages, you can liberate some free GB in one go using opam clean --all-switches.
Major change: performance improvements on certain file-systems (e.g. NTFS on Windows or IO constrained machines)
Some file-systems, such as NTFS on Windows famously take forever for commands such as opam update, opam init or any command upon upgrading opam.
This is due to how opam stored its repositories: i.e. opam-repository is just a large number of directories and files that opam has to scan through to get the informations it needs to run.
Once a repository is read once it's usually not a problem anymore as opam caches it internally, however everytime opam update is called the new repository has to be re-read,
which on platforms such as Windows or a busy VPS causes long delays because the files and directories being read are not in the OS's internal cache anymore.
To remedy this while keeping the same repository format, we now leverage the existing index.tar.gz file expected to be served by HTTP opam repositories and simply don't extract it.
Instead we now use the ocaml-tar library to read the file in-memory, thus only needing one read syscall (against tens of thousands previously, counting on OS-level caches to be fast).
While this only helps HTTP repositories (e.g. the default opam-repository), other types of repositories are usually either smaller (local repositories) or less impacted (VCS repositories) and overall less used
than the default HTTP repository so this is less of an issue. However we will still look into it in the future.
You can enable this mechanism for all non-VCS repositories by setting the environment variable OPAMREPOSITORYTARRING=1, however this is not as efficient as for HTTP, so it may or may not be worth doing depending on your file-system.
Other noteworthy changes
-
Add root and rootexec sections to .install files to install files from the root prefix. Thanks to @WardBrian for this contribution.
-
Reorder the list of actions by increased priority
-
Improved depexts handling by caching system package availability during opam update, avoiding redundant system checks at install time
-
Allow detection of installed system packages through their virtual names on ALT Linux, RHEL-based and SUSE-based distributions
-
Added --ignore-available-on option to allow ignoring the available: field of certain packages. Thanks once-again to @WardBrian for this contribution.
-
Fix an opam 2.5 regression where opam pin list failed abruptly when the source of the pinned package doesn't exist
-
opam update now supports updating a repository that changed a file to a directory of the same name and vice versa
-
Do not fail on directories named opam when scanning the packages directory of a repository during opam repo add or opam init (worked on subsequent opam update)
-
Fix "undefined variable" error when a lock file filter contains an undefined variables: fail gracefully with strict mode, continue and default the variable to false otherwise
-
Fix opam lock support of dependency formula that include disjunctions
-
Fix package installation during opam pin add <url to archive>. Thanks to @zoggy for this contribution.
-
Fix the filename check used when parsing arguments to allow / to be recognised as a directory separator on Windows
-
Make git calls more deterministic regardless of the global or system config
-
Read full lines when asking for user input when TERM=dumb (e.g. emacs' M-x shell). Thanks to @arvidj for this contribution.
-
opam init --reinit now regenerate the list of valid switches, fix switch internal data (cache, config, packages)
-
Safe mode doesn't reset debuglevel to 0 anymore. Consider updating your scripts to discard stderr or add --debug-level=0 if your script isn't resistant to output on stderr
-
To avoid git underlying maintenance operation from interfering with opam (possible race condition), opam now disable git gc/maintenance on repositories it maintains
Various performance and other improvements were made and bugs were fixed.
This release also includes a handful of improvement the documentation and more than two dozen improvement and extensions to our testsuite.
API changes are also denoted in the release notes:
Please report any issues to the bug-tracker.
Happy hacking!
Special thanks to the Haematology department and Bone Marrow Transplant Unit of the NHS Greater Glasgow for making this release possible <3
We have the pleasure of celebrating the birthday of Giovanni Girolamo Saccheri
by announcing the release of OCaml version 5.5.1.
This patch-level release fixes a major type system bug for module-dependent
functions and also contains two security fixes for the runtime: one in the
Marshal module, another inside the loading of bytecode.
At a less severe level, this release also fixes two bugs in the runtime for
concurrent programs, another runtime bug for musl users; and a handful of other
bugs.
The release also restores support for cloning the compiler on macOS.
Overall, we are strongly advising you to switch to OCaml 5.5.1 if you were
already using OCaml 5.5.0.
The full list of changes can be found in the full changelog.
Installation Instructions
The base compiler can be installed as an opam switch with the following
commands:
opam update
opam switch create 5.5.1
The source code for the release is also directly available on:
Fine-Tuned Compiler Configuration
If you want to tweak the configuration of the compiler, you can switch to the
option variant with:
opam update
opam switch create <switch_name> ocaml-variants.5.5.1+options <option_list>
where <option_list> is a space separated list of ocaml-option-* packages.
For instance, for a flambda and no-flat-float-array switch:
opam switch create 5.5.1+flambda+nffa ocaml-variants.5.5.1+options ocaml-option-flambda ocaml-option-no-flat-float-array
See full changelog
Bug fixes
Type system
Runtime
-
14872: harden loading of
bytecode executable files against corrupted or malicious files having 2^29
TOC entries or more. (Xavier Leroy, review by Nicolás Ojeda Bär)
-
15019,
15030,
OSEC-2026-18:
Marshal.from_{string,bytes}: guard against overflow in the computation of
the total data length. (Xavier Leroy, report by Akshay Singh, review by
Nicolás Ojeda Bär and Antonin Décimo)
-
14933: Respect
sysconf(_SC_SIGSTKSZ) when choosing the size for the alternate signal
stack, avoiding fatal errors when linked against musl libc on some Intel
CPUs. (Nat Mote, review by Florian Angeletti and Miod Vallat)
-
14940, fix a memory leak in
the OCaml runtime by bounding the size of the internal cache of stacks.
(Vesa Karvonen, Florian Angeletti, review by Gabriel Scherer)
-
15029: Fix a regression on
Windows where an OCaml thread that never yielded voluntarily would keep the
runtime lock forever, so that the other threads of its domain never ran.
Preemptive switching between systhreads had no effect; only explicit calls
to Thread.yield or blocking sections would let other threads run.
(Nicolás Ojeda Bär, report by Daniel Larraz, review by Antonin Décimo)
Build system
-
14883,
14884: fix Windows
cross-compilation with older mingw32-gcc versions (Brian Ward, review by
Antonin Décimo and Stefan Muenzel)
-
14871,
14914: Ignore
OCAMLTOP_INCLUDE_PATH during the build. (David Allsopp, report by Andreas
Rossberg, review by Florian Angeletti)
-
14901,
14923: Fix the generated
installation script to cope with macOS's geriatric version of bash when
executing in opam's sandbox. (David Allsopp, report by Julian Fondren and
Sacha-Élie Ayoun, investigation and initial fix by Kate Deplaix, review by
Florian Angeletti)
-
14989: Improve build
reproducibility by letting only otherlibs/{str,unix} build their own .cmi
and .cmx. The generic %.cmi/%.cmx rules of the root Makefile were racing
with them under make -j and recorded a different source path, which changed
the interface digest (and, through it, most other compiled artefacts) as
well as the debug info packed into str.a and unix.a. (Bernhard M.
Wiedemann, review by David Allsopp and Stefan Muenzel)
User interface
- 14881,
14882: fix printing of
external types that are subject to module constraints. (Stefan Muenzel,
review by Florian Angeletti)
Runtime events library
-
14966: add the missing
EV_MINOR_EPHE_CLEAN constructor to Runtime_events.runtime_phase, introduced
in 13643. The runtime has
emitted this phase since 5.4, when a minor collection has to clean locked
ephemerons, but the OCaml type had no constructor for it, so consumers were
handed an out-of-range value and crashed when matching on it. (Tim
McGilchrist, review by Florian Angeletti)
-
14969: Fix the units of the
runtime events counter EV_C_MINOR_ALLOCATED_WORDS to report as the number
of words of minor heap consumed, including headers. (Tim McGilchrist,
review by Nicolás Ojeda Bär)
CHANGES:
- Bump OCaml lower bound to 4.11 (#343, @NathanReb)
- Add explicit support for effect syntax (#342, @NathanReb)
- Remove support for legacy camlp4 extensions that was causing misidentation of
code using some predefined identifiers (TEST, BENCH, IFDEF)
(#345, @NathanReb)
- Add support for starred style comments (#347, @NathanReb)
- Add explicit support for labeled tuples syntax (#349, @NathanReb)
- Fix
strict_with so it applies to extensible variant types in the
same way it applies to variant types (#350, @NathanReb)
- Fix a bug where
- would be rejected as ocp-indent input argument
instead of being interpreted as stdin (#351, @NathanReb)
- Update to cmdliner 2 and install completion scripts for common shells
(#351, @NathanReb)
- Add explicit support for external types (#353, @NathanReb)
- Add explicit support for new 5.5 let in constructs:
let type, let external, let class (#354, @NathanReb)
- Add
--strict flag to make warnings fatal and parsing stricter
(#356, @NathanReb)
- Add
--check flag and corresponding check mode which does not print
indented version but instead succeed if the input is already correctly
indented and fails otherwise. (#357, @NathanReb)
- Add
?filename argument to Nstream functions to allow properly
setting the filename for parsing errors. (#357, @NathanReb)
CHANGES:
Fixed
-
Add the implicit unix dependency required by MDX 2.6 and later to
generated MDX test executables (#15592, @avsm)
-
Rescan the RPC registry when its directory mtime changes, allowing clients
that poll before Dune registers to discover the new instance (#15634, fixes
#15630, @rgrinberg)
Revisit generic printing API
CHANGES:
Fri Jul 31 11:31:42 CEST 2026
- merlin library
- occurrences: fix files modified since the index was built never being
reported as out-of-sync. (#2104)
- Fix
locate and document on open paths in .mli files: resolve the
open path in the environment before the open, so a self-shadowing
submodule no longer hides the opened module (fixes #1748)
- Fix occurrences staleness detection when the server is not running at the
project's source root. (#2097)
- Reproduce and fix a load_path staleness issue particularly visible when
using ocaml-lsp and dune in watch mode (#2109)
- Fix bug in
document query (#2092)
- ocaml index
- Fix staleness detection in the presence of ppxes. (#2110)
CHANGES:
- merlin library
- Experimental support for OCaml 5.6
CHANGES:
- Stop testing OCaml < 4.11 and require OCaml >= 4.11 [#209 #210 @rjbou @kit-ty-kate]
- Add support for opam 2.6 by removing indirect calls to
chdir [#204 @kit-ty-kate]
- Use the proper shell quoting mechanism instead of "OCaml quoting" when quoting filenames into the system shell [#204 @kit-ty-kate]
CHANGES:
Added
- If a test takes longer than 5 seconds, display a warning with the test's location
Also display the location on Ctrl-C (#476, @talex5 @avsm).
- Support oxcaml-5.2.0-minus39 alongside normal OCaml (#481, @avsm)
Changed
- Mark the tests as conflicting with dune 3.24.0 due to a bug in
that release; see ocaml/dune#14724 (@avsm)
The Dune team is pleased to announce the release of dune
3.24.1.
This patch release includes bug fixes and a change to Melange sandboxing
defaults. See the full
changelog for all the
changes and for attribution to the contributors who made it all possible.
Thank you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
See full changelog
Fixed
- Fix an internal error (
modules_and_obj_dir: failed lookup) when generating
js_of_ocaml archive rules for a dune file that defines two libraries with
the same name distinguished by mutually exclusive enabled_if clauses, as
ocaml-re does for ppx_expect_common (#14904, fixes #14775, @vouillon)
- Fix passing environment variables to formatter actions (#15386,
@anmonteiro)
- Fix missing source dependency in the sandbox when preprocessing Melange
sources (#15395, @anmonteiro)
- Treat OCaml compiler packages version 5.5 or newer as relocatable so their
installations do not use the toolchain cache (#15444, fixes #15443,
@Alizter)
- Fix
build_runtime_flags given in a js_of_ocaml/wasm_of_ocaml field of
an executable being silently ignored in separate compilation mode: such
executables were given the workspace-shared standalone runtime, which is
built with the default flags. Executables customizing build_runtime_flags
now get their own standalone runtime again. (#15455, @hhugo)
- Use installed filenames for local package binaries in
%{bin:...} PATH
layouts on Windows (#15518, fixes #15512, @Alizter)
Changed
- Revert sandboxing Melange rules by default in the
(library ..) and
(melange.emit ..) stanzas. In Melange libraries with many modules,
sandbox creation / destruction dominates build time and adds significant
overhead to build time (#15418, @anmonteiro)
Feedback on this post is welcomed on Discuss!
We are pleased to announce the release of opam 2.5.2 fixing a security issue (OSEC-2026-10) and other minor things.
We advise everyone to upgrade. Please read on for installation and upgrade instructions.
Security fix
- OSEC-2026-10 / CVE-2026-57825: Fix a bug that allowed a package to install files anywhere on the system using a symlink to an external directory without warning the user and asking for their permission (#7005)
Distributions maintainers that have not already done so, are invited to either upgrade their opam package to 2.5.2 or backport the fix. For any questions please send an email to the authors of this here blog post as listed above.
Other changes
Try it!
The upgrade instructions are unchanged:
-
Either from binaries: run
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.5.2"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.5.2"
or download manually from the Github "Releases" page to your PATH.
-
Or from source, manually: see the instructions in the README.
You should then run:
opam init --reinit -ni
Please report any issues to the bug-tracker.
Happy hacking!
The Dune team is pleased to announce the release of dune
3.24.0.
Highlights include the following
- Dune package management now uses the relocatable compiler by default, for all
supported compiler versions. This brings a massive speedup to workspace setup
in the many cases where built compiler versions can be reused.
(ocaml/dune#14357,
@Alizter)
- Directory targets are now generally available
(ocaml/dune#14579), allowing tools
to produce entire directory trees as targets. See the documentation on
directory
targets
for details.
- Path handling has been refined, improving the consistency of paths across
platforms (ocaml/dune#14278 and
ocaml/dune#14278) and using a more
consistent and disciplined location for
%{bin:NAME} variable expansions
(ocaml/dune#14432).
- Path-valued percent forms (
%{bin:...}, %{dep:...}, %{path:...}, and
friends) now expand same-directory paths with a leading ./, so that shells
like bash in (bash ...) and (system ...) actions execute them directly
instead of looking them up in PATH
(ocaml/dune#15156). This is a
breaking change for configurations that were handling paths naively, and
neglected to normalize the representation before using it test fixtures or for
constructing other strings.
- The deprecated
lang coq has been removed, as scheduled, superseded by lang rocq. See ocaml/dune#12788 for
details.
See the full changelog
for all new features and fixes, and for attribution to the contributors who made
it all possible. Thank you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
See full changelog
Fixed
- Fix promotion failure when a target changes from a directory to a file
between builds, causing "Is a directory" errors.
(#14371, fixes #5647, fixes #6575, @Alizter)
- Make
dune build @doc pick up an odoc installed via dune tools install odoc even without DUNE_CONFIG__LOCK_DEV_TOOL=enabled, mirroring how
dune fmt consumes a locked ocamlformat (#14426, fixes #14235, @mt-caret)
- Reject
(package ...) inside a named dependency binding
((deps (:name (package foo)))). Previously this was silently accepted but
%{name} would resolve to an empty path list. (#14499, @Alizter)
- Fix incorrect dependency in the
.cmxs build for libraries with
mode-dependent foreign stubs: the rule depended on the byte stubs archive
instead of the native one, so parallel builds could fail to find
-l<lib>_stubs_native. (#14500, fixes #12964, @Alizter)
- Fix
dune build failing with "No rule found" when lock_dir paths in
dune-workspace contain a subdirectory (e.g. (path sub/dune.lock)).
(#14524, fixes #14523, @Alizter)
- Artifact substitution repairs executable bit if it's not set correctly in the workspace
(#14556, @rgrinberg)
- Ignore
EINVAL when accepting sockets on MacOS (#14612, fixes #12660, @rgrinberg)
- Validate profile names. Profile names must be non-empty and can only contain
letters, digits,
_ and -. The name _ is reserved as a wildcard in
(env ...) stanzas. (#14657, fixes #14630, @rlepigre)
Added
- Add
%{pkg:<package>:<section>:<path>} pform for resolving package install
files. Works with workspace packages, lock-file packages, and installed
packages. (#14200, fixes #14193, fixes #3378, @Alizter)
- Enable the relocatable compiler by default for package management (#14357,
fixes #14012, @Alizter)
- Add changed source files to the
build-start trace event for watch-mode
restarts, showing the paths that triggered the rebuild (#14396, @rgrinberg)
- Add dune's rusage information in start/finish build trace events (#14402, @rgrinberg)
- Add a status message for RPC clients that manage to connect (#14424, @rgrinberg)
- Allow blang expressions in the
runtest_alias field in the cram stanza (#14425, @rgrinberg)
- Extend the stat based cache to cache the contents of directories and not just
source files (#14469, @rgrinberg).
- Show the number of connected RPC clients in the watch mode status line
(#14489, @rgrinberg)
- Promote directory targets from experimental to generally available in 3.24
(#14579, @rgrinberg)
Changed
- Use
/ as directory separator when appending local paths to external paths,
making path construction consistent across platforms. (#14278, @Alizter)
- On Windows, normalise process paths to
\ before passing them to
CreateProcessW so that programs which scan argv[0] (notably cmd.exe)
do not misparse mixed separators. (#14278, @Alizter)
%{bin:NAME} now resolves to the build artifact path rather than
the install staging path. Rules with %{bin:NAME} deps additionally
get a per-rule .binaries directory prepended to the action's
PATH, containing correctly-named symlinks for each declared bin
pform dep. (#14432, fixes #3324, @Alizter)
- Replace the Rocq language field
(stdlib ...) with the presence-only field
(no_corelib) in Rocq language 0.14. (#14452, fixes #14358, @Durbatuluk1701)
- Throttle sandbox creation to 250 concurrent sandboxes. (#14464, @rgrinberg)
- The package solver now uses cached revision store lookups for improved
performance. (#14494, fixes #12637, @Alizter, @rgrinberg)
- Remove the deprecated
(lang coq) Coq Build Language. Use the
Rocq Build Language ((using rocq <version>)) instead. Projects that
still declare (using coq <version>) now get an error pointing them
at Rocq. (#14525, fixes #12788, @Alizter)
- Path-valued pforms (
%{bin:...}, %{dep:...}, %{path:...}, and
friends) now expand same-directory paths with a leading ./, so that
shells like bash in (bash ...) and (system ...) actions execute
them directly instead of looking them up in PATH.
(#15156, fixes #15147, @Alizter)
CHANGES:
Features
- Upgrade to OCaml 5.5 (#1609)
Fixes
- Fix compatibility with upcoming Dune versions by avoiding the
Stdune.Pid
module. (#1608)
CHANGES:
Tue Jun 23 12:15:42 CEST 2026
- merlin library
- Support for OCaml 5.5 (#2077, fixes #2024)
- Fix signature-help with type aliases (#2067, fixes #1927)
- Fix locate on punned let bindings, to use the common identifier as the
expression (instead of the pattern) (#2066)
- test suite
- Remove the FIXME line for #1404 as the issue was already fixed and add two tests (#2073).
We have the pleasure of celebrating the birthday of Blaise Pascal by announcing the release of OCaml version 5.5.0.
Release Highlights
Some of the highlights of OCaml 5.5.0 are:
Module-dependent Functions
Modules can now be used as function arguments in a form of lightweight functors.
For instance, we can define a function for printing a map generated by
the Map.Make functor:
let pp_map (module M: Map.S) pp_key pp_v ppf set =
if M.is_empty set then
Format.fprintf ppf "ø"
else
let pp_sep ppf () = Format.fprintf ppf ",@ " in
let pp_binding ppf (k,v) =
Format.fprintf ppf "@[%a@ =@ %a@]" pp_key k pp_v v
in
Format.fprintf ppf "@[{@ %a@ }@]"
(Format.pp_print_seq ~pp_sep pp_binding) (M.to_seq set)
We can then apply this function on a string map
module String_map = Map.Make(String)
with
let () =
let m = String_map.of_list ["Zero", "Zero"; "One", "Un"] in
let pp_str = Format.pp_print_string in
Format.printf "%a@."
(pp_map (module String_map) pp_str pp_str) m
Compared to first-class modules, the type of the function pp_map
type 'a printer = Format.formatter -> 'a -> unit
val pp_map: (module M: Map.S) -> M.key printer -> 'a printer -> 'a M.t printer
is dependent over the value of the module S, and thus the function can only
applied over a statically known module:
let f (): (module Map.S) =
if Random.bool () then
(module Map.Make(Int))
else
(module Map.Make(Float))
let fail = pp_map (f ())
Error: This expression has type
(module M : Map.S) ->
(Format.formatter -> M.key -> unit) ->
(Format.formatter -> 'a -> unit) -> Format.formatter -> 'a M.t -> unit
but an expression was expected of type (module Map.S) -> 'b
The module M would escape its scope
This function is module-dependent. The dependency is preserved
when the function is passed a static module argument (module M : S)
or (module M). Its argument here is not static, so the type-checker
tried instead to change the function type to be non-dependent.
Relocatable Compiler
A compiler installation can now be moved or copied with no risk
of hard-to-debug errors due to mixing incompatible bytecode runtime interpreters.
In practice, this means that creating a local switch when there is a
global switch with the same compiler version and configuration
available can be done by cloning the global switch rather than
recompiling the whole compiler.
This should considerably reduce the time required to create
new local opam switches out-of-the-box.
Polymorphic Functions as Function Arguments
Higher-rank polymorphic functions can now be defined directly by
using an explicit type annotation in a function argument
let apply_map (map: 'a 'b. ('a -> 'b) -> 'a list -> 'b list) =
map string_of_int [1;2;3], map List.singleton ["x"; "y"]
let _ = apply_map List.map
Previously defining such a function required going through either a record or an object
with a polymorphic field or methods
type map = { map: 'a 'b. ('a -> 'b) -> 'a list -> 'b list }
let apply_map {map} =
map string_of_int [1;2;3], map List.singleton ["x"; "y"]
Search and Replace Substring Functions
The String module has been extended with many functions
for searching and replacing substrings inside a string.
let _true = String.includes ~affix:"aba" "abbaba"
let sentence = String.replace_all ~sub:"𝄽" ~by:"word" "A 𝄽 is re𝄽ed"
The substring search is using the 2-way string matching algorithm
which has the advantage of requiring constant space memory overhead
independently of the needle size.
Generalised Local Definitions
It is now always possible to define locally a type,
a class, a module type or any kind of item that can be defined
globally:
let mandelbrot n x =
let type t = Converge | Escape of int in
...
match orbit n x with
| Converge -> 0
| Exit_at n -> colorize n
External Types
When interfacing with foreign function libraries, it is now possible
to define external type
type int_gmp = external "mpz_t"
type float_gmp = external "mpf_t"
Compared to an abstract type definition, the external type name
"mpz_t" (resp. mpf_t) makes the type distinguishable from any
non-abstract types or external types with a different name.
In particular, this makes FFI types better behaved when combined with
Generalised Abstract Data Types (GADTs). For instance, The typechecker
is able to prove that
let ok: (int_gmp,[` A] ) Type.eq -> _ = function _ -> .
is a total function because the external type int_gmp is not compatible
with a polymorphic variant type.
Warning: Abstract types in the current module
The astute reader has probably noticed in the definition above that,
in OCaml 5.4.0, the typechecker does accept
type int_gmp
let ok: (int_gmp, [` A] ) Type.eq -> _ = function _ -> .
as total.
Indeed until OCaml 5.5.0, abstract types defined in the current module
type a
type b
were considered as unique and provably different
let f: 'x. (a,b) Type.eq -> 'x = function _ -> .
However, this special rule for local definition of abstract types was
very brittle. As soon as one moved outside of the current module, it
was no longer possible to prove that the types were different.
module M = struct
type a
type b
end
let fail: 'x. (M.a,M.b) Type.eq -> 'x = function _ -> .
Error: This match case could not be refuted.
Here is an example of a value that would reach it: Equal
This special typechecking rule has been removed in OCaml 5.5.0. If you were relying on it,
for instance, because you used an abstract type as type-level label in a GADTs, you
can change your abstract type definition to a possibly private abbreviation of a polymorphic variant
type a = private [`A]
type b = [`B]
or a (possibly private) sum type
type a = A
type b = private B
If you were using an abstract type as both a type-level label and a FFI type, you
can now use an external type definition which will give you a provably distinct type
even outside of the current module.
GC improvements
Some of the ongoing work to improve the pacing of the garbage
collector has been integrated in OCaml 5.5.0, two of the important
changes in OCaml 5.5 GC are
- the addition of a sweep-only phase at the start of major GC
- the addition of an idle phase to smooth the behaviour of the GC
at the start.
Many incremental changes
- The Windows implementation is no more reliant on Winpthreads
- Around 60 new standard library functions
- Around 90 various improvements
- A dozen of documentation updates
- Around 40 bug fixes
Please report any unexpected behaviours on the OCaml issue
tracker and post any questions or
comments you might have on our discussion forums.
The full list of changes can be found in the full changelog.
Installation Instructions
The base compiler can be installed as an opam switch with the following commands:
opam update
opam switch create 5.5.0
The source code for the release is also directly available on:
Fine-Tuned Compiler Configuration
If you want to tweak the configuration of the compiler, you can switch to the option variant with:
opam update
opam switch create <switch_name> ocaml-variants.5.5.0+options <option_list>
where <option_list> is a space separated list of ocaml-option-* packages. For instance, for a flambda and no-flat-float-array switch:
opam switch create 5.5.0+flambda+nffa ocaml-variants.5.5.0+options ocaml-option-flambda ocaml-option-no-flat-float-array
See full changelog
Language features:
- (breaking change) #13681, #13682, #13683, #13684, #13275 :
Introduce a new type
(module M : S) -> t[M] that corresponds to
module-dependent functions (also called: modular explicits).
val mapM: (module M : Monad) (f : 'a -> 'b M.t) : 'a list -> 'b list M.t
(Samuel Vivien review by Leo White, Gabriel Scherer, Florian Angeletti,
Jacques Garrigue and Stephen Dolan)
-
#14040: generalize the constructs let module, let exception and let open
to most other structure items, for example:
let type t = ... in ...
let type Effect.t += Yield in ...
(Nicolás Ojeda Bär, review by Valentin Gatien-Baron)
-
#13806: Enable the use of function parameters with polymorphic types.
let extract (getter : 'a . 'a t -> 'a) = ...
let runST (m : 's . ('s, 'a) ST.t) : 'a = ...
(Ulysse Gérard, Leo White, review by Florian Angeletti, Samuel Vivien, Gabriel
Scherer and Jacques Garrigue)
-
(breaking change) #13712: Introduce a new kind Type_external and syntax
type t = external "name" to discriminate external types from other types
and each other. This PR turns primitive types into external and removes the
past behavior of discriminating abstract types defined in the current module.
(Takafumi Saikawa, Jacques Garrigue, review by Richard Eisenberg)
-
(breaking change) #14009: infix extension points/attributes appearing in local structure items,
eg let module%foo[@bar] ... in ... are attached to the AST node of the
corresponding structure item (similar to their global counterparts) and no
longer to the enclosing let expression. Extension points/attributes that
are to be attached to the enclosing let expression are to be written next to
the let keyword, eg let%foo[@bar] module ... in .... The same holds for
let exception and let open.
(Nicolás Ojeda Bär, review by Gabriel Scherer)
- #14029: Recognize
%identity as nonexpansive
(Stephen Dolan and Olivier Nicole, review by Hugo Heuzard, Jacques Garrigue,
Jeremy Yallop, and Gabriel Scherer)
Standard library:
-
#13372: New Format and Printf printf-like functions that accept a
heterogeneous list as arguments.
Format.lprintf "@[%s@ %d@]@." [ "x ="; 1 ]
(Leonardo Santos, review by Florian Angeletti and Gabriel Scherer)
-
#14437: Add String.split_{first,last,all} and String.rsplit_all
split_first: sep:string -> string -> (string * string) option
split_all: sep:string -> drop:(string -> bool) -> string -> string list
(Daniel Bünzli, review by Nicolás Ojeda Bär and Florian Angeletti)
-
#14436: Add String.replace_{first,last,all}
replace_first: sub:string -> by:string -> ?start:int -> string -> string
(Daniel Bünzli, review by Nicolás Ojeda Bär, Ali Caglayan and
Florian Angeletti)
-
#14439: Add String.includes, to complete the trio:
starts_with: prefix:string -> string -> bool
ends_with: suffix:string -> string -> bool
includes: affix:string -> string -> bool
(Daniel Bünzli, review by Nicolás Ojeda Bär and Olivier Nicole)
-
#14381: Add String.find_{first,last}index, String.find{first,last},
String.[r]find_all.
find_first_index: (char -> bool) -> ?start:int -> string -> int option
(Daniel Bünzli, review by Nicolás Ojeda Bär, Ali Caglayan and
Florian Angeletti)
-
#14438: Add String.is_empty
(Daniel Bünzli, review by Nicolás Ojeda Bär and Gabriel Scherer)
-
#14440: Add String.of_char
(Daniel Bünzli, review by Nicolás Ojeda Bär and Gabriel Scherer)
-
#14352: Add String.{drop,take,cut}_{first,last}.
take_first: int -> string -> string
cut_first: int -> string -> string * string
(Daniel Bünzli, review by David Allsopp, Nicolás Ojeda Bär and
Vincent Laviron)
-
#14362: Add String.{drop,take,cut}_{first,last}_while
drop_first_while: (char -> bool) -> string -> string
(Daniel Bünzli, review by Nicolás Ojeda Bär and David Allsopp)
-
#13916: Add Option.product and Option.Syntax.
(Nicolás Ojeda Bär, review by Daniel Bünzli, Gabriel Scherer and David
Allsopp)
-
#13995: Option.blend: ('a -> 'a -> 'a) -> 'a option -> 'a option -> 'a option
(Kate Deplaix, review by Daniel Bünzli, Gabriel Scherer,
Nicolás Ojeda Bär, Florian Angeletti and Josh Berdine)
-
#13920: add Option.{for_all, exists}
(Gabriel Scherer, review by Kate Deplaix, Nicolás Ojeda Bär, Richard Eisenberg
and Jeremy Yallop)
-
#14185: List.split_map: ('a -> 'b * 'c) -> 'a list -> 'b list * 'c list
(Jeremy Yallop, review by Daniel Bünzli, Nicolás Ojeda Bär and Damien Doligez)
-
#14043, #14393: Lazy.Mutexed: simple mutex-protected lazy thunks,
that may block the entire domain/thread on initialization races.
(Gabriel Scherer, suggestion by Kate Deplaix and Pierre Chambart,
review by KC Sivaramakrishnan, Florian Angeletti, Kate Deplaix
and Daniel Bünzli)
-
#14118: Add {Set,Map}.S.is_singleton
(Kate Deplaix, review by Daniel Bünzli, Vincent Laviron, Nicolás Ojeda Bär
and Stephen Dolan)
-
#14060: Add Hashtbl.find_and_replace and Hashtbl.find_and_remove.
find_and_replace: ('k, 'a) Hashtbl.t -> 'k -> 'a -> 'a option
find_and_remove: ('k, 'a) Hashtbl.t -> 'k -> 'a option
(Sacha-Élie Ayoun, review by Nicolás Ojeda Bär and Gabriel Scherer)
-
#14227: Add List.filter_mapi.
(Émile Trotignon, review by Nicolás Ojeda Bär, Jan Midtgaard and
Damien Doligez)
-
#14432: Add floor division, ceil division, Euclidean division and remainder
to the Int, Int32, Int64 and Nativeint modules: fdiv, cdiv, ediv.
(Xavier Leroy, review by Ali Caglayan, Nicolás Ojeda Bär, Gabriel Scherer)
-
#14433: Add bit-counting functions leading_zeros, leading_sign_bits,
trailing_zeros, bit_count, unsigned_bitsize, signed_bitsize
to Int, Int32, Int64, and Nativeint
(Xavier Leroy, review by Ali Caglayan and David Allsopp)
-
#10177: Seq.(delay : (unit -> 'a t) -> 'a t)
(Gabriel Scherer, review by Jeremy Yallop and François Pottier)
-
#13343: Add Array.stable_sort_sub
(François Pottier, review by Gabriel Scherer, Corentin Leruth and Nicolás
Ojeda Bär)
-
#14363: Preserve the backtrace at exceptional domain termination. Domain.join
on an exceptionally terminated domain re-raises the exception with the
backtrace.
(KC Sivaramakrishnan, report by Nathan Taylor, review by Gabriel Scherer,
David Allsopp)
-
#13728: Add Sys.runtime_executable containing the full path (if available) to
the currently executing runtime.
(David Allsopp, review by Nicolás Ojeda Bär and Daniel Bünzli)
-
#14086: Add Domain.count.
(Nicolás Ojeda Bär, review by David Allsopp, Gabriel Scherer, Daniel Bünzli
and KC Sivaramakrishnan)
-
#12877: Dynarray.rev_iter, Dynarray.rev_iteri
(Gabriel Scherer, review by Léo Andrès, Jeremy Yallop and Nicolás Ojeda Bär)
-
#14084: Future-proof Dynarray implementation against a smarter compiler
(Basile Clément, review by Gabriel Scherer)
Tools:
-
#13728, #14014, #14243, #14244, #14245 : The compiler is now relocatable: it
can be copied/moved to a different directory and everything still
works.
(David Allsopp, review by Nicolás Ojeda Bär, Jonah Beckford, Daniel Bünzli,
Antonin Décimo, Damien Doligez, Hugo Heuzard, Samuel Hym,
and Vincent Laviron)
-
#14055: Invert BUILD_PATH_PREFIX_MAP in directories loaded at startup
by the debugger.
(Pierre Boutillier, review by Gabriel Scherer and Daniel Bünzli)
- (breaking change) #13638: ocamlmklib exits with code 4 if passed an unrecognised option, as it
does with an unrecognised file.
(David Allsopp, review by Antonin Décimo and Sébastien Hinderer)
-
#13941, #13961: Fix ocamltest variable handing.
(Damien Doligez, report by Olivier Nicole, review by Gabriel Scherer)
-
#13962: Little ocamltest refactors. Fix error handling in C code,
leaking file descriptors, code style.
(Antonin Décimo, review by Gabriel Scherer)
-
#14059: Fix flaky TSan tests
(Fabrice Buoro and Olivier Nicole, review by Gabriel Scherer)
-
#13966, #13969: Enable "generalized polymorphic #install_printer"
in the debugger
(Pierre Boutillier and Gabriel Scherer, review by Florian Angeletti)
-
#14063 : Debugger fallbacks to "looking for 'module_name'.ml in the
loadpath" when seeking source files. It improves hit rate for
sources of installed packages.
(Pierre Boutillier, review by Gabriel Scherer)
-
#14032, #14034: Update to and require FlexDLL 0.44.
(Jan Midtgaard, Antonin Décimo, review by David Allsopp)
-
#14239: Fix #show_constructor when printing non-GADT type parameters
(Takafumi Saikawa, Jacques Garrigue, review by Gabriel Scherer)
-
#14245: ocamlobjinfo now displays the runtime invoked by a bytecode
executable (either from the RNTM section or by analysing the shebang lines)
(David Allsopp, review by Damien Doligez and Samuel Hym)
Runtime system:
-
#14365: Add an Idle phase to the GC for better performance on small
heaps and for a smooth start at program launch and after a forced major GC.
(Damien Doligez, review by Stephen Dolan and Nick Barnes)
-
#13416: Implement concurrency primitives using WinAPI instead of
winpthreads on Windows.
(Antonin Décimo, review by Samuel Hym, Gabriel Scherer, Miod Vallat,
B. Szilvasy, and Nicolás Ojeda Bär)
-
#14367: Gc.Tweak mechanism to allow named GC parameters
(Stephen Dolan and Nick Barnes, review by Gabriel Scherer, David Allsopp and
Antonin Décimo)
-
#13574, #13594: Generational scanning of stack frames for ARM 64 bits, POWER,
and RISC-V. This reduces minor GC work in the presence of deep call stacks.
(Xavier Leroy, review by Miod Vallat, Gabriel Scherer and Olivier Nicole)
-
#14416: Spawned domains will record backtraces if the parent domain has
enabled it.
(Nathan Taylor, review by Gabriel Scherer)
-
#14275: Add function caml_c_thread_register_in_domain, which makes it
possible to register "C threads" in another domain than 0 (which is
what caml_c_thread_register does). The function takes a domain unique
ID in which to register the thread. The domain must be running
when the function is called.
(Jack Nørskov Jørgensen, review by Gabriel Scherer,
Guillaume Munch-Maccagnoni)
-
#13616: Change free list representation in shared heap
(Sadiq Jaffer, review by Damien Doligez)
-
#13580: Introduce sweep-only phase at start of major GC cycle,
to reduce latent-garbage delay and therefore improve GC performance.
(Stephen Dolan and Nick Barnes, review by KC Sivaramakrishnan)
-
#14053: Statmemprof: it is now possible to replace a profile in the
current domain without stopping it in all domains.
Added the function [Gc.Memprof.is_sampling].
(Guillaume Munch-Maccagnoni, review by Gabriel Scherer)
-
#14168: restore the stack size statistic in Gc.stat and adds a new
live_stacks_words field tracking the total size in words of live stacks.
(Florian Angeletti, review by Gabriel Scherer)
-
#14189: Add runtime counters EV_C_MINOR_PROMOTED_WORDS and
EV_C_MINOR_ALLOCATED_WORDS. EV_C_MINOR_PROMOTED_WORDS reports words promoted
by minor GC and EV_C_MINOR_ALLOCATED_WORDS reports words allocated by minor
GC. Both have equivalent bytes counters. Also updated the documentation for
EV_C_MINOR_PROMOTED and EV_C_MINOR_ALLOCATED to qualify scope of the values
reported as being per-domain.
(Tim McGilchrist, review by Nick Barnes, Sadiq Jaffer and
Gabriel Scherer)
- (breaking change) #14243: Explicit relative paths in ld.conf (".", "..", "./<path...>",
"../<path...>") are interpreted as being relative to the directory ld.conf
was loaded from, and the default ld.conf now uses relative paths, rather than
embedding the absolute path to the Standard Library. The brave may continue to
put implicit paths in ld.conf. The interpretation of CAML_LD_LIBRARY_PATH is
unaltered. Additionally, ld.conf is loaded from all of $OCAMLLIB/ld.conf,
$CAMLLIB/ld.conf and standard_library_default/ld.conf rather than just the
first one found. ld.conf files with CRLF line endings are now consistently
normalised on both Windows and Unix.
(David Allsopp, review by Jonah Beckford, Damien Doligez and Hugo Heuzard)
-
#14244: Added --with-relative-libdir which allows the runtime and the
compilers to locate the Standard Library relative to where the binaries
themselves are installed, removing the absolute path previously embedded in
caml_standard_library_default. Executables linked with ocamlc -custom now
always attempt to load bytecode from the executable itself, rather than first
trying argv[0].
(David Allsopp, review by Jonah Beckford, Antonin Décimo, Damien Doligez,
Samuel Hym and Vincent Laviron)
-
#14245: Introduce Runtime IDs for use in filename mangling to allow different
configurations and different versions of the runtime system to coexist
harmoniously on a single system. The IDs are used, along with the host
triplet, to provide mangled names for the ocamlrun executable and its variants
and the DLL versions of both the bytecode and native runtimes, with symlinks
created for the original names. They are also used to mangle the names of stub
libraries so that stub libraries compiled for a given configuration of the
runtime will only be sought by that runtime. The behaviour is disabled by
configuring with --disable-suffixing.
(David Allsopp, review by Damien Doligez and Samuel Hym)
-
#12269, #12410, #13063: Fix unsafety, deadlocks, and/or leaks should
rare errors happen during domain creation and thread
creation/registration.
(Guillaume Munch-Maccagnoni, review by Gabriel Scherer, B. Szilvasy,
Miod Vallat)
-
#14337: Fix potential segfault due to the C callback mechanism dropping
continuations without calling caml_continuation_use.
(Max Slater, review by Nick Barnes and Stephen Dolan)
-
#14461: Fix racy socketpair on Windows. Address-in-use errors would sometimes
occur when concurrent threads or processes were trying to create socketpairs.
(Jessie Grosen, review by Antonin Décimo and Nicolás Ojeda Bär)
-
#14820: caml_ba_alloc must account for memory it allocated itself.
CAML_BA_SUBARRAY (introduced in 5.2) with data=NULL would result in the
Gc accounting for the allocation as 0 bytes, which can eventually lead
to OOM. This condition never occurs in the compiler itself, but occurs
in external C bindings that attempt to create a new bigarray in the
shape of an existing one. For backwards compatibility ignore CAML_BA_SUBARRAY
when data is NULL.
(Edwin Török, review by Damien Doligez)
Type system:
- #13781: Set scope of internal type nodes during abbreviation expansion
rather than recursing during unification.
(Jacques Garrigue, review by Gabriel Scherer)
-
(breaking change) #14066: catch invalid aliases introduced by signature constraints during
merging rather than in subtyping:
module X = struct end module F (_:sig end) = struct end
module type T = (sig module X0 : sig end module X1 = X0 end)
with module X0 := F(X)
Before, it failed with a subtyping error. Now, it fails with a proper error,
explaining that X1 would keep an invalid alias to F(X)
(Clement Blaudeau, review by Florian Angeletti)
-
(breaking change) #14100: Do not ignore type-constraints and module-constraints when building
the approximated signature of recursive modules. Ignoring those constraints
resulted in incorrect (wrong set of fields, wrong shadowing between fields)
approximated signatures, failing to typecheck, as in:
module X0 : sig type t end
module rec X : ((sig module A : sig end end) with module A := X0)
and Y : sig type t = X.A.t end (* Unbound type constructor X.A.t *)
Now, type and module constraints are properly merged during approximation ,
reusing the infrastructure for normal merging of constraints, but disabling
any wellformedness check.
(Clement Blaudeau and Ryan Tjoa, review by Florian Angeletti)
-
#14327: Allow retyping as-patterns that contain existentials
(completing #14229)
(Jacques Garrigue and Takafumi Saikawa, reported by Olivier Nicole,
review by Gabriel Scherer)
-
#14434, #14652: Protect check_counter_example_pat against polymorphic types,
restoring type soundness.
(Stephen Dolan and Jacques Garrigue, report and review by Alistair O'Brien)
Compiler user-interface and warnings:
-
#14330: add suggestions when a signature mismatch is likely to be be caused by
spellchecking mistakes, for instance
module M: sig type albatross end = struct type albatros end
(Malo Monin, Florian Angeletti, review by Gabriel Scherer)
-
#12628: Improved error message for unsafe values: print out the full path for
the value that is unsafe when they are detected during the compilation of
recursive modules.
(Shivam Acharya, review by Gabriel Scherer and Florian Angeletti)
-
#14076, 14111: error messages, add a short explanation for mismatched
universal variables and universal quantifications.
(Florian Angeletti, review by Gabriel Scherer)
-
#14126: Document the -i-variance option and +-, -+ variance indicators
in the reference manual.
(Takafumi Saikawa, review by Florian Angeletti)
-
#14146: add an error message for external declaration with
a non-syntactic arity
external fail: (int -> int as 'a) -> 'a = "%identity"
rather than failing with an internal error.
(Florian Angeletti, review by Gabriel Scherer)
-
#14147: print row types in error messages when they are a type constructor,
e.g. < foo : int; .. as $0> when $0 is introduced by a GADT constructor
(Stefan Muenzel, review by Jacques Garrigue and Florian Angeletti)
-
#14190: ocaml -e now also processes -init (previously it was ignored).
(Emile Trotignon, review by David Allsopp and @ygrek)
-
#14225: do not raise unused-constructor warning on private
constructor in type implementations, for example
type safe = private Safe, which are typically used to
create new fresh/generative types (here safe) to be used
as GADT indices.
(Gabriel Scherer, review by Nicolás Ojeda Bär and Florian Angeletti,
report by Kate Deplaix)
-
#14244: Add -set-runtime-default option to the compiler, allowing the default
value of the Standard Library location used by the runtime to be overridden.
(Antonin Décimo, review by David Allsopp, Jonah Beckford, Damien Doligez and
Samuel Hym)
-
#14245: New option -launch-method for ocamlc allows the method used by a
tendered bytecode executable to locate the interpreter to be given explicitly.
In particular, it makes it easier to specify the use of the executable
launcher on Unix. New option -runtime-search extends the bytecode executable
header to be able to search for the runtime interpreter in the directory
containing the executable and in PATH rather than relying on a single
hard-coded path.
(David Allsopp, review by Damien Doligez and Samuel Hym)
-
#14315: enable -i-variance also for classes and extension constructors,
and add description of -i-variance in manpages and the manual
(Takafumi Saikawa, review by Florian Angeletti and Jacques Garrigue)
-
#14373: remove the OCAML_BINANNOT_WITHENV environment variable, and
always strip typing environment in cmt files
(Florian Angeletti, review by David Allsopp)
Other libraries:
-
#13700, #14454, #14715: Use POSIX thread-safe getgrnam_r, getgrgid_r,
getpwnam_r, getpwuid_r, gmtime_r, localtime_r, getlogin_r, and fix mktime
error checking.
(Antonin Décimo, review by Florian Angeletti, David Allsopp, Stefan Muenzel,
Gabriel Scherer, and Miod Vallat)
-
#14406: Better handling of address length for unix sockets, improving Haiku
compatibility.
(Sylvain Kerjean, review by Antonin Décimo and Nicolás Ojeda Bär)
- (breaking change) #14046: On Windows,
Unix.kill pid Sys.sigkill causes the receiving process
to exit with code ERROR_PROCESS_ABORTED (1067) instead of 0.
(Nicolás Ojeda Bär, review by Miod Vallat, Antonin Décimo and David Allsopp)
-
#14020: Add Unix.unsetenv.
(Nicolás Ojeda Bär, review by Antonin Décimo and David Allsopp)
-
#13447: Symmetrize shared Sys and Unix functions. Apply fixes
of #12072, #12184, #12320, and #13166, from Sys.rename to
Unix.rename. Make caml_sys_close raise on error, allowing
Filename.temp_file retries if close fails. Flush buffers when
calling caml_sys_system_command on Windows. Error with EINVAL
instead of ENOENT if the command string is not a valid C string.
(Antonin Décimo, review by Gabriel Scherer and Nicolás Ojeda Bär)
-
#14310: Deprecate union sock_addr_union for struct sockaddr_storage
and socklen_param_type for socklen_t.
(Antonin Décimo, review by Nicolás Ojeda Bär, David Allsopp and Samuel Hym)
-
#14391: unload native dynlinked objects when an error occurs and it is safe to
do so. (Fixes #14323)
(Nicolás Ojeda Bär, review by Vincent Laviron)
Code generation and optimizations:
- #14583: fix bug in linear scan spilling heuristic that in certain situations
could lead to miscompilations.
(Nicolás Ojeda Bär, review by Vincent Laviron)
Manual and documentation:
-
#14684, #14782, #14838: Improve ocamlc's and ocamlopt's manual pages and fix
small issues in the manual
(Samuel Hym, review by Florian Angeletti, Antonin Décimo, Gabriel Scherer and
Nicolás Ojeda Bär)
-
#14397: Improve documentation of type-directed disambiguation of array
literals
(Alicia Michael, review by Olivier Nicole and Florian Angeletti)
-
#14293: Improve documentation of Runtime_events.Timestamp
(Raphaël Proust, review by Gabriel Scherer)
-
#13747: Document support for native debugging with GDB and LLDB.
(Tim McGilchrist, review by Daniel Bünzli, Samuel Hym, Olivier Nicole
and Antonin Décimo)
- (breaking change) #13975: documented the
[@remove_aliases] built-in attribute for signatures
(introduced by #1652 in 2018). Small refactor of the code that fetches the
attribute.
(Clement Blaudeau, review by Gabriel Scherer)
-
#14002: Add anchors to items and headings of the web version of the API
documentation for easier linking.
(Nicolás Ojeda Bär, report by Louis Roché, review by Gabriel Scherer and
Florian Angeletti)
-
#14023: Add documentation for the [row_more] function.
(Richard Eisenberg, review by Jacques Garrigue)
-
#14038: Fall back immediately to user-agent-defined fonts when web fonts
fail to load.
(toastal)
-
#14048: document modular explicits
(Gabriel Scherer, review by Samuel Vivien, Ali Caglayan,
Didier Remy and François Pottier)
-
#13994: document external types
(Gabriel Scherer, review by Jan Midtgaard, Jacques Garrigue
and Florian Angeletti)
-
#14077: Add missing item-attribute rule for let-bindings in documentation
for attributes.
(Shon Feder)
-
#14228: Trim leading spaces from first lines of LaTeX ocamldoccode
environments.
(Yukai Chou, review by Nicolás Ojeda Bär)
-
#14248: Added documentation about the way Domain.join triggers a
Thread.join on the domain's systhreads.
(Raphaël Proust, review by Gabriel Scherer)
-
#14392: Fix AsciiDoc files, add more markup, xrefs, documentation.
(Antonin Décimo, review by Gabriel Scherer and David Allsopp)
-
#13590: Document automatic command-line expansion of * and ? wildcards by
the runtime under Windows.
(Benjamin Sigonneau, review by Nicolás Ojeda Bär)
Internal/compiler-libs changes:
-
#13913: Use Blake128 as the hash function for the compiler's CRCs
(Vincent Laviron, review by Xavier Leroy and Gabriel Scherer)
-
#13911, #14117, #14127: Refactor the merging of signature constraints, by
splitting the monolithic merge function into separate, specialized functions
(for merging types, modules and module types) - sharing only the recursive
part for handling deep constraints.
(Clement Blaudeau, review by Florian Angeletti and Samuel Vivien, fix by Ryan
Tjoa)
-
#14120, #14474, #14476: Associate Uids to items that don't have a concrete
definition; improves Merlin's renaming for functors.
(Ulysse Gérard, review by Florian Angeletti and Gabriel Scherer)
-
#13839, #14008: Reimplement let open, let module and let exception in
terms of a single construct.
(Nicolás Ojeda Bär, review by Gabriel Scherer, Samuel Vivien, Ulysse Gérard
and Vincent Laviron, temporary regression reported by Antonio Monteiro)
-
#13980 Refactor type-approx and improve some errors' locations.
(Leo White, Ulysse Gérard, review by Samuel Vivien and Florian Angeletti)
-
#14024: Fix unterminated-string-initialization warnings from the C compiler.
(Antonin Décimo, review by David Allsopp and Miod Vallat)
-
#14094: toplevel, simplify check on installed printer types
(Florian Angeletti, review by Gabriel Scherer)
-
#13656, #14114, #14308: Use C99 stdint.h/inttypes.h fixed-width
integer types and macros to define OCaml integers.
(Antonin Décimo, review by Nick Barnes and David Allsopp)
-
#14148: Remove an unused field from package_type in typedtree
(Samuel Vivien, review by Gabriel Scherer)
-
#14141: Rename cstrs to constraints when it refers to constraints to avoid
confusing it with constructors.
(Stefan Muenzel, review by Nicolás Ojeda Bär)
-
#14149: Distinguish (module M : S) from (module M) : (module S) in
patterns.
(Samuel Vivien, review by Gabriel Scherer)
-
#14161: refactor the STW-participants machinery to add an intermediate
category of 'parked' domain structures.
(Gabriel Scherer, review by Sivaramakrishnan)
-
#14198 Constraints on module unpacking are not ghost
(Thomas Refis, review by Nicolás Ojeda Bär)
-
#14243: ocamlc now uses the same code as the runtime to parse ld.conf (via a
C primitive), eliminating some highly obscure corner cases.
(David Allsopp, review by Jonah Beckford, Damien Doligez and Hugo Heuzard)
-
#14260: Refactor Lambda.structured_constant to avoid duplicate
representations for string constants
(Vincent Laviron, review by Nicolás Ojeda Bär and Gabriel Scherer)
-
#14297, #14299: Avoid iterating on hash tables to produce types or terms
(Vincent Laviron, review by Nicolás Ojeda Bär and Gabriel Scherer)
- (breaking change) #14322: Remove leftover hacks for handling pattern constraints
As a side effect,
let rec (_ as x) = ... is now always rejected instead of
being treated as equivalent to let rec x = ...
(Vincent Laviron, review by Alistair O'Brien and Florian Angeletti)
- #14331: Enforce current_level <= generic_level, and explain create_scope
(Jacques Garrigue and Takafumi Saikawa, review by Gabriel Scherer)
- (breaking change) #14388: Remove support for
let rec (module M : S) = e1 in e2.
(Alistair O'Brien, review by Vincent Laviron and Gabriel Scherer)
-
#14422: Refactoring an if match e with p1 -> true | p2 -> false then ...
into a match in typetexp.
(Samuel Vivien, review by Gabriel Scherer)
-
#13224: Clarify barriers and spin macros with delayed expansion.
(Antonin Décimo, review by David Allsopp and Gabriel Scherer)
-
#14435, #14455, #14550: Add the not-root builtin ocamltest action. This
allows to skip tests that fail if the current user is root (superuser).
(Kate Deplaix, review by Gabriel Scherer, Nicolás Ojeda Bär, and
Antonin Décimo)
-
#14457: Handle qualified M.{ x } patterns in untypeast
(Basile Clément, review by Florian Angeletti)
Build system:
-
#13705, #14444: Cache test results of custom Autoconf tests from aclocal.m4.
(Antonin Décimo, review by David Allsopp and Miod Vallat)
-
#13810: Support build of cross compilers to native freestanding targets
(Samuel Hym, review by Antonin Décimo and Romain Calascibetta)
-
#14243: New configure option --with-additional-stublibsdir allows an
additional directory to be added to the start of ld.conf. Additionally, the
stublibs subdirectory is no longer created, nor added to ld.conf, when
building OCaml with --disable-shared.
(David Allsopp, review by Jonah Beckford, Damien Doligez and Hugo Heuzard)
-
#14244: When targeting native Windows on Cygwin or MSYS2, preserve
backslashes in the supplied --prefix (in particular, backslashes instead of
slashes will then be displayed by ocamlopt -config-var standard_library).
If the supplied prefix contains a slash, then it is normalised, as
previously.
(David Allsopp, review by Jonah Beckford, Antonin Décimo, Damien Doligez and
Samuel Hym)
-
#14245: New --enable-runtime-search configure option controls the
-runtime-search option used to build the bytecode binaries in the compiler
distribution. --enable-runtime-search-target controls the default value of
-runtime-search used for bytecode executables produced by the compiler.
(David Allsopp, review by Damien Doligez and Samuel Hym)
-
#14484: Set _WIN32_WINNT to require Windows 8/Server 2012 Windows header SDK
support.
(Antonin Décimo, review by David Allsopp)
Bug fixes:
-
#14123: Fix integer-overflow problems in heap compaction.
(Nick Barnes, review by Antonin Décimo).
-
#14035: Fix the alignment of _Atomic long long unsigned int fields
before GCC 11.1 on i686. Silence GCC note on newer versions.
(Antonin Décimo, review by Sadiq Jaffer)
-
#14010: Fix miscompilation / liveness errors for string operations
(Mark Shinwell, Xavier Clerc, review by Xavier Leroy and Gabriel Scherer)
-
#14036: Fix nontermination of cycle printing in recursive modules with
-short-paths. Add error message for types considered abstract while
checking recursive modules.
(Brandon Stride, review by Florian Angeletti)
-
#14065: Fix function signature mismatch of __tsan_func_exit with GCC 15.
Check in the configure step if the TSan provided internal builtins are the
same as what we expect, introduce caml_tsan_* wrappers for the __tsan_*
functions we use.
(Hari Hara Naveen S, report by Hari Hara Naveen S,
review by Gabriel Scherer, Antonin Décimo, Olivier Nicole)
-
#14071: Fix exception name in Dynlink.Error printer.
(Etienne Millon, review by Nicolás Ojeda Bär)
-
#13853: Format breaks some line too early when there
is a break hint at the end.
(Florian Angeletti, review by Gabriel Scherer)
-
#10570: Fix handling of caml_sys_argv when exposed directly as an
external
(Keryan Didier, review by Vincent Laviron and Gabriel Scherer)
-
#14155: Audit unexecuted phrases in compiler expect tests and
fix all occurrences
(Stefan Muenzel, review by Gabriel Scherer)
-
#14163, #14176: add a filename location to the deprecation alert for implicit
uses of libraries bundled with the compiler (unix,re,threads,dynlink)
(Florian Angeletti, report by Ali Caglayan, review by Gabriel Scherer)
-
#14210: fix TSan-reported data race in weak pointers runtime
(Gabriel Scherer and Damien Doligez, report by Olivier Nicole,
review by KC Sivaramakrishnan)
-
#14213: Fix shadow-stack-related crashes with TSan
(Olivier Nicole, report by Nathan Taylor, review by Gabriel Scherer and
Stefan Muenzel)
-
#13658, #14181: Fix handling of recursive function types that can result
in an unbounded number of labeled or optional arguments.
(Stefan Muenzel, report by Samuel Vivien, review by Florian Angeletti)
-
#14255: Fix TSan bug with C calls that take many arguments
(Olivier Nicole and Miod Vallat, report by Nathan Taylor, review by Gabriel
Scherer)
-
#14230 : ocamltest fails to link test program with -custom in some cases
(Damien Doligez, review by David Allsopp)
-
#14279: -dsource, preserve (mod) and other escaped infix keyword operators in
the printed source wherever possible.
(Florian Angeletti, review by Gabriel Scherer)
-
#14300, #14304: fix a race between memprof and the minor GC, detected by TSan
(Gabriel Scherer, review by Stephen Dolan and Nick Barnes,
report by Olivier Nicole)
-
#14332: Fix missing TSan instrumentation in subexpressions
(Vincent Laviron, review by Gabriel Scherer and Olivier Nicole)
-
#14370, #14429: Fix headers for C++ inclusion.
(Antonin Décimo, review by Gabriel Scherer)
-
#14417: Fix issue with nested packs on macOS.
(Vincent Laviron, report by Kate Deplaix, review by Gabriel Scherer)
-
#14423: Fix detection of SetThreadDescription on 32-bit builds, meaning that
Thread.set_current_thread_name now works on 32-bit MSVC and uses the correct
mechanism on 32-bit mingw-w64.
(David Allsopp, review by Antonin Décimo)
-
#14431: Enable native backend for DragonFly BSD. This builds ocamlopt on
DragonFly.
(Michael Neumann, review by Gabriel Scherer and Kate Deplaix)
-
#14495: Fix infix-tag bug in the minor collector which could cause SEGVs
in multi-domain programs.
(Nick Barnes, review by Gabriel Scherer)
-
#14519: Fix segfault when using Runtime_events under certain
circumstances due to bad error checking when calling mmap().
(Mark Elvers, review by Nicolás Ojeda Bär)
-
private, CVE-2026-28364, OSEC-2026-01: robustify intern.c
(Xavier Leroy and Nicolás Ojeda Bär, review by Olivier Nicole, Mindy Preston,
Edwin Török, and Gabriel Scherer)
-
#13693, #14514: s390x: fix heap corruption with libasmrun_shared.so caused
by PLT lazy binding trampoline saving FPRs into OCaml's fiber stack.
Replace @PLT calls with GOT-indirect calls in the s390x code emitter.
(Zane Hambly, review by David Allsopp and Xavier Leroy)
-
#14557, #12150, #14696: ensure that the self type of class cannot escape
through type constraints.
(Leo White, review by Florian Angeletti)
-
#14603, #14604: avoid Ctype.apply failures when mixing
polymorphic types and unboxed constructors.
(Gabriel Scherer and Stefan Muenzel, report by Brandon Stride,
review by Florian Angeletti)
-
#14626, #14675: take in account module-dependent functions when
determining if an optional argument is non-erasable.
(Alistair O'Brien and Florian Angeletti, review by Gabriel Scherer)
-
#14635: Fix a bug in caml_floatarray_gather that would cause
the result of Float.Array.sub, Float.Array.append, Float.Array.concat
(when empty) not to be equal to [||].
(Marc Lasson, review by Gabriel Scherer)
-
#14644, #14647: Fix a bug related to unhandled effects in bytecode.
(Vincent Laviron, report by Thibaut Mattio,
review by Nicolás Ojeda Bär, Stephen Dolan and Olivier Nicole)
-
#14655, #14691: check for size overflow in caml_ba_reshape
(Stephen Dolan, review by Xavier Leroy)
-
#14667: enable application related warnings for module-dependent functions
(Florian Angeletti, review by Gabriel Scherer)
-
#14690: Fix Name_type_mismatch error message when the expected type is an
alias: print the expanded path on the right-hand side of the equality, not
the alias twice.
(Weixie Cui, review by Florian Angeletti)
-
#14349, #14718, #14722: runtime, fix in the orphaning of ephemerons
(Gabriel Scherer, review by Olivier Nicole and Damien Doligez,
report by Jan Midtgaard)
-
#14702: Fix hidden directory files leaking into the visible load path table.
When a hidden directory contained a file whose basename was already present,
the file could be incorrectly added to the visible table.
(Hugo Heuzard, review by Florian Angeletti)
-
#14719, #14721: compute arity correctly for module-dependent function
(Florian Angeletti, report by Jeremy Yallop, review by Stefan Muenzel)
-
#14760, #14802, #14846: Correct the detection of argument defaults in
configure, fixing an incorrect error message when installing OCaml through
opam on OpenSUSE with the site-config package installed.
(David Allsopp, report and review by Edwin Török)
-
#14797: avoid dropping attributes attached to package types when pretty
printing in surface syntax.
(Chet Murthy, review by Nicolás Ojeda Bär)
-
#14853, CVE-2026-41083, OSEC-2026-05: fix quoting of filenames
passed to Filename.quote_command on Windows.
(David Allsopp, report by Andrew Nesbitt, review by Florian Angeletti)
- Security fix for check for size overflow in caml_ba_reshape (CVE-2026-34353, OSEC-2026-04)
- Security fix for quoting of filenames passed to Filename.quote_command on Windows
- Bug fixes for 4.14.3
See detailed list of changes.
We have the pleasure of celebrating the anniversary of the first flight of Ariane 4 by announcing the release of OCaml version 4.14.4.
This release is a collection of safe bug fixes, cherry-picked from the OCaml 5 branch.
The 4.14 branch is expected to receive updates until at least the end of 2026.
However, the end of its extended maintenance period is on the horizon.
Consequently, please mention to us any obstacle remaining to your migration to OCaml 5.
In the meanwhile, do not hesitate to report any bugs on the OCaml issue tracker.
See the list of changes below for more details.
Installation Instructions
The base compiler can be installed as an opam switch with the following commands:
opam update
opam switch create 4.14.4
The source code for the release candidate is also directly available on:
See full changelog
Changes in OCaml 4.14.4 (15 June 2026)
Build system:
- #12372, #14572: Pass option -no-execute-only to the linker for OpenBSD >= 7.3
so that code sections remain readable, as needed for closure marshaling.
Originally backported in 4.14.2, but the flag was accidentally not passed when
linking the .so versions of the OCaml runtime libraries or when linking .cmxs
files.
(Xavier Leroy and Anil Madhavapeddy, review by Anil Madhavapeddy and
Sébastien Hinderer)
Bug fixes:
-
#14599, #14606: on ARM64 platforms, ocamlopt was under-estimating
the sizes of some instructions. This could lead to overflows in
relative branch offsets, reported as errors by the assembler.
(Xavier Leroy, review by Vincent Laviron, report by Raphaël Proust)
-
#14607: Fix linking with libasmrun_shared.so on Risc-V (undefined symbol
declared riscv.o)
(David Allsopp, review by Nicolás Ojeda Bär)
-
#14661: Build dllthreads.so with pthreads flags (removed in #13018). For
normal programs there's no semantic difference, because ocamlrun and
ocamlc.opt are always linked with pthreads, but it was a regression to require
programs wishing to dlopen dllthreads.so to have already linked with pthreads
themselves.
(David Allsopp, review by Gabriel Scherer)
-
#14655, #14691, CVE-2026-34353, OSEC-2026-04: check for size overflow in
caml_ba_reshape
(Stephen Dolan, review by Xavier Leroy)
-
#14853, CVE-2026-41083, OSEC-2026-05: fix quoting of filenames passed to
Filename.quote_command on Windows.
(David Allsopp, report by Andrew Nesbitt, review by Florian Angeletti)
Bootstrap (probably not necessary)
The Dune team is pleased to announce the release of dune
3.23.1.
This is a patch release consisting of bug fixes. See the full
changelog for all the
changes and for attribution to the contributors who made it all possible. Thank
you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
See full changelog
Fixed
- Fix the
menhir opam dependency injection introduced in 3.23. Dune
now only fills in the lower bound {>= "20180523"} on an existing
user-declared menhir dependency; it no longer adds menhir as a
new dependency to packages that did not declare it themselves.
(#14434, fixes #14428, @robinbb)
- Gate the
dune version-bound deduplication in generated opam files
(introduced in 3.23) on (lang dune 3.23). Projects at earlier lang
versions get the prior And [...] shape — e.g.
{>= "3.17" & >= "3.20"} — restoring 3.22 behaviour and avoiding a
silent change to opam output on dune-binary upgrade. (#14436,
@robinbb)
- Preserve library order when building a shared jsoo standalone runtime.
(#14438, @vouillon)
- Fix the fallback to the secondary compiler, allowing recovering of support for
packages with upper bounds on OCaml less than 4.14. Packages depending on dune
3.23.1 or later and with an upper bound on the OCaml compiler that is less
than 4.14, will now be able to use the latest dune, but dune will be built
with the secondary compiler at version 4.14. (#14443, @Alizter)
- Fix the bootstrap on NetBSD by including
<sys/wait.h> in lev_stubs.c,
matching the existing FreeBSD/OpenBSD guard.
(#14512, fixes #14484, @0-wiz-0)
The Dune team is pleased to announce the release of dune
3.23.0.
Along with many other fixes and improvements, some highlights include:
- Add support for
c_library_flags in foreign_stubs
(#13484,
@madroach)
- Many improvements to the promotion and diffing functionality, by
@rgrinberg.
- As part of the previous, a breaking change to the promotion logic has been
introduced: Dune does not automatically promote generated opam files, which must
now be manually promoted with
dune promote. You can trigger building .opam
files with the @install, @runtest, and @opam aliases. In release mode,
.opam files aren't generated at all and whatever is in the source is used
(ocaml/dune#14108,
@rgrinberg).
- User rules and inline test runners are now sandboxed by default
(ocaml/dune#13805 and
ocaml/dune#14257,
@rgrinberg).
- The minimum OCaml version required to build dune is now 4.14.
See the full changelog
for all new features and fixes, and for attribution to the contributors who made
it all possible. Thank you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
See full changelog
Fixed
- Auto-inject
"menhir" {>= "20180523"} into generated opam files when the
menhir extension is used. Dune's menhir rules rely on --infer-write-query
and --infer-read-reply, which require at least this version; without the
lower bound, builds fail with older menhir installations.
(#10707, @robinbb)
- Fix
--display=quiet not suppressing "Entering directory" and "Leaving
directory" messages when using --root. These messages are now deferred
until there is actual output, so silent builds produce no noise.
(#12974, fixes #12854, @Alizter)
- Fix an internal error when a module is shared between a
rocq.theory and
rocq.extraction stanza. The error now includes a hint pointing to the
conflicting stanza. (#13733, @Durbatuluk1701)
- Fix cookies defined on
ppx_rewriter being lost when that rewriter was used
as a dependency of another ppx_rewriter. (#13737, fixes #3426, @Alizter)
- Improve opam file generation for packages that set
(dir ..). Such packages
will now have a test target that is limited to this directory. (#13778, @rgrinberg)
- Stop duplicating dune diagnostics to subscribers over RPC (#13816,
@rgrinberg)
- Fix dependency cycle when using the
package with a library
conditionally enabled via enabled_if. (#13833, @toots)
- Fix underspecification of dependencies in the sandbox for modules with
interfaces. (#13842, @anmonteiro)
- Honor sandbox settings specified inside
(:include ..) expressions in the deps field
(#13898, @rgrinberg)
- Fix
dune pkg lock failing when a pin stanza contains a file:// URL with
a relative path outside the workspace (#13915, fixes #10254, @shunueda)
- Use all stat attributes to detect patch back source tree changes (#13986, @rgrinberg)
- Use device and inode number for invalidating cached digests (#13991, @rgrinberg)
- Stop trying to set SO_REUSEADDR on unix sockets when setting up dune rpc
(#14056, @rgrinberg)
- Fix autolocking to correctly detect changes to
(depends) in watch mode
(#14066, fixes #13234, @Alizter)
- Fix incremental builds for libraries using
(wrapped (transition ...)).
The compat shim modules were never recompiled when the inner module's
interface changed, causing "inconsistent assumptions" errors.
(#14090, fixes #14089, @Alizter)
- Fix Rocq configuration detection to use
rocq c --config subcommand
instead of rocq --config (#14093, fixes #13774, @Durbatuluk1701)
- Bump dune rpc's request pending request limit 10 to 100 (#14094, @rginberg)
- Invalidate stale cached digests in all build commands (#14126, @rgrinberg)
- Fix
root_module generating duplicate module definitions when a
findlib sub-package shares a directory with its parent (e.g.,
logs.lwt alongside logs). (#14135, fixes #6148, @robinbb)
- Fix
dune subst prepending a duplicate version: field to opam
files that already contain one, instead of replacing it in place.
(#14136, fixes #878, @robinbb)
- Fix
@ocaml-index alias being generated for all contexts, causing build
errors in multi-context workspaces where some libraries are disabled in
non-default contexts. The alias is now only generated for the merlin context.
(#14137, fixes #12007, @robinbb)
- Remove the warning about the deprecation of the coq stanza for
dune lang before 3.21 since it has been introduced in this
version (#14187, @bobot)
$ dune init now generates projects with correct .opam files (#14192, @rgrinberg)
- Send SIGTERM before SIGKILL when cancelling child processes in watch
mode, giving cleanup handlers a chance to run before escalating.
(#14224, #14170, fixes #2445, @robinbb)
- Correctly specify dependencies for
generate_runner in inline tests (#14276, @rgrinberg)
- Fix duplicate dune version bounds in generated opam files. When users
declare
(dune (>= X.Y)) matching or exceeding the (lang dune X.Y)
version, the generated opam depends no longer contains redundant
constraints like {>= "2.7" & >= "2.7"}. (#3916, #11106, @robinbb)
- Fix inline tests not being executed for byte-only libraries. When a library
has
(modes byte), the inline test runner is now linked in byte mode so the
library's test code is included. (#9757, @robinbb)
Added
- Add support for
c_library_flags in foreign_stubs (#13484, @madroach)
- Move the management of Jsoo config details out of dune (#13613, @vouillon)
- Js_of_ocaml: share standalone runtimes (#13621, @vouillon)
- Allow multiple
(dirs ..) stanzas in the same Dune file. Starting with
(lang dune 3.23), Dune takes the union of the specified directories
(#13734, fixes #6249, @anmonteiro)
- Sandboxed rules are now allowed to produce diff promotions when
(corrections produce) is set on the rules. Whenever such an action produces foo.corrected, it will
be automatically registered as a promotion for foo (#13813, @rgrinberg)
$ dune clean now accepts arguments to only remove certain targets from the
_build directory (#13875, @rgrinberg)
$ dune promote now promotes all paths that are a prefix of the path provided.
For example, $ dune promote foo will promote foo, foo/bar, foo/bar/baz
(but not foobar). (#13876, @rgrinberg)
- Allow for the
diff action to diff entire directories (#13880, fixes #3567, @rgrinberg)
- A hint is now emitted when trying to build a target inside a directory that
was excluded by a
(dirs ...) stanza (#13919, @mefyl).
- Add --debug-backtraces to
$ dune {promote,trace,cache} (#13933, @rgrinberg)
- Actions are now able to observe their project directory via
DUNE_PROJECT_ROOT (#13934, @rgrinberg)
- Support hardlink sandboxing on Windows. (#13987, addresses part of #4362, @Alizter)
rocq.extraction: Add extracted_files field in (rocq 0.13), replacing
extracted_modules, supporting extraction to languages other than OCaml
(#13997, @Durbatuluk1701).
- Infer source directories as dependencies when they're as reference
directories in
diff actions.
- Add trace events for build start/stop/restarts (#14163, #14166, @rgrinberg)
- Generate
compile_commands.json for C/C++ foreign stubs when building
@check with (lang dune 3.23). This enables clangd, ccls, and other
tools that consume compilation databases. (#14185, fixes #3531, @Alizter)
- Add trace events for accepting clients and shutting down RPC (#14232, @rgrinberg)
- Back up the default trace file as
trace.csexp.old before each build,
preserving the previous trace for comparison. This does not apply when
--trace-file is used. (#14269, @Alizter)
Changed
- Dune digests target files and directories in background threads (#13341,
@rgrinbreg)
Dyn.pp now prints valid OCaml literals for more constructors:
Char is quoted (e.g., 'a')
Int32/Int64/Nativeint include literal suffixes (l/L/n)
Float handles infinity, neg_infinity, and nan
(#13394, grants #13378, @Alizter)
- Bump the minimal OCaml version required to build Dune from 4.08 to 4.14.
(#13533, @Alizter)
- Starting from 3.23, user rules are sandboxed by default (#13805, @rgrinberg)
- Dune will no longer stat paths in the _build directory. This was done as protection
from user rules accidentally touching things in the _build directory. This is forbidden,
and dune offers rule sandboxing to prevent this (#13875, @rgrinberg)
- Improve mtime precision by no longer approximating them with floats (#13962,
@rgrinberg).
- Remove
--makefile (or -m) in $ dune rules. The sexp output is the only
supported way of reflecting dune rules (#14069, @rgrinberg)
- Do not automatically promote files. Now, opam files must be manually
promoted with
$ dune promote. Their generation is triggered by @install,
@runtest, and @opam. In release mode, .opam files aren't generated at all
and whatever is in the source is used (#14108, @rgrinberg)
- Inline test runner generation is now sandboxed (#14257, @rgrinberg)
We're happy to announce the release of Odoc 3.2.0.
This release brings:
- Support for OCaml 5.5.0 (#1406).
- Support for the OxCaml compiler variant (#1399).
- Persistent LaTeX macros in the HTML/KaTeX backend (#1391), so a macro defined with
\gdef in one math block can be reused in subsequent ones.
- Multiple
.odocl files accepted by markdown-generate in a single invocation, removing the need for shell scripting around it (#1388).
For more details, see the full changelog below.
See full changelog
Added
- Allow persistent latex macros in HTML/KaTeX backend (@dlesbre, #1391)
markdown-generate command now accepts multiple .odocl files in a single
invocation, eliminating the need for shell scripting (@davesnx, #1388)
- Support for OxCaml (@lukemaurer, @art-w, #1399)
- OCaml 5.5.0 support (@panglesd, @xvw, #1406)
Fixed
- Fix compile-time crashing bugs #930 and #1385 (@jonludlam, #1400)
- Markdown backend assumes ocaml as langId on declarations
- Markdown backend collects all code snippets and render a single code block with comments, rather than split the variants/records per constructor/field
- Fix URL remapping for page references (@jonludlam, #1395)
- Fix #1396, which broke incrememntal builds (@jonludlam, #1402)
- Ensure all warnings turn into errors with --warn-error (@jonludlam, #1402)
- Fix missing parentheses for polymorphic arguments (@art-w, #1404)
We're happy to announce the release of Merlin 5.7.1-504, a patch release for the OCaml 5.4 series. This release brings:
- A fix for a typer cache invalidation bug (#2062) where Merlin would not pick up newly created
.cmi files appearing in the build path, for instance when Dune built a new module.
- A change to the on-disk index format (#2051) so that merged indexes can point to existing index files, resulting in significantly smaller index files and fewer write operations.
For more details, see the full changelog below.
See full changelog
Thu Apr 30 14:15:42 CEST 2026
- merlin library
- Fix a cache invalidation issue due to the introduction of hidden deps in
OCaml 5.2. (#2062)
- index format
- Merged indexes now point to each-others. This results in smaller index
files. The index of a project is now defined by all its index files, not
only the final aggregation. (#2051)
Feedback on this post is welcomed on Discuss!
We are pleased to announce the release of opam 2.5.1 fixing a security issue (OSEC-2026-03) and other minor things.
We advise everyone to upgrade. Please read on for installation and upgrade instructions.
Security fix
OSEC-2026-03: Invalidate .install fields containing destination filepath trying to escape their scope. Thanks to @andrew for reporting this issue. (#6897)
Distributions maintainers that have not already done so, are invited to either upgrade their opam package to 2.5.1 or backport the fix. For any questions please send an email to the authors of this here blog post as listed above.
Other changes
-
Fix a string injection from the depexts field to nix-build, when os-family=nixos. Thanks to @RyanGibb for this contribution and @andrew for the report. (#6894)
-
Restore the distribution detection on Gentoo. (#6887)
-
Add support for single-quoted values of the /etc/os-release file. (#6887)
-
Fix rare potential GC corruptions. Thanks to @avsm for the contribution and @andrew for the report. (#6882, #6880)
Try it
The upgrade instructions are unchanged:
-
Either from binaries: run
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.5.1"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.5.1"
or download manually from the Github "Releases" page to your PATH.
-
Or from source, manually: see the instructions in the README.
You should then run:
opam init --reinit -ni
Please report any issues to the bug-tracker.
Happy hacking!
The Dune team is pleased to announce the release of dune
3.22.2.
This is a patch release consisting of bug fixes. See the full
changelog for all the
changes and for attribution to the contributors who made it all possible. Thank
you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
See full changelog
Fixed
- Revert the change in behavior of
--diff-command back to 3.21. Non-existent
files are now passed to this command instead of being replaced with /dev/null
(#14098, fixes 13891, @rgrinberg)
This new release of OCaml-LSP brings several new features and improvements, including new custom requests, support for range formatting, and enhanced hover capabilities.
See the related announcement on the Discuss forums.
See full changelog
Features
- Add custom
ocamllsp/refactorExtract request (#1545)
- Add
destruct custom request (#1583)
- Add
locate_types custom request (#1584)
- Add support for the
textDocument/rangeFormatting request (#1591)
- Allow to configure merlin using build systems other than dune.
If
$OCAMLLSP_PROJECT_BUILD_SYSTEM environment variable is set then OCaml
LSP will execute $OCAMLLSP_PROJECT_BUILD_SYSTEM ocaml-merlin command to get
merlin configuration for a module. It is expected the command to communicate
using merlin-dot-protocol.
If $OCAMLLSP_PROJECT_ROOT environment variable is set then OCaml LSP will
use it as a project root directory.
Fixes
- Enable "hover" on more locations, notably class and object related (#1599)
We're happy to announce the release of Merlin 5.7.0-504. This release comes with a number of bug fixes and improvements to Merlin.
For more details, we encourage you to delve into the full changelog.
See the related announcement on the Discuss forums.
See full changelog
- merlin library
- Implement new refactor-extract-region command for extracting region to a fresh let binding (warning: this feature is still experimental) (#1948)
- Add "Other" variant to locate-types result (#2025)
- Don't include
option in locate-types result for optional parameters (#2027)
- Fix record field autocompletion (#2028)
- Signature help should not loop over the parameters once it is finished (#2023)
- Fix bugs on signature help about labelled and optional parameters (#2032)
- Add
-end-position parameter for enclosing (#2029)
- Signature help should appear even if the 'in' is not written (#2036)
- Improve type enclosing behavior on various class and object related items
(#2053)
- merlin binary
- Define PATH_MAX to 4096 if undefined (eg. hurd) (#2039)
- test suite
The Dune team is pleased to announce the release of dune
3.22.1.
This is a patch release consisting of bug fixes. See the full
changelog for all the
changes and for attribution to the contributors who made it all possible. Thank
you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
See full changelog
Fixed
-
Restore compatibility with Windows 7 (#13905, @nojb)
-
dune test now runs tests in the default context only. When there is a
single context, it is treated as the default. This fixes a crash when the
workspace has no context named "default".
(#13930, fixes #13904, @Alizter)
-
Fix dune trace cat --chrome-trace to adhere to the Chrome Trace Event
Format by providing timestamps and durations at microsecond granularity
(#13911, fixes #13906, @Alizter)
We're happy to announce the release of utop 2.17.0.
This release brings:
- Support for OCaml 5.5 (#510).
- Decoupling of
utop.el from tuareg-mode (#511): tuareg is now loaded lazily, and other OCaml major modes for Emacs (such as neocaml) can integrate with utop via the new utop-mode-compat-alist. Existing tuareg, caml, typerex, and reason users are unaffected.
For more details, see the full changelog below.
See full changelog
- Add support for OCaml 5.5 (#510 @anmonteiro)
- Add support for neocaml or other major modes in utop.el (#511, @bbatsov)
We're happy to announce the release of Dune-release 2.2.1.
This release adds a CLI flag to mark a GitHub release as a prerelease, exposing capability that already existed in the GitHub REST API to the dune-release command line (#517).
For more details, see the full changelog below.
See full changelog
Added
- Add support for marking a release as a prerelease. (#517, @Sudha247)
We're happy to announce the release of MDX 2.5.2.
This is a small compatibility release that adjusts MDX's toplevel support to work with OCaml 5.5.
For more details, see the full changelog below.
See full changelog
Added
- Support OCaml 5.5 (#475, @anmonteiro)
The ppxlib team is happy to announce the release of ppxlib.0.38.0.
The main features of this release are support for OCaml 5.5 and improved support of OCaml 5.4 and 5.3. It also comes with a few bug fixes and a couple new API entries, you can read the extensive release notes here.
This is our first release since we announced our new approach to supporting new compilers in this thread. All support for compilers versions >= 5.3 is implemented using this technique and new language features are encoded into the AST. We've added Ast_builder and Ast_pattern functions to allow you to manipulate some of those, such as labeled tuples or effect patterns. You can see those in our API documentation here and there. We've also illustrated how to use them in our new manual section. If you're interested in producing or consuming other new language features that cannot be represented with our current internal AST (5.2), please open an issue so we can add the relevant helpers.
Given the ecosystem hasn't yet recovered from the 5.2 AST bump and ppxlib.0.36.0, we're glad that we can add support for new compilers without introducing further breakage and keep the maintenance burden within ppxlib's bounds.
We've started discussions with the compiler team to make this approach even more viable in the future on our end.
We'd like to thank @ceastlund who's our only external contributor for this release.
I'd personally like to thank @patricoferris for his help getting this out the door as well as the OCaml Software Foundation and OCamlPro for funding my work on ppxlib.
Thank you for reading and happy preprocessing!
You can comment on this announcement on the OCaml discuss forums.
See full changelog
-
Add support for OCaml 5.5 (#622, @patricoferris, @NathanReb)
-
Add support for OCaml 5.4 bivariant type parameters, they can now be used
alongside ppx-es. (#629, @NathanReb)
-
Add Attribute.Floating.declare_with_attr_loc and .declare_with_name_loc,
by analogy to the same functions at top level of Attribute. (#631, @ceastlund)
-
Migrate Ptyp_open nodes using an extension point (#625, @patricoferris)
-
Add Ast_builder and Ast_pattern utilities to manipulate encoded
effect patterns (#624, @NathanReb)
-
Fix a bug where ppat_effects would be encoded/decoded instead of copied by
the 5.4 <-> 5.3 migrations (#624, @NathanReb)
-
Fix infinite loop when duplicate attributes are present, raising
an error instead (#613, @ceastlund, @patricoferris)
-
Ignore extensions inside attributes for the unused extension check
(#616, @Skepfyr)
-
Fix a bug that inserted Location.none into Longidents when using OCaml
5.4 and above (#619, @patricoferris)
-
Add support for OCaml 5.4 labeled tuples, they can now be used alongside
ppx-es. Also adds Ast_builder and Ast_pattern utilities to manipulate them.
(#607, @NathanReb)
The Dune team is pleased to announce the release of dune
3.22.0.
In addition to many fixes and small improvements, notable highlights of this
release include:
- Fixes to the dune cache on Windows, thanks to
@Nevor in
ocaml/dune#13713.
- New tracing functionality, to inspect and diagnose the build processes thanks
to @rgrinberg across many PRs. See the
documentation.
- Addition of the
dune-action-trace library, to instrument trace emission, thanks
to @rgrinberg.
- Support for generating odoc documentation in markdown via the
@doc-markdown
build alias thanks to @davesnx
ocaml/dune#12581.
- Full support for OxCaml's parameterised libraries, thanks to
@art-w and @maiste.
To learn more, see the
docs.
See the full changelog
for all new features and fixes, and for attribution to the contributors who made
it all possible. Thank you, contributors!
If you encounter a problem with this release, please report it in our issue
tracker.
You can comment on this announcement on the OCaml discuss forums.
See full changelog
Fixed
-
Dyn.to_string now uses a smarter way to convert floats. This ensures that
floats are printed with enough precision to round-trip and are valid OCaml
lexemes. (#12982, fixes #12980, @Alizter)
-
Fix dune install --prefix failing with relative paths outside the workspace
like ../foo (#12993, fixes #12241, @benodiwal)
-
Place the default trace file inside the build directory at the
workspace root, rather than relative to the current directory.
(#13735, @vouillon)
-
Fixed interpreting relative paths in %{bin:..} and %{bin-available:..}.
These are now interpreted correctly, relative to the dune file they're in.
(#13712, fixes #9564, @anmonteiro)
-
Delete sandboxes with broken permissions (#13511, @rgrinberg)
-
Fix compiling Menhir parsers that refer to sibling modules within a
subdirectory of (include_subdirs qualified). (#13118, fixes #11119,
@anmonteiro)
-
Fixed the dependency specification of C stubs, which could result in C
stubs not getting rebuilt when needed (which could in turn lead to
segmentation faults and other hard-to-track bugs).
(#13652, fixes #13651, @nojb)
-
Fix the Dune cache on Windows by correctly handling renames onto read-only
files. Before this change, the Dune cache would be filled but the stored
artifacts would not generally be usable by Dune. (#13713, @Nevor)
-
Fix rpc not transferring promotion warnings to the client
(#12604, fixes #12578, @ElectreAAS)
-
Fix issue where dune exec -w was unable to kill running programs on
rebuild. (#12360, fixes #12323, @Alizter)
-
Resolve context and workspace binaries introduced by the respective (env (binaries ..)) stanzas. (#12952, fixes #6220, @anmonteiro)
-
Fix diff promotions originating from sandboxed rules. Previously, they
would be completely ignored as the sandbox with the promoted file would be
destroyed if the promotion fired (#13520, @rgrinberg)
-
Fix failure to digest installed directory targets, allowing them to be used
as dependencies to other rules. (#13045, @anmonteiro)
-
Fix handling of (select ..) field when used with (include_subdirs ..).
(select <path> from ..) modules now parse path as a relative path
starting from the module group root (#13175, fixes #4383, #12450,
@anmonteiro)
-
Fix dune trying to kill processes that were already reaped due to race
conditions (#13245, @rgrinberg)
-
Add O_CLOEXEC to all files used for stdin/stdout/stderr (#13385, @rgrinberg)
-
Fix $ dune promote dir/foo when dir does not exist (#13493, @rgrinberg)
-
Fix (select ..) field evaluation when a transitive library has optional
dependencies (fixes #13299, #13389, @anmonteiro)
-
Fix sandboxed builds of library stanzas that set
(stdlib (modules_before_stdlib ..)) (#13624, @anmonteiro)
-
Dune cache: use of hard links under Windows. (#13714, @Nevor)
-
Fixed non-build caches not following $DUNE_CACHE_ROOT and instead only
relying on $XDG_CACHE_HOME.
This means the normal build cache moves:
$DUNE_CACHE_ROOT -> $DUNE_CACHE_ROOT/db (no changes if that variable was
unset). Affected users can prevent a full cache invalidation by moving
previous contents:
cd $DUNE_CACHE_ROOT; mkdir db; mv <contents of directory> db.
(#11612, fixes #11584, @ElectreAAS)
-
$ dune promotion list writes output to stdout rather than stderr (#13462)
-
Improve handling of empty files in the diff action. These are now correctly
distinguished from empty files. (#13696, @rgrinberg)
-
Pass /dev/null to --diff-command instead of non-existent files (#13696,
@rgrinberg)
-
Fix failure when multiple rocq.extraction stanzas existing in a directory
(#13531, fixes #8042, @rlepigre-skylabs-ai)
-
Print $ dune promotion show output to stdout rather than stderr (#13481,
@rgrinberg)
-
Fix deadlock in the memo library in the presence of dependency cycles
(#13625, @anmonteiro)
-
Fix promotions that modify a directory into a file (#13516, fixes #4067,
@rgrinberg)
-
Fix installation of implementations of virtual libraries. This failed when
the implementation had no private modules, but the virtual library did
(#10635, @rgrinberg)
-
Respect the (dir ..) field on packages when setting up cram tests (#13581,
@rgrinberg)
Added
-
Add support for generating .cms files using oxcaml and adding .cms or
.cmt files as compilation dependencies (#13397, @spiessimon)
-
Add trace events for custom actions (#13265, @rgrinberg)
-
Allow enabling extensions with (using ..) in dune-workspace files
(#13395, @spiessimon)
-
Add sandbox extraction trace event (#13544, @rgrinberg)
-
Add the initial cwd to the first config event (#13026, @rgrinberg)
-
Dune dune produces trace events in DUNE_ACTION_TRACE_DIR if this variable
is set. (#13302, @rgrinberg)
-
Add file watching events to the trace file (#13038, @rgrinberg)
-
Introduce the $ dune trace cat subcommand to view the trace file. (#13055,
@rgrinberg)
-
Add diagnostic events to the trace. (#13041, @rgrinberg)
-
Add DUNE_JOBS environment variable for controlling concurrency of Dune from
environment. The INSIDE_DUNE variable also now no longer controls
concurrency (#12800, @Alizter)
-
Support for Rocq expected output tests (#13632, @rlepigre-skylabs-ai)
-
Add rusage information to completed processes in the trace (@rgrinberg,
#13241)
-
Add process start events to the trace (#13261, rgrinberg)
-
Generate odoc documentation in markdown using the @doc-markdown alias
(#12581, @davesnx)
-
Add timing information for every command executed by cram (#13092,
@rgrinberg)
-
Add the workspace root to the config trace event (#12922, @rgrinberg)
-
Introduce the dune-action-trace library. This public library is to be used
by custom actions to emit trace events while executed as part of a dune
build. The trace events emitted through this library will be incorporated
into dune's own trace (#13348, @rgrinberg)
-
Add dune-find-dominating to dune.el, a command to find the
dominating dune file. (#12696, @arvidj)
-
Add a --no-recursive flag to $ dune describe workspace (#13590, @rgrinberg)
-
Trace events for files written directly by dune (#13618, @rgrinberg)
-
Allow expansion of special forms like (:include ..) and %{read-lines:..}
in the modules specification for the ocamllex, ocamlyacc and menhir
stanzas. (#13105, #13135, #13157, @anmonteiro)
-
Add a trace event for snapshotting the sandbox (#13541, @rgrinberg)
-
Add signal send and receive events to the trace (#13193, @rgrinberg)
-
Emit final trace event before exiting. (#13018, @rgrinberg)
-
dune runtest can now run individual test executables from (tests) stanzas
and inline tests from (library (inline_tests)) stanzas by providing their
source files as arguments. (#13064, fixes #870, @Alizter)
-
Add a shell field to the cram stanza. This field allows customizing the
shell to be bash rather than sh (#13083, @haochenx)
Changed
-
Start sandboxing the execution of tests defined with the test and tests
stanzas (#13510, #13617, @rgrinberg)
-
Disabled cram tests can now be run explicitly with dune runtest disabled.t.
The enabled_if field now only controls whether a test is included in
the @runtest alias. (#13081, @Alizter)
-
Process categories in trace events are moved to their own field in args
(#13024, @rgrinberg)
-
Sandbox running ocamllex and ocamlyacc actions. (#13098, @anmonteiro)
-
Sandboxing mdx test actions is now the default starting from 0.5 (#13504,
@rgrinberg)
-
Start sandboxing Melange rules by default in the (library ..) and
(melange.emit ..) stanzas (#13619, @anmonteiro)
-
Introduce a promotion trace event and remove the corresponding verbose log
message. (#12949, #13444, @rgrinberg)
-
Change dune's trace format to emit canonical s-expressions. This improves
performance and is better aligned with dune's usage of the format
elsewhere. $ dune trace cat can also emit the trace in --chrome-trace
for perfetto, or --sexp for regular s-expressions for interactive usage.
(#13059, @rgrinberg)
-
Move all logging statements to the trace file. All log statements now contain
structured payloads (#13015, fixes #12904, @rgrinberg)
-
Add a target resolution event to replace the equivalent log message (#12955,
@rgrinberg)
We're happy to announce the release of OCamlFormat 0.29.0.
CHANGES:
Highlight
-
* Support OCaml 5.5 syntax
(#2772, #2774, #2775, #2777, #2780, #2781, #2782, #2783, @Julow)
The update brings several tiny changes, they are listed below.
-
* Update Odoc's parser to 3.0 (#2757, @Julow)
The indentation of code-blocks containing OCaml code is reduced by 2 to avoid
changing the generated documentation. The indentation within code-blocks is
now significative in Odoc and shows up in generated documentation.
Added
-
Added option letop-punning (#2746, @WardBrian) to control whether
punning is used in extended binding operators.
For example, the code let+ x = x in ... can be formatted as
let+ x in ... when letop-punning=always. With letop-punning=never, it
becomes let+ x = x in .... The default is preserve, which will
only use punning when it exists in the source.
This also applies to let%ext bindings (#2747, @WardBrian).
-
Support the unnamed functor parameters syntax in module types
(#2755, #2759, @Julow)
module type F = ARG -> S
The following lines are now formatted as they are in the source file:
module M : (_ : S) -> (_ : S) -> S = N
module M : S -> S -> S = N
(* The preceding two lines are no longer turned into this: *)
module M : (_ : S) (_ : S) -> S = N
Fixed
-
Fix dropped comment in (function _ -> x (* cmt *)) (#2739, @Julow)
-
* cases-matching-exp-indent=compact does not impact begin end nodes that
don't have a match inside. (#2742, @EmileTrotignon)
(* before *)
begin match () with
| () -> begin
f x
end
end
(* after *)
begin match () with
| () -> begin
f x
end
end
-
Ast_mapper now iterates on all locations inside of Longident.t,
instead of only some.
(#2737, @v-gb)
-
Remove line break in M with module N = N (* cmt *) (#2779, @Julow)
Internal
- Added information on writing tests to
CONTRIBUTING.md (#2838, @WardBrian)
Changed
-
indentation of the end keyword in a match-case is now always at least 2. (#2742, @EmileTrotignon)
(* before *)
begin match () with
| () -> begin
match () with
| () -> ()
end
end
(* after *)
begin match () with
| () -> begin
match () with
| () -> ()
-
* use shortcut begin end in match cases and if then else body. (#2744, @EmileTrotignon)
(* before *)
match () with
| () -> begin
match () with
| () ->
end
end
(* after *)
match () with
| () ->
begin match () with
| () ->
end
end
-
* Set the ocaml-version to 5.4 by default (#2750, @EmileTrotignon)
The main difference is that the effect keyword is recognized without having
to add ocaml-version=5.3 to the configuration.
In exchange, code that use effect as an identifier must use
ocaml-version=5.2.
-
The work to support OCaml 5.5 come with several improvements:
We're happy to announce the release of opam-publish 3.0.0.
This major release contains breaking changes:
- The deprecated
--split option has been removed (#194).
- Following the upgrade to cmdliner 2.0, option names can no longer be abbreviated to an unambiguous prefix (for example,
--dry is no longer accepted as an alias of --dry-run) (#202).
- The
github-unix dependency has been dropped (#196).
For more details, see the full changelog below.
See full changelog
- No longer allow option names to be specified by a prefix if the prefix is unambiguous [#202 @kit-ty-kate]
- Query upstream repo for default branch instead of defaulting to
master [#201 @mbarbin]
- Query fork name from GitHub to support users whose fork of opam-repository isn't named
opam-repository [#199 @mbarbin]
- Fix an infinit loop if the user repeatedly provided an invalid token [#186 @filipeom]
- Remove the deprecated
--split option [#194 @kit-ty-kate]
- Remove the
github-unix dependency [#196 @kit-ty-kate]
- Upgrade to cmdliner 2.0 [#202 @kit-ty-kate]
We have the pleasure of announcing the dual releases of OCaml 4.14.3 and OCaml 5.4.1, dedicated to the memory of Nicolaas Govert de Bruijn on the anniversary of his death.
Those releases are a collection of safe and valuable runtime bugfixes.
The OCaml 5.4.1 release also contains a fix for the -pack mode for macOs and various TSAN fixes.
More importantly, those new versions harden the Marshal module against malicious inputs as described in the security announcement OSEC-2026-01.
We are encouraging you to switch to those new releases whenever possible.
Don't hesitate to report any bugs on the OCaml issue tracker and to leave comments on the discuss announcement.
See the list of changes below for more details.
Happy hacking,
-- Florian Angeletti for the OCaml team.
Installation Instructions
The base compiler can be installed as an opam switch with the following commands:
opam update
opam switch create 4.14.3
opam switch create 5.4.1
The source code for the release is also directly available on:
See full changelog
OCaml 4.14.3 (17 February 2026)
-
#12070, #12075, #13209: auto-detect whether ar support @FILE arguments at
configure-time to avoid using this feature with toolchains that do not support
it (eg FreeBSD/Darwin); backport from 5.3.
(backport by Boris Dobroslavov, original fix by Nicolás Ojeda Bär, review by
Xavier Leroy, David Allsopp, Javier Chávarri, Anil Madhavapeddy)
-
#12207, #12222: Make closure computation linear in the number of recursive
functions instead of quadratic
(Vincent Laviron, report by François Pottier, review by Nathanaëlle Courant
and Gabriel Scherer)
-
#13430, #13434: protect memory-safety on Lazy.force races
(Gabriel Scherer and Vincent Laviron, report by Edwin Török,
review by Vincent Laviron)
-
#13448, #13449: fix a code-generation bug on unsafe array accesses
at type int32, int64, nativeint, which has been introduced in OCaml 4.04.
(Gabriel Scherer, review by Nicolás Ojeda Bär and Vincent Laviron,
report by Simon Cruanes)
-
#13516: Fix regression where error conditions during bytecode initialisation
caused a segmentation fault rather than being properly reported (regression of
#5115 in #11788)
(David Allsopp, review by Nicolás Ojeda Bär)
-
#13847: On Windows, maintain a number of threads waiting on the master lock to
avoid unnecessary context switches
(Dmitry Bely, review by Antonin Décimo)
-
#14007, #14015: Fix memory corruption when an exception is raised during
demarshaling.
(Benoît Vaugon, review by David Allsopp and Gabriel Scherer)
-
OSEC-2026-01: robustify intern.c
(Xavier Leroy, review by Damien Doligez and Olivier Nicole)
OCaml 5.4.1 (17 February 2026)
Bug fixes:
-
#14010: Fix miscompilation / liveness errors for string operations
(Mark Shinwell, Xavier Clerc, review by Xavier Leroy and Gabriel Scherer)
-
#14065: Fix function signature mismatch of __tsan_func_exit with GCC 15.
Check in the configure step if the TSan provided internal builtins are the
same as what we expect, introduce caml_tsan_* wrappers for the __tsan_*
functions we use.
(Hari Hara Naveen S, report by Hari Hara Naveen S,
review by Gabriel Scherer, Antonin Décimo, Olivier Nicole)
-
#14417: Fix issue with nested packs on macOS.
(Vincent Laviron, report by Kate Deplaix, review by Gabriel Scherer)
-
#14213: Fix shadow-stack-related crashes with TSan
(Olivier Nicole, report by Nathan Taylor, review by Gabriel Scherer and
Stefan Muenzel)
-
#14255: Fix TSan bug with C calls that take many arguments
(Olivier Nicole and Miod Vallat, report by Nathan Taylor, review by Gabriel
Scherer)
-
OSEC-2026-01: robustify intern.c
(Xavier Leroy and Nicolás Ojeda Bär, review by Olivier Nicole, Mindy Preston,
Edwin Török, and Gabriel Scherer)
If you want to contribute to a new release announcement, check out the Contributing Guide on GitHub.
|