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]".
2 Likes

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

Cheers,
Nicolas

1 Like

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.

1 Like

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.