@@ -258,8 +258,10 @@ let is_nullary_variant (x : Types.constructor_arguments) =
258
258
let check_invariant ~is_untagged_def ~(consts : (Location.t * tag) list )
259
259
~(blocks : (Location.t * block) list ) =
260
260
let module StringSet = Set. Make (String ) in
261
- let string_literals = ref StringSet. empty in
262
- let nonstring_literals = ref StringSet. empty in
261
+ let string_literals_consts = ref StringSet. empty in
262
+ let string_literals_blocks = ref StringSet. empty in
263
+ let nonstring_literals_consts = ref StringSet. empty in
264
+ let nonstring_literals_blocks = ref StringSet. empty in
263
265
let instance_types = Hashtbl. create 1 in
264
266
let function_types = ref 0 in
265
267
let object_types = ref 0 in
@@ -268,15 +270,21 @@ let check_invariant ~is_untagged_def ~(consts : (Location.t * tag) list)
268
270
let bigint_types = ref 0 in
269
271
let boolean_types = ref 0 in
270
272
let unknown_types = ref 0 in
271
- let add_string_literal ~loc s =
272
- if StringSet. mem s ! string_literals then
273
+ let add_string_literal ~is_const ~loc s =
274
+ let set =
275
+ if is_const then string_literals_consts else string_literals_blocks
276
+ in
277
+ if StringSet. mem s ! set then
273
278
raise (Error (loc, InvalidUntaggedVariantDefinition (DuplicateLiteral s)));
274
- string_literals := StringSet. add s ! string_literals
279
+ set := StringSet. add s ! set
275
280
in
276
- let add_nonstring_literal ~loc s =
277
- if StringSet. mem s ! nonstring_literals then
281
+ let add_nonstring_literal ~is_const ~loc s =
282
+ let set =
283
+ if is_const then nonstring_literals_consts else nonstring_literals_blocks
284
+ in
285
+ if StringSet. mem s ! set then
278
286
raise (Error (loc, InvalidUntaggedVariantDefinition (DuplicateLiteral s)));
279
- nonstring_literals := StringSet. add s ! nonstring_literals
287
+ set := StringSet. add s ! set
280
288
in
281
289
let invariant loc name =
282
290
if ! unknown_types <> 0 && List. length blocks <> 1 then
@@ -302,23 +310,27 @@ let check_invariant ~is_untagged_def ~(consts : (Location.t * tag) list)
302
310
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean ));
303
311
if
304
312
! boolean_types > 0
305
- && (StringSet. mem " true" ! nonstring_literals
306
- || StringSet. mem " false" ! nonstring_literals )
313
+ && (StringSet. mem " true" ! nonstring_literals_consts
314
+ || StringSet. mem " false" ! nonstring_literals_consts )
307
315
then raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean ));
308
316
()
309
317
in
318
+ let check_literal ~is_const ~loc (literal : tag ) =
319
+ match literal.tag_type with
320
+ | Some (String s ) -> add_string_literal ~is_const ~loc s
321
+ | Some (Int i ) -> add_nonstring_literal ~is_const ~loc (string_of_int i)
322
+ | Some (Float f ) -> add_nonstring_literal ~is_const ~loc f
323
+ | Some (BigInt i ) -> add_nonstring_literal ~is_const ~loc i
324
+ | Some Null -> add_nonstring_literal ~is_const ~loc " null"
325
+ | Some Undefined -> add_nonstring_literal ~is_const ~loc " undefined"
326
+ | Some (Bool b ) ->
327
+ add_nonstring_literal ~is_const ~loc (if b then " true" else " false" )
328
+ | Some (Untagged _ ) -> ()
329
+ | None -> add_string_literal ~is_const ~loc literal.name
330
+ in
331
+
310
332
Ext_list. rev_iter consts (fun (loc , literal ) ->
311
- match literal.tag_type with
312
- | Some (String s ) -> add_string_literal ~loc s
313
- | Some (Int i ) -> add_nonstring_literal ~loc (string_of_int i)
314
- | Some (Float f ) -> add_nonstring_literal ~loc f
315
- | Some (BigInt i ) -> add_nonstring_literal ~loc i
316
- | Some Null -> add_nonstring_literal ~loc " null"
317
- | Some Undefined -> add_nonstring_literal ~loc " undefined"
318
- | Some (Bool b ) ->
319
- add_nonstring_literal ~loc (if b then " true" else " false" )
320
- | Some (Untagged _ ) -> ()
321
- | None -> add_string_literal ~loc literal.name);
333
+ check_literal ~is_const: true ~loc literal);
322
334
if is_untagged_def then
323
335
Ext_list. rev_iter blocks (fun (loc , block ) ->
324
336
match block.block_type with
@@ -338,6 +350,9 @@ let check_invariant ~is_untagged_def ~(consts : (Location.t * tag) list)
338
350
| StringType -> incr string_types);
339
351
invariant loc block.tag.name
340
352
| None -> () )
353
+ else
354
+ Ext_list. rev_iter blocks (fun (loc , block ) ->
355
+ check_literal ~is_const: false ~loc block.tag)
341
356
342
357
let get_cstr_loc_tag (cstr : Types.constructor_declaration ) =
343
358
( cstr.cd_loc,
0 commit comments