@@ -5,6 +5,7 @@ type untaggedError =
55 | AtMostOneFunction
66 | AtMostOneString
77 | AtMostOneNumber
8+ | AtMostOneBoolean
89 | DuplicateLiteral of string
910 | ConstructorMoreThanOneArg of string
1011type error =
@@ -34,6 +35,7 @@ let report_error ppf =
3435 | AtMostOneString -> " At most one case can be a string type."
3536 | AtMostOneNumber ->
3637 " At most one case can be a number type (int or float)."
38+ | AtMostOneBoolean -> " At most one case can be a boolean type."
3739 | DuplicateLiteral s -> " Duplicate literal " ^ s ^ " ."
3840 | ConstructorMoreThanOneArg (name ) -> " Constructor " ^ name ^ " has more than one argument." )
3941
@@ -42,6 +44,7 @@ type block_type =
4244 | IntType
4345 | StringType
4446 | FloatType
47+ | BooleanType
4548 | ArrayType
4649 | FunctionType
4750 | ObjectType
@@ -137,6 +140,9 @@ let get_block_type ~env (cstr : Types.constructor_declaration) :
137140 | true , Cstr_tuple [{desc = Tconstr (path, _, _)}]
138141 when Path. same path Predef. path_float ->
139142 Some FloatType
143+ | true , Cstr_tuple [{desc = Tconstr (path, _, _)}]
144+ when Path. same path Predef. path_bool ->
145+ Some BooleanType
140146 | true , Cstr_tuple [{desc = Tconstr (path, _, _)}]
141147 when Path. same path Predef. path_array ->
142148 Some ArrayType
@@ -196,6 +202,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
196202 let functionTypes = ref 0 in
197203 let objectTypes = ref 0 in
198204 let stringTypes = ref 0 in
205+ let booleanTypes = ref 0 in
199206 let numberTypes = ref 0 in
200207 let unknownTypes = ref 0 in
201208 let addStringLiteral ~loc s =
@@ -219,6 +226,8 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
219226 raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneFunction ));
220227 if ! stringTypes > 1 then
221228 raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneString ));
229+ if ! booleanTypes > 1 then
230+ raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean ));
222231 if ! numberTypes > 1 then
223232 raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneNumber ));
224233 ()
@@ -253,6 +262,9 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
253262 | Some (IntType | FloatType ) ->
254263 incr numberTypes;
255264 invariant loc name
265+ | Some BooleanType ->
266+ incr booleanTypes;
267+ invariant loc name
256268 | Some StringType ->
257269 incr stringTypes;
258270 invariant loc name
@@ -315,6 +327,7 @@ module DynamicChecks = struct
315327 let function_ = Untagged FunctionType |> tag_type
316328 let string = Untagged StringType |> tag_type
317329 let number = Untagged IntType |> tag_type
330+ let boolean = Untagged BooleanType |> tag_type
318331
319332 let ( == ) x y = bin EqEqEq x y
320333 let ( != ) x y = bin NotEqEq x y
@@ -333,6 +346,11 @@ module DynamicChecks = struct
333346 | Int _ | Float _ -> true
334347 | _ -> false )
335348 in
349+ let literals_overlaps_with_boolean () =
350+ Ext_list. exists literal_cases (function
351+ | Bool _ -> true
352+ | _ -> false )
353+ in
336354 let literals_overlaps_with_object () =
337355 Ext_list. exists literal_cases (function
338356 | Null -> true
@@ -348,6 +366,8 @@ module DynamicChecks = struct
348366 typeof e != number
349367 | FloatType when literals_overlaps_with_number () = false ->
350368 typeof e != number
369+ | BooleanType when literals_overlaps_with_boolean () = false ->
370+ typeof e != boolean
351371 | ArrayType -> not (is_array e)
352372 | FunctionType -> typeof e != function_
353373 | ObjectType when literals_overlaps_with_object () = false ->
@@ -356,6 +376,7 @@ module DynamicChecks = struct
356376 | StringType (* overlap *)
357377 | IntType (* overlap *)
358378 | FloatType (* overlap *)
379+ | BooleanType (* overlap *)
359380 | UnknownType -> (
360381 (* We don't know the type of unknown, so we need to express:
361382 this is not one of the literals *)
@@ -396,7 +417,7 @@ module DynamicChecks = struct
396417 let add_runtime_type_check ~tag_type ~(block_cases : block_type list ) x y =
397418 let has_array () = Ext_list. exists block_cases (fun t -> t = ArrayType ) in
398419 match tag_type with
399- | Untagged (IntType | StringType | FloatType | FunctionType ) ->
420+ | Untagged (IntType | StringType | FloatType | BooleanType | FunctionType ) ->
400421 typeof y == x
401422 | Untagged ObjectType ->
402423 if has_array () then typeof y == x &&& not (is_array y) else typeof y == x
0 commit comments