@@ -22,6 +22,7 @@ type untaggedError =
22
22
| AtMostOneFunction
23
23
| AtMostOneString
24
24
| AtMostOneNumber
25
+ | AtMostOneBoolean
25
26
| DuplicateLiteral of string
26
27
| ConstructorMoreThanOneArg of string
27
28
type error =
@@ -49,6 +50,7 @@ let report_error ppf =
49
50
| AtMostOneInstance i -> " At most one case can be a " ^ (Instance. to_string i) ^ " type."
50
51
| AtMostOneFunction -> " At most one case can be a function type."
51
52
| AtMostOneString -> " At most one case can be a string type."
53
+ | AtMostOneBoolean -> " At most one case can be a boolean type."
52
54
| AtMostOneNumber ->
53
55
" At most one case can be a number type (int or float)."
54
56
| DuplicateLiteral s -> " Duplicate literal " ^ s ^ " ."
@@ -59,6 +61,7 @@ type block_type =
59
61
| IntType
60
62
| StringType
61
63
| FloatType
64
+ | BooleanType
62
65
| InstanceType of Instance .t
63
66
| FunctionType
64
67
| ObjectType
@@ -167,6 +170,8 @@ let get_block_type_from_typ ~env (t: Types.type_expr) : block_type option =
167
170
Some IntType
168
171
| {desc = Tconstr (path , _ , _ )} when Path. same path Predef. path_float ->
169
172
Some FloatType
173
+ | {desc = Tconstr (path , _ , _ )} when Path. same path Predef. path_bool ->
174
+ Some BooleanType
170
175
| ({desc = Tconstr _ } as t ) when Ast_uncurried_utils. typeIsUncurriedFun t ->
171
176
Some FunctionType
172
177
| {desc = Tarrow _ } -> Some FunctionType
@@ -232,6 +237,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
232
237
let objectTypes = ref 0 in
233
238
let stringTypes = ref 0 in
234
239
let numberTypes = ref 0 in
240
+ let booleanTypes = ref 0 in
235
241
let unknownTypes = ref 0 in
236
242
let addStringLiteral ~loc s =
237
243
if StringSet. mem s ! string_literals then
@@ -258,6 +264,10 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
258
264
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneString ));
259
265
if ! numberTypes > 1 then
260
266
raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneNumber ));
267
+ if ! booleanTypes > 1 then
268
+ raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean ));
269
+ if ! booleanTypes > 0 && (StringSet. mem " true" ! nonstring_literals || StringSet. mem " false" ! nonstring_literals) then
270
+ raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean ));
261
271
()
262
272
in
263
273
Ext_list. rev_iter consts (fun (loc , literal ) ->
@@ -267,34 +277,27 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
267
277
| Some (Float f ) -> addNonstringLiteral ~loc f
268
278
| Some Null -> addNonstringLiteral ~loc " null"
269
279
| Some Undefined -> addNonstringLiteral ~loc " undefined"
270
- | Some (Bool b ) ->
271
- addNonstringLiteral ~loc (if b then " true" else " false" )
280
+ | Some (Bool b ) -> addNonstringLiteral ~loc (if b then " true" else " false" )
272
281
| Some (Untagged _ ) -> ()
273
282
| None -> addStringLiteral ~loc literal.name);
274
283
if isUntaggedDef then
275
284
Ext_list. rev_iter blocks (fun (loc , block ) ->
276
- let name = block.tag.name in
277
- match block.block_type with
278
- | Some UnknownType ->
279
- incr unknownTypes;
280
- invariant loc name
281
- | Some ObjectType ->
282
- incr objectTypes;
283
- invariant loc name
284
- | Some (InstanceType i ) ->
285
+ match block.block_type with
286
+ | Some block_type ->
287
+ (match block_type with
288
+ | UnknownType -> incr unknownTypes;
289
+ | ObjectType -> incr objectTypes;
290
+ | (InstanceType i ) ->
285
291
let count = Hashtbl. find_opt instanceTypes i |> Option. value ~default: 0 in
286
292
Hashtbl. replace instanceTypes i (count + 1 );
287
- invariant loc name
288
- | Some FunctionType ->
289
- incr functionTypes;
290
- invariant loc name
291
- | Some (IntType | FloatType ) ->
292
- incr numberTypes;
293
- invariant loc name
294
- | Some StringType ->
295
- incr stringTypes;
296
- invariant loc name
297
- | None -> () )
293
+ | FunctionType -> incr functionTypes;
294
+ | (IntType | FloatType ) -> incr numberTypes;
295
+ | BooleanType -> incr booleanTypes;
296
+ | StringType -> incr stringTypes;
297
+ );
298
+ invariant loc block.tag.name
299
+ | None -> ()
300
+ )
298
301
299
302
let names_from_type_variant ?(isUntaggedDef = false ) ~env
300
303
(cstrs : Types.constructor_declaration list ) =
@@ -353,6 +356,7 @@ module DynamicChecks = struct
353
356
let function_ = Untagged FunctionType |> tag_type
354
357
let string = Untagged StringType |> tag_type
355
358
let number = Untagged IntType |> tag_type
359
+ let boolean = Untagged BooleanType |> tag_type
356
360
357
361
let ( == ) x y = bin EqEqEq x y
358
362
let ( != ) x y = bin NotEqEq x y
@@ -371,6 +375,11 @@ module DynamicChecks = struct
371
375
| Int _ | Float _ -> true
372
376
| _ -> false )
373
377
in
378
+ let literals_overlaps_with_boolean () =
379
+ Ext_list. exists literal_cases (function
380
+ | Bool _ -> true
381
+ | _ -> false )
382
+ in
374
383
let literals_overlaps_with_object () =
375
384
Ext_list. exists literal_cases (function
376
385
| Null -> true
@@ -386,6 +395,8 @@ module DynamicChecks = struct
386
395
typeof e != number
387
396
| FloatType when literals_overlaps_with_number () = false ->
388
397
typeof e != number
398
+ | BooleanType when literals_overlaps_with_boolean () = false ->
399
+ typeof e != boolean
389
400
| InstanceType i -> not (is_instance i e)
390
401
| FunctionType -> typeof e != function_
391
402
| ObjectType when literals_overlaps_with_object () = false ->
@@ -394,6 +405,7 @@ module DynamicChecks = struct
394
405
| StringType (* overlap *)
395
406
| IntType (* overlap *)
396
407
| FloatType (* overlap *)
408
+ | BooleanType (* overlap *)
397
409
| UnknownType -> (
398
410
(* We don't know the type of unknown, so we need to express:
399
411
this is not one of the literals *)
@@ -434,7 +446,7 @@ module DynamicChecks = struct
434
446
let add_runtime_type_check ~tag_type ~(block_cases : block_type list ) x y =
435
447
let instances = Ext_list. filter_map block_cases (function InstanceType i -> Some i | _ -> None ) in
436
448
match tag_type with
437
- | Untagged (IntType | StringType | FloatType | FunctionType ) ->
449
+ | Untagged (IntType | StringType | FloatType | BooleanType | FunctionType ) ->
438
450
typeof y == x
439
451
| Untagged ObjectType ->
440
452
if instances <> [] then
0 commit comments