I've noticed a change in OCaml 5.5 where a local open will make the type-checker change its behaviour.
Before 5.5, the type-checker had the same behaviour regardless of the local open: optional arguments were eliminated when the function is used with the pipe operator:
$ ocaml
OCaml version 5.5.0+dev4-2026-02-25
# let f ?x ?y ~z () = z;;
val f : ?x:'a -> ?y:'b -> z:'c -> unit -> 'c = <fun>
# let a = () |> Stdlib.(f ~z:2);;
Error: This expression has type ?x:'a -> ?y:'b -> unit -> int
but an expression was expected of type unit -> 'c
The first argument is labeled ?x,
but an unlabeled argument was expected
Hint: This function application is partial, maybe some arguments are missing.
# let a = () |> f ~z:2;;
val a : int = 2
$ opam exec --sw=5.4 -- ocaml
OCaml version 5.4.0
# let f ?x ?y ~z () = z;;
val f : ?x:'a -> ?y:'b -> z:'c -> unit -> 'c = <fun>
# let a = () |> Stdlib.(f ~z:2);;
val a : int = 2
# let a = () |> f ~z:2;;
val a : int = 2
I've noticed a change in OCaml 5.5 where a local open will make the type-checker change its behaviour.
Before 5.5, the type-checker had the same behaviour regardless of the local open: optional arguments were eliminated when the function is used with the pipe operator: