[ANN] ppx_deriving.6.0.2 and ppx_deriving_yojson.3.8.0

My quick suspicion is that this isn’t specific to ppx_deriving_yojson’s strict flag, but rather about the placement of [@@deriving] attributes in recursive type declarations.

In ppxlib, the deriver is given all the type declarations in a set of mutual declarations simultaneously as a list, so only the [@@deriving] attribute after all of them would actually derive for all the types in the set, if I remember correctly. I don’t know if the intermediate attribute is even handled in such case.

Maybe the old ppx_deriving transformation somehow worked differently. I think I have only ever seen the attribute attached to the entire set, which is also what ppx_deriving_yojson tests show: ppx_deriving_yojson/src_test/test_ppx_yojson.ml at 61f2d63138ec1efea0a3fb4afa682f40497ec380 · ocaml-ppx/ppx_deriving_yojson · GitHub.

EDIT: Indeed ppx_deriving transformation has some interesting logic around this: ppx_deriving/src/api/ppx_deriving.cppo.ml at 32f7c31ecfcbca6d53f3655a00e8852f4751123e · ocaml-ppx/ppx_deriving · GitHub and ppx_deriving/src/api/ppx_deriving.cppo.ml at 32f7c31ecfcbca6d53f3655a00e8852f4751123e · ocaml-ppx/ppx_deriving · GitHub,
Basically, if any declaration in the set has the attribute, the entire set is derived and the attributes of all of them are concatenated and used for each declaration.

1 Like

Indeed the ppxlib driver will apply derivers to all type declaration in a set of mutually recursive type declarations. You only need to add a [@@deriving ...] attribute once for the set and it will apply the deriver to the list of type declarations.

I’m not sure what the exact behaviour is when it comes to merging arguments accross the declarations in the set but it would indeed seem that we somehow lost the strict argument here. I’ll look into this.

In the meantime, as ppxlib manual’s recommend, I would only use a single [@@deriving ...] attribute for the whole set:

type t_ = {foo: string}
and t = t_ value
[@@deriving yojson {strict=false}]

or, given that the type aren’t actually recursive here, you can also split out the two type declarations:

type t_ = {foo: string} [@@deriving yojson {strict = false}]
type t = t_ value [@@deriving yojson]

If in your real life usecase you do happen to need setting different arguments for different type declarations from the same set, please consider opening an issue on ppxlib about this!