This type cannot be unboxed

but I would like it to be (ocaml v5.2.0). Is there any workaround ?

module A : sig
  type 'a t
  type exist = V : 'a t -> exist [@@unboxed]
end = struct
  type 'a t = { value : 'a; }
  type exist = V : 'a t -> exist [@@unboxed]
end
[FAIL] [exec-build ocamlopt][2]: (brzo log --id 10)
File "/Users/dbuenzli/tmp/test/a.ml", line 4, characters 2-44:
4 |   type exist = V : 'a t -> exist [@@unboxed]
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This type cannot be unboxed because
       it might contain both float and non-float values,
       depending on the instantiation of the existential variable "'a".
       You should annotate it with "[@@ocaml.boxed]".

One way is by disabling the flat-float-array “hack”.

Cheers,
Nicolas

I suspect you’re already aware of those alternatives, but just in case:

  • Using a compiler configured with -no-flat-float-array will work
  • Exposing the type as type 'a t = private { value : 'a } will work

Apart from that, I have seen proposals for a [@non_float] attribute that would solve your problem properly, but I think they all failed to get through. (I found #7485, #1261, and I think someone proposed it again on the Jane Street compiler but I can’t find it.)

Looking at the type-checker code more in detail, your example would work if you could put an annotation on the 'a parameter of type 'a t that tells the type-checker that 'a t is separable (either always float or always non-float) independently of 'a. The type-checker actually tracks this property internally, so all that’s missing is syntax (like the variance and injectivity annotations) to let programmers write the annotation.

Thanks for your answers. None of that looks very enticing :–) Perhaps I’ll simply move back to boxed existentials with preallocated ones in 'a t via let rec.

If the float hack isn’t going away anytime soon, maybe we need an [@@unboxed_when_non_float] attribute instead.