Skip to content

ppx_deriving.make breaks on mutually recurive types #272

@shonfeder

Description

@shonfeder

In ex.ml

module Ex = struct
  type t = {a : int; b: s}
  [@@deriving make]
  and s = t list
end

With the dune file:

(library
 (name ex)
 (modules ex)
 (preprocess (pps ppx_deriving.make)))

dune build gives

$ dune build                    
File "ex.ml", line 5, characters 2-16:
5 |   and s = t list
      ^^^^^^^^^^^^^^
Error: make can be derived only for record types

If we put another deriving annotation on s and swap the order the types are declared, the compilation goes thru but the make annotation is ignored:

module Ex = struct
  type s = t list
  [@@deriving show]

  and t = {a : int; b: s}
  [@@deriving make]
end

Which produces

[@@@ocaml.ppx.context
  {
    tool_name = "ppx_driver";
    include_dirs = [];
    load_path = [];
    open_modules = [];
    for_package = None;
    debug = false;
    use_threads = false;
    use_vmthreads = false;
    recursive_types = false;
    principal = false;
    transparent_modules = false;
    unboxed_types = false;
    unsafe_string = false;
    cookies = [("library-name", "ex")]
  }]
module Ex =
  struct
    type s = t list[@@deriving show]
    and t = {
      a: int ;
      b: s }[@@deriving make]
    let rec pp_s :
      Ppx_deriving_runtime.Format.formatter -> s -> Ppx_deriving_runtime.unit
      =
      let __0 () = pp in
      ((let open! ((Ppx_deriving_runtime)[@ocaml.warning "-A"]) in
          fun fmt ->
            fun x ->
              Ppx_deriving_runtime.Format.fprintf fmt "@[<2>[";
              ignore
                (List.fold_left
                   (fun sep ->
                      fun x ->
                        if sep
                        then Ppx_deriving_runtime.Format.fprintf fmt ";@ ";
                        ((__0 ()) fmt) x;
                        true) false x);
              Ppx_deriving_runtime.Format.fprintf fmt "@,]@]")
        [@ocaml.warning "-A"])
    and show_s : s -> Ppx_deriving_runtime.string =
      fun x -> Ppx_deriving_runtime.Format.asprintf "%a" pp_s x[@@ocaml.warning
                                                                 "-32"]
    and pp :
      Ppx_deriving_runtime.Format.formatter -> t -> Ppx_deriving_runtime.unit
      =
      let __0 () = pp_s in
      ((let open! ((Ppx_deriving_runtime)[@ocaml.warning "-A"]) in
          fun fmt ->
            fun x ->
              Ppx_deriving_runtime.Format.fprintf fmt "@[<2>{ ";
              ((Ppx_deriving_runtime.Format.fprintf fmt "@[%s =@ " "Ex.Ex.a";
                (Ppx_deriving_runtime.Format.fprintf fmt "%d") x.a;
                Ppx_deriving_runtime.Format.fprintf fmt "@]");
               Ppx_deriving_runtime.Format.fprintf fmt ";@ ";
               Ppx_deriving_runtime.Format.fprintf fmt "@[%s =@ " "b";
               ((__0 ()) fmt) x.b;
               Ppx_deriving_runtime.Format.fprintf fmt "@]");
              Ppx_deriving_runtime.Format.fprintf fmt "@ }@]")
        [@ocaml.warning "-A"])
    and show : t -> Ppx_deriving_runtime.string =
      fun x -> Ppx_deriving_runtime.Format.asprintf "%a" pp x[@@ocaml.warning
                                                               "-32"]
  end

As per dune describe pp ex.ml.

If the additional deriving annotation is not added, we get the same error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions