Skip to content

Commit e452ce6

Browse files
gkzfacebook-github-bot
authored andcommitted
[flow][enums] Allow strict equality comparison of abstract Flow Enums
Summary: Changelog: [feature] Allow `===` comparison of abstract Flow Enums, and also enums themselves with the same ID. Reviewed By: SamChou19815 Differential Revision: D55705473 fbshipit-source-id: 56e21c5535fcc1e92f6d34669d5cd8b650b8c9b0
1 parent 135d02c commit e452ce6

File tree

5 files changed

+58
-7
lines changed

5 files changed

+58
-7
lines changed

src/typing/flow_js.ml

+13-6
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,21 @@ let strict_equatable_error cond_context (l, r) =
134134
| (AnyT _, _)
135135
| (_, AnyT _) ->
136136
None
137-
(* No comparisons of enum objects are allowed. *)
138-
| (DefT (_, EnumObjectT _), _)
139-
| (_, DefT (_, EnumObjectT _)) ->
140-
Some (Lazy.force comparison_error)
141-
(* We allow comparison between enums of the same type. *)
137+
(* We allow comparison between enums and enum values with the same id. *)
138+
| ( DefT (_, EnumObjectT { enum_info = ConcreteEnum { enum_id = id1; _ }; _ }),
139+
DefT (_, EnumObjectT { enum_info = ConcreteEnum { enum_id = id2; _ }; _ })
140+
)
142141
| ( DefT (_, EnumValueT (ConcreteEnum { enum_id = id1; _ })),
143142
DefT (_, EnumValueT (ConcreteEnum { enum_id = id2; _ }))
144143
)
145144
when ALoc.equal_id id1 id2 ->
146145
None
146+
(* We allow comparison between abstract and concrete enums and enum values. *)
147+
| (DefT (_, EnumObjectT _), DefT (_, EnumObjectT { enum_info = AbstractEnum _; _ }))
148+
| (DefT (_, EnumObjectT { enum_info = AbstractEnum _; _ }), DefT (_, EnumObjectT _))
149+
| (DefT (_, EnumValueT _), DefT (_, EnumValueT (AbstractEnum _)))
150+
| (DefT (_, EnumValueT (AbstractEnum _)), DefT (_, EnumValueT _)) ->
151+
None
147152
(* We allow the comparison of enums to null and void outside of switches. *)
148153
| (DefT (_, EnumValueT _), DefT (_, (NullT | VoidT)))
149154
| (DefT (_, (NullT | VoidT)), DefT (_, EnumValueT _)) -> begin
@@ -155,7 +160,9 @@ let strict_equatable_error cond_context (l, r) =
155160
end
156161
(* We don't allow the comparison of enums and other types in general. *)
157162
| (DefT (_, EnumValueT _), _)
158-
| (_, DefT (_, EnumValueT _)) ->
163+
| (_, DefT (_, EnumValueT _))
164+
| (DefT (_, EnumObjectT _), _)
165+
| (_, DefT (_, EnumObjectT _)) ->
159166
Some (Lazy.force comparison_error)
160167
(* We don't check other strict equality comparisons. *)
161168
| _ -> None

tests/enums/abstract-enum-value.js

+12
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,15 @@ function g<T: string | number>(x: EnumValue<T>): T {
7878
const b: string = x.valueOf(); // OK
7979
const c: string = x; // ERROR
8080
}
81+
82+
// Strict Equality
83+
{
84+
declare const x: E;
85+
declare const y: EnumValue<>;
86+
x === y; // OK
87+
y === x; // OK
88+
89+
declare const z: EnumValue<>;
90+
y === z; // OK
91+
z === y; // OK
92+
}

tests/enums/abstract-enum.js

+11
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,14 @@ f<string, E, typeof E>(E); // OK
4040
f(E); // OK
4141

4242
f(true); // ERROR
43+
44+
// Strict Equality
45+
{
46+
declare const x: Enum<>;
47+
E === x; // OK
48+
x === E; // OK
49+
50+
declare const y: Enum<>;
51+
x === y; // OK
52+
y === x; // OK
53+
}

tests/enums/enums.exp

+18-1
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,23 @@ References:
10791079
^ [2]
10801080

10811081

1082+
Error ------------------------------------------------------------------------------------------------- equality.js:63:1
1083+
1084+
Cannot compare enum `E` [1] to enum `F` [2]. [invalid-compare]
1085+
1086+
equality.js:63:1
1087+
63| E === F; // ERROR
1088+
^
1089+
1090+
References:
1091+
equality.js:3:6
1092+
3| enum E {
1093+
^ [1]
1094+
equality.js:8:6
1095+
8| enum F {
1096+
^ [2]
1097+
1098+
10821099
Error --------------------------------------------------------------------------------------------- error-access.js:9:13
10831100

10841101
Cannot access `C` because `C` is not a member of enum `E` [1]. [invalid-enum-access]
@@ -4419,7 +4436,7 @@ References:
44194436

44204437

44214438

4422-
Found 262 errors
4439+
Found 263 errors
44234440

44244441
Only showing the most relevant union/intersection branches.
44254442
To see all branches, re-run Flow with --show-all-branches

tests/enums/equality.js

+4
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ for (; e === E.A;) {} // OK
5757
switch (true) {
5858
case s === E.A: break; // Error
5959
}
60+
61+
// Equality of enums
62+
E === E; // OK
63+
E === F; // ERROR

0 commit comments

Comments
 (0)