Skip to content

Commit

Permalink
[flow] add experimental.natural_inference.local_primitive_literals op…
Browse files Browse the repository at this point in the history
…tion

Summary:
Adds a flag that will enable the new behavior of natural inference on primitive literals and const-vars initialized with primitive literals.

The valid values of the `experimental.natural_inference.local_primitive_literals` flowconfig option enable a two phase rollout for this behavior:
* "partial" mode enables precise inference (singleton literal types) for literals/const-variables when necessary (e.g. in the presence of annotations, `as const`, etc.)
* "full" mode additionally enables general types (`StrGeneralT`, etc.) to be inferred for literals/const-variables otherwise (instead of `StrT_UNSOUND`, etc. that is inferred today)

Changelog: [internal]

Reviewed By: gkz

Differential Revision: D70712087

fbshipit-source-id: 757ff37a87669803a1a1cc817cabbb76a8927dcc
  • Loading branch information
panagosg7 authored and facebook-github-bot committed Mar 8, 2025
1 parent 5ad243c commit 8be18ab
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/commands/commandUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,8 @@ let make_options
opt_strict_mode = strict_mode;
opt_merge_timeout;
opt_missing_module_generators = FlowConfig.missing_module_generators flowconfig;
opt_natural_inference_exports_primitive_const =
FlowConfig.natural_inference_local_primitive_literals flowconfig;
opt_no_unchecked_indexed_access = FlowConfig.no_unchecked_indexed_access flowconfig;
opt_saved_state_fetcher;
opt_saved_state_force_recheck = saved_state_options_flags.saved_state_force_recheck;
Expand Down
14 changes: 14 additions & 0 deletions src/commands/config/flowConfig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ module Opts = struct
multi_platform_extension_group_mapping: (string * string list) list;
multi_platform_ambient_supports_platform_directory_overrides: (string * string list) list;
munge_underscores: bool;
natural_inference_local_primitive_literals: Options.NaturalInferenceLevel.t;
no_flowlib: bool;
no_unchecked_indexed_access: bool;
node_main_fields: string list;
Expand Down Expand Up @@ -250,6 +251,7 @@ module Opts = struct
multi_platform_extension_group_mapping = [];
multi_platform_ambient_supports_platform_directory_overrides = [];
munge_underscores = false;
natural_inference_local_primitive_literals = Options.NaturalInferenceLevel.Off;
no_flowlib = false;
no_unchecked_indexed_access = false;
node_main_fields = ["main"];
Expand Down Expand Up @@ -1124,6 +1126,15 @@ module Opts = struct
("module.use_strict", boolean (fun opts v -> Ok { opts with modules_are_use_strict = v }));
("munge_underscores", boolean (fun opts v -> Ok { opts with munge_underscores = v }));
("name", root_name_parser);
( "experimental.natural_inference.local_primitive_literals",
enum
[
("off", Options.NaturalInferenceLevel.Off);
("partial", Options.NaturalInferenceLevel.Partial);
("full", Options.NaturalInferenceLevel.Full);
]
(fun opts v -> Ok { opts with natural_inference_local_primitive_literals = v })
);
("no_flowlib", boolean (fun opts v -> Ok { opts with no_flowlib = v }));
( "no_unchecked_indexed_access",
boolean (fun opts v -> Ok { opts with no_unchecked_indexed_access = v })
Expand Down Expand Up @@ -1894,6 +1905,9 @@ let multi_platform_ambient_supports_platform_directory_overrides c =

let munge_underscores c = c.options.Opts.munge_underscores

let natural_inference_local_primitive_literals c =
c.options.Opts.natural_inference_local_primitive_literals

let no_flowlib c = c.options.Opts.no_flowlib

let no_unchecked_indexed_access c = c.options.Opts.no_unchecked_indexed_access
Expand Down
2 changes: 2 additions & 0 deletions src/commands/config/flowConfig.mli
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ val multi_platform_ambient_supports_platform_directory_overrides :

val munge_underscores : config -> bool

val natural_inference_local_primitive_literals : config -> Options.NaturalInferenceLevel.t

val no_flowlib : config -> bool

val no_unchecked_indexed_access : config -> bool
Expand Down
11 changes: 11 additions & 0 deletions src/common/options.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ type react_rules =
| DeepReadOnlyHookReturns
| RulesOfHooks

module NaturalInferenceLevel = struct
type t =
| Off
| Partial
| Full
end

type format = {
opt_bracket_spacing: bool;
opt_single_quotes: bool;
Expand Down Expand Up @@ -128,6 +135,7 @@ type t = {
opt_module_name_mappers: (Str.regexp * string) list;
opt_modules_are_use_strict: bool;
opt_munge_underscores: bool;
opt_natural_inference_exports_primitive_const: NaturalInferenceLevel.t;
opt_no_unchecked_indexed_access: bool;
opt_node_main_fields: string list;
opt_node_package_export_conditions: string list;
Expand Down Expand Up @@ -302,6 +310,9 @@ let module_system opts = opts.opt_module

let modules_are_use_strict opts = opts.opt_modules_are_use_strict

let natural_inference_local_primitive_literals opts =
opts.opt_natural_inference_exports_primitive_const

let no_unchecked_indexed_access opts = opts.opt_no_unchecked_indexed_access

let node_main_fields opts = opts.opt_node_main_fields
Expand Down
1 change: 1 addition & 0 deletions src/flow_dot_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ let stub_metadata ~root ~checked =
max_literal_length = 100;
max_workers = 0;
missing_module_generators = [];
natural_inference_local_primitive_literals = Options.NaturalInferenceLevel.Off;
no_unchecked_indexed_access = false;
react_custom_jsx_typing = false;
react_ref_as_prop = Options.ReactRefAsProp.PartialSupport;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ let stub_metadata ~root ~checked =
max_literal_length = 100;
max_workers = 0;
missing_module_generators = [];
natural_inference_local_primitive_literals = Options.NaturalInferenceLevel.Off;
no_unchecked_indexed_access = false;
react_custom_jsx_typing = false;
react_ref_as_prop = Options.ReactRefAsProp.PartialSupport;
Expand Down
1 change: 1 addition & 0 deletions src/typing/__tests__/type_hint_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ let metadata =
max_literal_length = 100;
max_workers = 0;
missing_module_generators = [];
natural_inference_local_primitive_literals = Options.NaturalInferenceLevel.Off;
no_unchecked_indexed_access = false;
react_custom_jsx_typing = false;
react_ref_as_prop = Options.ReactRefAsProp.PartialSupport;
Expand Down
1 change: 1 addition & 0 deletions src/typing/__tests__/typed_ast_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ let metadata =
max_literal_length = 100;
max_workers = 0;
missing_module_generators = [];
natural_inference_local_primitive_literals = Options.NaturalInferenceLevel.Off;
no_unchecked_indexed_access = false;
react_custom_jsx_typing = false;
react_ref_as_prop = Options.ReactRefAsProp.PartialSupport;
Expand Down
17 changes: 17 additions & 0 deletions src/typing/context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type metadata = {
max_literal_length: int;
max_workers: int;
missing_module_generators: (Str.regexp * string) list;
natural_inference_local_primitive_literals: Options.NaturalInferenceLevel.t;
no_unchecked_indexed_access: bool;
react_custom_jsx_typing: bool;
react_ref_as_prop: Options.ReactRefAsProp.t;
Expand Down Expand Up @@ -290,6 +291,8 @@ let metadata_of_options options =
max_literal_length = Options.max_literal_length options;
max_workers = Options.max_workers options;
missing_module_generators = Options.missing_module_generators options;
natural_inference_local_primitive_literals =
Options.natural_inference_local_primitive_literals options;
no_unchecked_indexed_access = Options.no_unchecked_indexed_access options;
react_custom_jsx_typing = Options.react_custom_jsx_typing options;
react_ref_as_prop = Options.react_ref_as_prop options;
Expand Down Expand Up @@ -663,6 +666,20 @@ let max_workers cx = cx.metadata.max_workers

let missing_module_generators cx = cx.metadata.missing_module_generators

let natural_inference_local_primitive_literals_partial cx =
match cx.metadata.natural_inference_local_primitive_literals with
| Options.NaturalInferenceLevel.Off -> false
| Options.NaturalInferenceLevel.Partial
| Options.NaturalInferenceLevel.Full ->
true

let natural_inference_local_primitive_literals_full cx =
match cx.metadata.natural_inference_local_primitive_literals with
| Options.NaturalInferenceLevel.Off
| Options.NaturalInferenceLevel.Partial ->
false
| Options.NaturalInferenceLevel.Full -> true

let no_unchecked_indexed_access cx = cx.metadata.no_unchecked_indexed_access

let jsx cx = cx.metadata.jsx
Expand Down
5 changes: 5 additions & 0 deletions src/typing/context.mli
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ type metadata = {
max_literal_length: int;
max_workers: int;
missing_module_generators: (Str.regexp * string) list;
natural_inference_local_primitive_literals: Options.NaturalInferenceLevel.t;
no_unchecked_indexed_access: bool;
react_custom_jsx_typing: bool;
react_ref_as_prop: Options.ReactRefAsProp.t;
Expand Down Expand Up @@ -317,6 +318,10 @@ val max_workers : t -> int

val missing_module_generators : t -> (Str.regexp * string) list

val natural_inference_local_primitive_literals_partial : t -> bool

val natural_inference_local_primitive_literals_full : t -> bool

val no_unchecked_indexed_access : t -> bool

val jsx : t -> Options.jsx_mode
Expand Down

0 comments on commit 8be18ab

Please sign in to comment.