@@ -35,10 +35,14 @@ let reduce_compare l =
35
35
| [] -> [% expr 0 ]
36
36
| x :: xs -> List. fold_left compare_reduce x xs
37
37
38
- let wildcard_case ~ typ int_cases =
38
+ let wildcard_case ? typ int_cases =
39
39
let loc = ! Ast_helper. default_loc in
40
+ let typ = match typ with
41
+ | Some typ -> typ
42
+ | None -> [% type : _] (* don't constrain *)
43
+ in
40
44
Exp. case [% pat? _] [% expr
41
- let to_int: [% t typ] -> Ppx_deriving_runtime. int = [% e Exp. function_ int_cases] in
45
+ let to_int ( x : [%t typ] ) = [% e Exp. match_ [ % expr x] int_cases] in
42
46
Ppx_deriving_runtime. compare (to_int lhs) (to_int rhs)]
43
47
44
48
let pattn side typs =
@@ -163,7 +167,7 @@ and expr_of_typ quoter typ =
163
167
| _ -> assert false )
164
168
in
165
169
[% expr fun lhs rhs ->
166
- [% e Exp. match_ [% expr lhs, rhs] (cases @ [wildcard_case ~typ int_cases])]]
170
+ [% e Exp. match_ [% expr lhs, rhs] (cases @ [wildcard_case int_cases])]]
167
171
| { ptyp_desc = Ptyp_var name } -> evar (" poly_" ^ name)
168
172
| { ptyp_desc = Ptyp_alias (typ , _ ) } -> expr_of_typ typ
169
173
| { ptyp_loc } ->
@@ -185,6 +189,24 @@ let sig_of_type ~options ~path type_decl =
185
189
let str_of_type ~options ~path ({ ptype_loc = loc } as type_decl ) =
186
190
parse_options options;
187
191
let quoter = Ppx_deriving. create_quoter () in
192
+ (* Capture type in helper module outside Ppx_deriving_runtime wrapper (added by sanitize).
193
+ Required for to_int constraint in variant type wildcard_case if the type name
194
+ conflicts with a Stdlib type from Ppx_deriving_runtime (e.g. bool in test).
195
+ In that case we must refer to the type being declared, not the one opened by Ppx_deriving_runtime. *)
196
+ let helper_type =
197
+ Type. mk ~loc ~attrs: [Ppx_deriving. attr_warning [% expr " -unused-type-declaration" ]]
198
+ ~params: type_decl.ptype_params
199
+ ~manifest: (Ppx_deriving. core_type_of_type_decl type_decl)
200
+ (mkloc " t" loc)
201
+ in
202
+ let helper_typ =
203
+ let name = mkloc (Longident. parse " Ppx_deriving_ord_helper.t" ) loc in
204
+ let params = match helper_type.ptype_params with
205
+ | [] -> []
206
+ | _ :: _ -> [Typ. any () ] (* match all params with single wildcard *)
207
+ in
208
+ Typ. constr name params
209
+ in
188
210
let comparator =
189
211
match type_decl.ptype_kind, type_decl.ptype_manifest with
190
212
| Ptype_abstract , Some manifest -> expr_of_typ quoter manifest
@@ -208,7 +230,7 @@ let str_of_type ~options ~path ({ ptype_loc = loc } as type_decl) =
208
230
)
209
231
in
210
232
[% expr fun lhs rhs ->
211
- [% e Exp. match_ [% expr lhs, rhs] (cases @ [wildcard_case ~typ: [ % type : Ppx_deriving_ord_helper. t] int_cases])]]
233
+ [% e Exp. match_ [% expr lhs, rhs] (cases @ [wildcard_case ~typ: helper_typ int_cases])]]
212
234
| Ptype_record labels , _ ->
213
235
let exprs =
214
236
labels |> List. map (fun ({ pld_name = { txt = name } ; _ } as pld ) ->
@@ -235,16 +257,6 @@ let str_of_type ~options ~path ({ ptype_loc = loc } as type_decl) =
235
257
core_type_of_decl ~options ~path type_decl in
236
258
let out_var =
237
259
pvar (Ppx_deriving. mangle_type_decl (`Prefix " compare" ) type_decl) in
238
- (* Capture type in helper module outside Ppx_deriving_runtime wrapper (added by sanitize).
239
- Required for to_int constraint in variant type wildcard_case if the type name
240
- conflicts with a Stdlib type from Ppx_deriving_runtime (e.g. bool in test).
241
- In that case we must refer to the type being declared, not the one opened by Ppx_deriving_runtime. *)
242
- let helper_type =
243
- Type. mk ~loc ~attrs: [Ppx_deriving. attr_warning [% expr " -unused-type-declaration" ]]
244
- ~params: type_decl.ptype_params
245
- ~manifest: (Ppx_deriving. core_type_of_type_decl type_decl)
246
- (mkloc " t" loc)
247
- in
248
260
let comparator_with_helper =
249
261
[% expr let module Ppx_deriving_ord_helper = struct [%% i Str. type_ Nonrecursive [helper_type]] end in
250
262
[% e Ppx_deriving. sanitize ~quoter (eta_expand (polymorphize comparator))]]
0 commit comments