# Record element types must have a representable layout

**URL:** <https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807>\
**Category:** Learning\
**Tags:** oxcaml\
**Created:** [June 13, 2025, 4:04pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807 "2025-06-13T16:04:43Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![joelreymont](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/joelreymont/32/5937_2.png) [@joelreymont](https://discuss.ocaml.org/u/joelreymont)\
**Post date:** [June 13, 2025, 4:04pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/1 "2025-06-13T16:04:43Z")

</div>

I set up a bunch of recursive modules, some of which have records inside.

I’m getting a weird error, though.

```auto
File "src/lib/ir.ml", lines 61-62, characters 6-5:
61 | ......map : Register_map.t
62 | ;................
Error: Record element types must have a representable layout.
       The layout of Register_map.t is any.
       But the layout of Register_map.t must be representable
         because it is the type of record field map.

```

Eyeballing the types below, it’s clear to me what the layout of `Register_map.t` is because `Register.t` is already defined at that point.

Why does the compiler think otherwise?

```auto
and Register : sig
  type t =
    { id : id
    ; size : int
    }
  [@@deriving sexp]
end =
  Register

and Register_map : sig
  type t = Register.t option array [@@deriving sexp]
end =
  Register_map

and Register_index : sig
  type t =
    { id : id
    ; map : Register_map.t
    ; map_index : int
    ; bit_field : Bit_field.t
    }
  [@@deriving sexp]
end =
  Register_index

```

---

<div class="post-metadata">

**Author:** ![vlaviron](https://avatars.discourse-cdn.com/v4/letter/v/ec9cab/32.png) [@vlaviron](https://discuss.ocaml.org/u/vlaviron)\
**Post date:** [June 13, 2025, 4:14pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/2 "2025-06-13T16:14:11Z")

</div>

Note for the curious: this is an OxCaml-specific error (OxCaml allows to define types whose layout is not the uniform layout of regular values, but this comes with restrictions on where these types can be used).

I’m not completely sure of what is going on (the typing of recursive modules is a notoriously complex problem), but I suspect that the signature of `Register_index` is checked under an approximated environment, where it only knows that `Register_map.t` exists but not its actual representation. The error then complains that because the representation is not known, the layout isn’t either, so it cannot be used as a record field.

If you don’t actually need the recursion, I would advise against using recursive modules (not only in OxCaml, but in OCaml in general). In this case you can at least switch to individual recursive definitions instead of mutually recursive ones.

---

<div class="post-metadata">

**Author:** ![joelreymont](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/joelreymont/32/5937_2.png) [@joelreymont](https://discuss.ocaml.org/u/joelreymont)\
**Post date:** [June 13, 2025, 4:17pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/3 "2025-06-13T16:17:59Z")

</div>

I’m using OxCaml to see source code in lldb on macOS. Unfortunately, stock OCaml has no DWARF debug info on the Mac.

The modules do need to be recursive because I’m trying to derive sexps for GADTs by hand and types then start to depend on one another.

---

<div class="post-metadata">

**Author:** ![joelreymont](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/joelreymont/32/5937_2.png) [@joelreymont](https://discuss.ocaml.org/u/joelreymont)\
**Post date:** [June 13, 2025, 4:45pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/4 "2025-06-13T16:45:30Z")

</div>

This is my compiler’s AST and these things tend to be recursive.

I guess I’ll have to give up source code in lldb for the sake of getting the job done with the stock OCaml compiler.

---

<div class="post-metadata">

**Author:** ![ccasin](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@ccasin](https://discuss.ocaml.org/u/ccasin)\
**Post date:** [June 13, 2025, 7:56pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/5 "2025-06-13T19:56:12Z")

</div>

Testing locally, I was able to reproduce this error, and adding a kind annotation to the type that was complained about fixed it. So in your example, try changing `Register_map` like this:

```ocaml
and Register_map : sig
  type t : value = Register.t option array [@@deriving sexp]
end

```

(It’s possible this won’t work, because I don’t have your complete example, but I’d be curious to have a look if not).

Another thing worth noting is that, at least in my small reproduction case, the problem goes away without the `[@@deriving sexp]`. I haven’t dug in to the generated code yet to see what’s going on in there.

As @vlaviron says, typechecking for recursive types and recursive modules is pretty tricky, and right now OxCaml will require kind annotations in a few cases where it seems like the compiler should be able to work it out.

Thanks for trying out OxCaml!

---

<div class="post-metadata">

**Author:** ![ccasin](https://avatars.discourse-cdn.com/v4/letter/c/8edcca/32.png) [@ccasin](https://discuss.ocaml.org/u/ccasin)\
**Post date:** [June 13, 2025, 8:15pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/6 "2025-06-13T20:15:22Z")

</div>

Ah, after a little more investigation, I’m pretty sure this is the result of a bug that we just found very recently (credit to Ryan Tjoa for tracking it down). He [made a PR to fix it](https://github.com/oxcaml/oxcaml/pull/4121) on the OxCaml repository, and the fix should make its way into the next release of OxCaml.

This turns out to be a bug that is also present in typechecking of recursive modules in upstream OCaml (it’s just a little harder to hit without OxCaml’s layouts), so we’ll also be making a bug fix upstream soon.

---

<div class="post-metadata">

**Author:** ![joelreymont](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/joelreymont/32/5937_2.png) [@joelreymont](https://discuss.ocaml.org/u/joelreymont)\
**Post date:** [June 14, 2025, 2:01pm UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/7 "2025-06-14T14:01:30Z")

</div>

I don’t see hit this bug when compiling with 5.3.

---

<div class="post-metadata">

**Author:** ![joelreymont](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/joelreymont/32/5937_2.png) [@joelreymont](https://discuss.ocaml.org/u/joelreymont)\
**Post date:** [June 15, 2025, 11:19am UTC](https://discuss.ocaml.org/t/record-element-types-must-have-a-representable-layout/16807/8 "2025-06-15T11:19:40Z")

</div>

It does work if I change the signature of `Register_map` as suggested.
