I have a snippet which type checks with OCaml 4.12.0 but does not with OCaml 4.13.0 nor OCaml 4.13.1 . I was wondering whether it was a regression or if my initial snippet was buggy.
Here is the original code which type checks with OCaml 4.12.0:
type _ t
module type S = sig type t end
type pack = Pack : 'a t * (module S with type t = 'a) -> pack
let dispatch : pack list ref = ref []
exception Not_registered
type (_,_) equal =
| Refl : 'a -> ('a,'a) equal
type equality =
{
equal: 'a 'b. ('a t * 'b t) -> ('a t,'b t) equal option
}
let equal : equality ref = ref {equal = fun _ -> None}
let get (type a) : a t -> (module S with type t = a) = fun index ->
let dispatch = !dispatch in
let rec unpack list =
match list with
| [] -> raise Not_registered
| Pack (index', (module P))::list' ->
match !equal.equal (index, index') with
| Some (Refl _) -> (module P : ( S with type t = a))
| None -> unpack list'
in
unpack dispatch
With OCaml 4.13.1 the code fails with the following error:
File "test.ml", line 28, characters 34-35:
28 | | Some (Refl _) -> (module P : ( S with type t = a))
^
Error: Signature mismatch:
Modules do not match:
sig type t = $Pack_'a end
is not included in
sig type t = P.t end
Type declarations do not match:
type t = $Pack_'a
is not included in
type t = P.t
File "test.ml", line 3, characters 20-26: Expected declaration
File "test.ml", line 3, characters 20-26: Actual declaration
I managed to write fix that type checks with OCaml 4.12, 4.13 and 4.13.1 for the get
function:
let get (type a) : a t -> (module S with type t = a) = fun index ->
let dispatch = !dispatch in
let rec unpack list : (module S with type t = a) =
match list with
| [] -> raise Not_registered
| Pack (index', (module P : (S with type t = _)))::list' ->
match !equal.equal (index, index') with
| Some (Refl _) -> (module (struct include P end) : (S with type t = _))
| None -> unpack list'
in
unpack dispatch
There are two differences: a type annotation for the function unpack
and module P
is replaced by module (struct include P end)
. I was not able to write a function which type checks for OCaml 4.13.x without the latter change.
I have read the Changelog of OCaml 4.13, but I was not able to figure out whether this is a regression or if my initial snippet was indeed buggy.