Skip to content

Commit

Permalink
[flow] add more SingletonNumT special-casing
Browse files Browse the repository at this point in the history
Summary:
This diff extends the work of D68337708, by filling in more cases that rely on the unsound `SingletonNumT ~> NumT_UNSOUND` coercion. Effectively, in places where we match against `NumT_UNSOUND`, we almost certainly want to match against `SingletonNUmT` as well.

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision: D68425896

fbshipit-source-id: 8be830491b9b78b9c2055c769f1791c031212a7b
  • Loading branch information
panagosg7 authored and facebook-github-bot committed Jan 23, 2025
1 parent 1e83204 commit 10559ca
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 24 deletions.
12 changes: 7 additions & 5 deletions src/typing/flow_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3748,7 +3748,7 @@ struct
rec_flow cx trace (key, ElemT (use_op, reason_lookup, l, action))
(* If we are accessing `Iterable<T>` with a number, and have `access_iterables = true`,
then output `T`. *)
| ( DefT (_, (NumGeneralT _ | NumT_UNSOUND _)),
| ( DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)),
ElemT
( use_op,
_,
Expand Down Expand Up @@ -3799,7 +3799,7 @@ struct
| None -> value
in
perform_elem_action cx trace ~use_op ~restrict_deletes:false reason_op arr value action
| ( DefT (_, (NumGeneralT _ | NumT_UNSOUND _)),
| ( DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)),
ElemT (use_op, reason, (DefT (reason_tup, ArrT arrtype) as arr), action)
) ->
let (write_action, read_action, never_union_void_on_computed_prop_access) =
Expand Down Expand Up @@ -5143,7 +5143,8 @@ struct
(***********************)
(* Number library call *)
(***********************)
| (DefT (reason, (NumGeneralT _ | NumT_UNSOUND _)), u) when primitive_promoting_use_t u ->
| (DefT (reason, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)), u)
when primitive_promoting_use_t u ->
rec_flow cx trace (get_builtin_type cx ~trace reason "Number", u)
(***********************)
(* Boolean library call *)
Expand Down Expand Up @@ -5255,8 +5256,9 @@ struct
suggestion = None;
}
)
| (DefT (reason, NumT_UNSOUND (_, (value, _))), WriteComputedObjPropCheckT { reason_key; _ })
->
| ( DefT (reason, (NumT_UNSOUND (_, (value, _)) | SingletonNumT (value, _))),
WriteComputedObjPropCheckT { reason_key; _ }
) ->
let kind = Flow_intermediate_error_types.InvalidObjKey.kind_of_num_value value in
add_output cx (Error_message.EObjectComputedPropertyAssign (reason, reason_key, kind))
| (_, WriteComputedObjPropCheckT { reason = _; reason_key; _ }) ->
Expand Down
39 changes: 27 additions & 12 deletions src/typing/flow_js_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ let ground_subtype = function
| (_, UseT (_, OpenT _)) ->
false
| (UnionT _, _) -> false
| ( DefT (_, (NumGeneralT _ | NumT_UNSOUND _)),
| ( DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)),
UseT (_, DefT (_, (NumGeneralT _ | NumT_UNSOUND _)))
)
| ( DefT (_, (StrGeneralT _ | StrT_UNSOUND _ | SingletonStrT _)),
Expand Down Expand Up @@ -2410,8 +2410,9 @@ module GetPropT_kit (F : Get_prop_helper_sig) = struct
let loc = loc_of_t elem_t in
add_output cx Error_message.(EInternal (loc, PropRefComputedLiteral));
F.error_type cx trace reason_op
| GenericT { bound = DefT (_, NumT_UNSOUND (_, (value, _))); _ }
| DefT (_, NumT_UNSOUND (_, (value, _))) ->
| GenericT
{ bound = DefT (_, (NumT_UNSOUND (_, (value, _)) | SingletonNumT (value, _))); _ }
| DefT (_, (NumT_UNSOUND (_, (value, _)) | SingletonNumT (value, _))) ->
let reason_prop = reason_of_t elem_t in
let kind = Flow_intermediate_error_types.InvalidObjKey.kind_of_num_value value in
add_output cx (Error_message.EObjectComputedPropertyAccess (reason_op, reason_prop, kind));
Expand Down Expand Up @@ -2460,7 +2461,8 @@ let array_elem_check
in
let (can_write_tuple, value, use_op) =
match l with
| DefT (index_reason, NumT_UNSOUND (_, (float_value, _))) -> begin
| DefT (index_reason, (NumT_UNSOUND (_, (float_value, _)) | SingletonNumT (float_value, _))) ->
begin
match elements with
| None -> (false, elem_t, use_op)
| Some elements ->
Expand Down Expand Up @@ -2559,8 +2561,13 @@ let propref_for_elem_t = function
let reason = replace_desc_reason (RProperty (Some name)) reason in
mk_named_prop ~reason ~from_indexed_access:true name
| OpaqueT (reason_num, { super_t = Some (DefT (_, SingletonNumT (value, raw))); _ })
| GenericT { bound = DefT (_, NumT_UNSOUND (_, (value, raw))); reason = reason_num; _ }
| DefT (reason_num, NumT_UNSOUND (_, (value, raw)))
| GenericT
{
bound = DefT (_, (NumT_UNSOUND (_, (value, raw)) | SingletonNumT (value, raw)));
reason = reason_num;
_;
}
| DefT (reason_num, (NumT_UNSOUND (_, (value, raw)) | SingletonNumT (value, raw)))
when Js_number.is_float_safe_integer value ->
let reason = replace_desc_reason (RProperty (Some (OrdinaryName raw))) reason_num in
let name = OrdinaryName (Dtoa.ecma_string_of_float value) in
Expand Down Expand Up @@ -2701,9 +2708,9 @@ let flow_unary_arith cx l reason kind =
add_output cx (Error_message.EBigIntNumCoerce reason_bigint);
AnyT.error reason
| (Plus, _) -> NumModuleT.why reason
| (BitNot, DefT (_, (NumGeneralT _ | NumT_UNSOUND _))) -> NumModuleT.why reason
| (BitNot, DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _))) -> NumModuleT.why reason
| (BitNot, DefT (_, (BigIntGeneralT _ | BigIntT_UNSOUND _))) -> BigIntModuleT.why reason
| (Update, DefT (_, (NumGeneralT _ | NumT_UNSOUND _))) -> NumModuleT.why reason
| (Update, DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _))) -> NumModuleT.why reason
| (Update, DefT (_, (BigIntGeneralT _ | BigIntT_UNSOUND _))) -> BigIntModuleT.why reason
| (_, AnyT (_, src)) ->
let src = any_mod_src_keep_placeholder Untyped src in
Expand All @@ -2727,7 +2734,10 @@ let flow_arith cx reason l r kind =
| (_, _, DefT (_, EmptyT)) ->
EmptyT.why reason
(* num <> num *)
| (_, DefT (_, (NumGeneralT _ | NumT_UNSOUND _)), DefT (_, (NumGeneralT _ | NumT_UNSOUND _))) ->
| ( _,
DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)),
DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _))
) ->
NumModuleT.why reason
| (RShift3, DefT (reason, (BigIntGeneralT _ | BigIntT_UNSOUND _)), _) ->
add_output cx (Error_message.EBigIntRShift3 reason);
Expand All @@ -2742,9 +2752,14 @@ let flow_arith cx reason l r kind =
(* str + num *)
(* num + str *)
| (Plus, DefT (_, (StrGeneralT _ | StrT_UNSOUND _)), DefT (_, (StrGeneralT _ | StrT_UNSOUND _)))
| (Plus, DefT (_, (StrGeneralT _ | StrT_UNSOUND _)), DefT (_, (NumGeneralT _ | NumT_UNSOUND _)))
| (Plus, DefT (_, (NumGeneralT _ | NumT_UNSOUND _)), DefT (_, (StrGeneralT _ | StrT_UNSOUND _)))
->
| ( Plus,
DefT (_, (StrGeneralT _ | StrT_UNSOUND _)),
DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _))
)
| ( Plus,
DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)),
DefT (_, (StrGeneralT _ | StrT_UNSOUND _))
) ->
StrModuleT.why reason
| _ ->
add_output
Expand Down
15 changes: 12 additions & 3 deletions src/typing/merge_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ let detect_sketchy_null_checks cx tast =
| DefT (_, StrT_UNSOUND _) ->
{ exists_check with string_loc = t_loc }
| DefT (_, NumGeneralT _)
| DefT (_, NumT_UNSOUND _) ->
| DefT (_, NumT_UNSOUND _)
| DefT (_, SingletonNumT _) ->
{ exists_check with number_loc = t_loc }
| DefT (_, (BigIntGeneralT _ | BigIntT_UNSOUND _)) ->
{ exists_check with bigint_loc = t_loc }
Expand Down Expand Up @@ -161,14 +162,22 @@ let detect_sketchy_null_checks cx tast =
( _,
EnumValueT
(ConcreteEnum
{ representation_t = DefT (_, (NumGeneralT _ | NumT_UNSOUND _)); _ }
{
representation_t =
DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _));
_;
}
)
)
| DefT
( _,
EnumValueT
(AbstractEnum
{ representation_t = DefT (_, (NumGeneralT _ | NumT_UNSOUND _)); _ }
{
representation_t =
DefT (_, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _));
_;
}
)
) ->
{ exists_check with enum_number_loc = t_loc }
Expand Down
9 changes: 6 additions & 3 deletions src/typing/subtyping_kit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,9 @@ module Make (Flow : INPUT) : OUTPUT = struct
add_output
cx
(Error_message.EExpectedStringLit { reason_lower = rl; reason_upper = ru; use_op })
| (DefT (rl, NumT_UNSOUND (_, (actual, _))), DefT (ru, SingletonNumT (expected, _))) ->
| ( DefT (rl, (NumT_UNSOUND (_, (actual, _)) | SingletonNumT (actual, _))),
DefT (ru, SingletonNumT (expected, _))
) ->
if expected = actual then
()
else
Expand Down Expand Up @@ -2265,7 +2267,7 @@ module Make (Flow : INPUT) : OUTPUT = struct
add_output
cx
(Error_message.EPrimitiveAsInterface { use_op; reason; interface_reason; kind = `Boolean })
| ( DefT (reason, (NumGeneralT _ | NumT_UNSOUND _)),
| ( DefT (reason, (NumGeneralT _ | NumT_UNSOUND _ | SingletonNumT _)),
DefT (interface_reason, InstanceT { inst = { inst_kind = InterfaceKind _; _ }; _ })
) ->
add_output
Expand Down Expand Up @@ -2446,7 +2448,8 @@ module Make (Flow : INPUT) : OUTPUT = struct
| DefT (_, BoolT_UNSOUND _) ->
Some "boolean"
| DefT (_, NumGeneralT _)
| DefT (_, NumT_UNSOUND _) ->
| DefT (_, NumT_UNSOUND _)
| DefT (_, SingletonNumT _) ->
Some "number"
| DefT (_, StrGeneralT _)
| DefT (_, SingletonStrT _)
Expand Down
3 changes: 2 additions & 1 deletion src/typing/type_operation_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,8 @@ module TypeAssertions = struct
| DefT (_, SingletonStrT _) ->
()
| DefT (_, NumGeneralT _)
| DefT (_, NumT_UNSOUND _) ->
| DefT (_, NumT_UNSOUND _)
| DefT (_, SingletonNumT _) ->
()
| l -> add_output cx (Error_message.EBinaryInLHS (reason_of_t l))
)
Expand Down

0 comments on commit 10559ca

Please sign in to comment.