@@ -4,11 +4,35 @@ open Ast_builder.Default
44open StdLabels
55open Expansion_helpers
66
7+ module Lid = struct
8+ let flatten =
9+ let rec flat accu = function
10+ | Lident s -> s :: accu
11+ | Ldot (lid , s ) -> flat (s :: accu) lid
12+ | Lapply (_ , _ ) -> failwith " Longident.flat"
13+ in
14+ fun lid -> flat [] lid
15+
16+ let unflatten l =
17+ match l with
18+ | [] -> None
19+ | hd :: tl ->
20+ Some
21+ (List. fold_left
22+ ~f: (fun p s -> Ldot (p, s))
23+ ~init: (Lident hd) tl)
24+ end
25+
726let not_supported ~loc what =
827 Location. raise_errorf ~loc " %s are not supported" what
928
1029let map_loc f a_loc = { a_loc with txt = f a_loc.txt }
1130
31+ let lident_with_optional_open ?opn label =
32+ match opn with
33+ | Some { txt = lid ; _ } -> Longident. Ldot (lid, label)
34+ | None -> lident label
35+
1236let gen_bindings ~loc prefix n =
1337 List. split
1438 (List. init ~len: n ~f: (fun i ->
@@ -129,13 +153,14 @@ module Schema = struct
129153 | Rinherit _ ->
130154 not_supported ~loc: field.prf_loc " this polyvariant inherit"
131155
132- let repr_core_type ty =
156+ let rec repr_core_type ty =
133157 let loc = ty.ptyp_loc in
134158 match ty.ptyp_desc with
135159 | Ptyp_tuple ts -> `Ptyp_tuple ts
136160 | Ptyp_constr (id , ts ) -> `Ptyp_constr (id, ts)
137161 | Ptyp_var txt -> `Ptyp_var { txt; loc = ty.ptyp_loc }
138162 | Ptyp_variant (fs , Closed, None) -> `Ptyp_variant fs
163+ | Ptyp_open (id , ct ) -> `Ptyp_open (id, repr_core_type ct)
139164 | Ptyp_variant _ -> not_supported ~loc " non closed polyvariants"
140165 | Ptyp_arrow _ -> not_supported ~loc " function types"
141166 | Ptyp_any -> not_supported ~loc " type placeholders"
@@ -246,11 +271,31 @@ module Schema = struct
246271
247272 method private derive_of_core_type' t =
248273 let loc = t.ptyp_loc in
249- match repr_core_type t with
274+ self#derive_of_core_type_repr ~loc t (repr_core_type t)
275+
276+ method private derive_of_core_type_repr ?opn ~loc t repr =
277+ match repr with
250278 | `Ptyp_tuple ts -> As_fun (self#derive_of_tuple t ts)
251279 | `Ptyp_var label ->
252- As_val (ederiver self#name (map_loc lident label))
280+ As_val
281+ (ederiver self#name
282+ (map_loc (lident_with_optional_open ?opn) label))
283+ | `Ptyp_open (_ , `Ptyp_open _ ) -> assert false
284+ | `Ptyp_open (lid , ct ) ->
285+ self#derive_of_core_type_repr ~opn: lid ~loc t ct
253286 | `Ptyp_constr (id , ts ) ->
287+ let id =
288+ match opn with
289+ | Some { txt = lid ; loc } ->
290+ {
291+ txt =
292+ Lid. flatten lid @ Lid. flatten id.txt
293+ |> Lid. unflatten
294+ |> Option. get;
295+ loc;
296+ }
297+ | None -> id
298+ in
254299 self#derive_type_ref' self#name ~loc id ts
255300 | `Ptyp_variant fs -> As_fun (self#derive_of_polyvariant t fs)
256301
0 commit comments