@@ -22,6 +22,7 @@ type untaggedError =
2222 | AtMostOneFunction
2323 | AtMostOneString
2424 | AtMostOneNumber
25+ | AtMostOneBoolean
2526 | DuplicateLiteral of string
2627 | ConstructorMoreThanOneArg of string
2728type error =
@@ -49,6 +50,7 @@ let report_error ppf =
4950 | AtMostOneInstance i -> " At most one case can be a " ^ (Instance. to_string i) ^ " type."
5051 | AtMostOneFunction -> " At most one case can be a function type."
5152 | AtMostOneString -> " At most one case can be a string type."
53+ | AtMostOneBoolean -> " At most one case can be a boolean type."
5254 | AtMostOneNumber ->
5355 " At most one case can be a number type (int or float)."
5456 | DuplicateLiteral s -> " Duplicate literal " ^ s ^ " ."
@@ -59,6 +61,7 @@ type block_type =
5961 | IntType
6062 | StringType
6163 | FloatType
64+ | BooleanType
6265 | InstanceType of Instance .t
6366 | FunctionType
6467 | ObjectType
@@ -167,6 +170,8 @@ let get_block_type_from_typ ~env (t: Types.type_expr) : block_type option =
167170 Some IntType
168171 | {desc = Tconstr (path , _ , _ )} when Path. same path Predef. path_float ->
169172 Some FloatType
173+ | {desc = Tconstr (path , _ , _ )} when Path. same path Predef. path_bool ->
174+ Some BooleanType
170175 | ({desc = Tconstr _ } as t ) when Ast_uncurried_utils. typeIsUncurriedFun t ->
171176 Some FunctionType
172177 | {desc = Tarrow _ } -> Some FunctionType
@@ -232,6 +237,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
232237 let objectTypes = ref 0 in
233238 let stringTypes = ref 0 in
234239 let numberTypes = ref 0 in
240+ let booleanTypes = ref 0 in
235241 let unknownTypes = ref 0 in
236242 let addStringLiteral ~loc s =
237243 if StringSet. mem s ! string_literals then
@@ -258,6 +264,10 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
258264 raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneString ));
259265 if ! numberTypes > 1 then
260266 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 ));
261271 ()
262272 in
263273 Ext_list. rev_iter consts (fun (loc , literal ) ->
@@ -267,34 +277,27 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list)
267277 | Some (Float f ) -> addNonstringLiteral ~loc f
268278 | Some Null -> addNonstringLiteral ~loc " null"
269279 | 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" )
272281 | Some (Untagged _ ) -> ()
273282 | None -> addStringLiteral ~loc literal.name);
274283 if isUntaggedDef then
275284 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 ) ->
285291 let count = Hashtbl. find_opt instanceTypes i |> Option. value ~default: 0 in
286292 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+ )
298301
299302let names_from_type_variant ?(isUntaggedDef = false ) ~env
300303 (cstrs : Types.constructor_declaration list ) =
@@ -353,6 +356,7 @@ module DynamicChecks = struct
353356 let function_ = Untagged FunctionType |> tag_type
354357 let string = Untagged StringType |> tag_type
355358 let number = Untagged IntType |> tag_type
359+ let boolean = Untagged BooleanType |> tag_type
356360
357361 let ( == ) x y = bin EqEqEq x y
358362 let ( != ) x y = bin NotEqEq x y
@@ -371,6 +375,11 @@ module DynamicChecks = struct
371375 | Int _ | Float _ -> true
372376 | _ -> false )
373377 in
378+ let literals_overlaps_with_boolean () =
379+ Ext_list. exists literal_cases (function
380+ | Bool _ -> true
381+ | _ -> false )
382+ in
374383 let literals_overlaps_with_object () =
375384 Ext_list. exists literal_cases (function
376385 | Null -> true
@@ -386,6 +395,8 @@ module DynamicChecks = struct
386395 typeof e != number
387396 | FloatType when literals_overlaps_with_number () = false ->
388397 typeof e != number
398+ | BooleanType when literals_overlaps_with_boolean () = false ->
399+ typeof e != boolean
389400 | InstanceType i -> not (is_instance i e)
390401 | FunctionType -> typeof e != function_
391402 | ObjectType when literals_overlaps_with_object () = false ->
@@ -394,6 +405,7 @@ module DynamicChecks = struct
394405 | StringType (* overlap *)
395406 | IntType (* overlap *)
396407 | FloatType (* overlap *)
408+ | BooleanType (* overlap *)
397409 | UnknownType -> (
398410 (* We don't know the type of unknown, so we need to express:
399411 this is not one of the literals *)
@@ -434,7 +446,7 @@ module DynamicChecks = struct
434446 let add_runtime_type_check ~tag_type ~(block_cases : block_type list ) x y =
435447 let instances = Ext_list. filter_map block_cases (function InstanceType i -> Some i | _ -> None ) in
436448 match tag_type with
437- | Untagged (IntType | StringType | FloatType | FunctionType ) ->
449+ | Untagged (IntType | StringType | FloatType | BooleanType | FunctionType ) ->
438450 typeof y == x
439451 | Untagged ObjectType ->
440452 if instances <> [] then
0 commit comments