Skip to content

Commit fc2cf04

Browse files
committedAug 26, 2023
Support bool untagged variants
1 parent bc2840e commit fc2cf04

File tree

4 files changed

+103
-12
lines changed

4 files changed

+103
-12
lines changed
 

‎jscomp/core/js_exp_make.ml

+1
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ let tag_type = function
807807
| Untagged FloatType -> str "number"
808808
| Untagged FunctionType -> str "function"
809809
| Untagged StringType -> str "string"
810+
| Untagged BooleanType -> str "boolean"
810811
| Untagged ArrayType -> str "Array" ~delim:DNoQuotes
811812
| Untagged ObjectType -> str "object"
812813
| Untagged UnknownType ->

‎jscomp/ml/ast_untagged_variants.ml

+22-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type untaggedError =
55
| AtMostOneFunction
66
| AtMostOneString
77
| AtMostOneNumber
8+
| AtMostOneBoolean
89
| DuplicateLiteral of string
910
| ConstructorMoreThanOneArg of string
1011
type 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

‎jscomp/test/UntaggedVariants.js

+47-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎jscomp/test/UntaggedVariants.res

+33-4
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,35 @@ module WithArray = {
134134
}
135135
}
136136

137+
module WithBool = {
138+
@unboxed
139+
type t<'a> = String(string) | Float(float) | Bool(bool) | Object({name: string})
140+
141+
let classify = x =>
142+
switch x {
143+
| String(_) => "string"
144+
| Float(_) => "int"
145+
| Bool(true) => "true"
146+
| Bool(_) => "boolean"
147+
| Object({name}) => "Object" ++ name
148+
}
149+
}
150+
151+
module WithBoolAndConstants = {
152+
@unboxed
153+
type t<'a> =
154+
| Bool(bool)
155+
| @as(false) False
156+
| @as(true) True
157+
158+
let classify = x =>
159+
switch x {
160+
| True => "true"
161+
| False => "false"
162+
| Bool(_) => "boolean"
163+
}
164+
}
165+
137166
module Json = {
138167
@unboxed
139168
type rec t =
@@ -296,16 +325,16 @@ module OptionUnboxingHeuristic = {
296325

297326
module TestFunctionCase = {
298327
@unboxed
299-
type t = Array(array<int>) | Record({x:int}) | Function((. int) => int)
328+
type t = Array(array<int>) | Record({x: int}) | Function((. int) => int)
300329

301330
let classify = v =>
302331
switch v {
303332
| Record({x}) => x
304333
| Array(a) => a[0]
305-
| Function(f) => f(. 3)
334+
| Function(f) => f(. 3)
306335
}
307336

308-
let ff = Function((. x) => x+1)
337+
let ff = Function((. x) => x + 1)
309338
}
310339

311340
module ComplexPattern = {
@@ -336,4 +365,4 @@ module ComplexPattern = {
336365
| Array([True, False, Array([String("My name is"), Number(10.)])]) => Js.log("yup")
337366
| _ => Js.log("Nope...")
338367
}
339-
}
368+
}

0 commit comments

Comments
 (0)
Please sign in to comment.