diff --git a/CHANGELOG.md b/CHANGELOG.md index d4d9da7b13..cb04f07a3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Use FORCE_COLOR environmental variable to force colorized output https://github.com/rescript-lang/rescript-compiler/pull/7033 - Allow spreads of variants in patterns (`| ...someVariant as v => `) when the variant spread is a subtype of the variant matched on. https://github.com/rescript-lang/rescript-compiler/pull/6721 - Fix the issue where dynamic imports are not working for function-defined externals. https://github.com/rescript-lang/rescript-compiler/pull/7060 +- Allow pattern matching on dicts. `switch someDict { | dict{"one": 1} => Js.log("one is one") }` https://github.com/rescript-lang/rescript-compiler/pull/7059 #### :bug: Bug fix diff --git a/jscomp/build_tests/super_errors/expected/dict_coercion.res.expected b/jscomp/build_tests/super_errors/expected/dict_coercion.res.expected new file mode 100644 index 0000000000..5e7889860a --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/dict_coercion.res.expected @@ -0,0 +1,10 @@ + + We've found a bug for you! + /.../fixtures/dict_coercion.res:7:10-30 + + 5 │ type fakeDict<'t> = {dictValuesType?: 't} + 6 │ + 7 │ let d = (dict :> fakeDict) + 8 │ + + Type Js.Dict.t = dict is not a subtype of fakeDict \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/dict_magic_field_on_non_dict.res.expected b/jscomp/build_tests/super_errors/expected/dict_magic_field_on_non_dict.res.expected new file mode 100644 index 0000000000..05d88219c2 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/dict_magic_field_on_non_dict.res.expected @@ -0,0 +1,13 @@ + + We've found a bug for you! + /.../fixtures/dict_magic_field_on_non_dict.res:5:6-23 + + 3 │ let foo = (fakeDict: fakeDict<'a>) => { + 4 │ switch fakeDict { + 5 │ | {someUndefinedField: 1} => Js.log("one") + 6 │ | _ => Js.log("not one") + 7 │ } + + The field someUndefinedField does not belong to type fakeDict + + This record pattern is expected to have type fakeDict<'a> \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/dict_pattern_inference.res.expected b/jscomp/build_tests/super_errors/expected/dict_pattern_inference.res.expected new file mode 100644 index 0000000000..eb2a546da9 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/dict_pattern_inference.res.expected @@ -0,0 +1,12 @@ + + We've found a bug for you! + /.../fixtures/dict_pattern_inference.res:3:27-33 + + 1 │ let foo = dict => + 2 │ switch dict { + 3 │ | dict{"one": 1, "two": "hello"} => Js.log("one") + 4 │ | _ => Js.log("not one") + 5 │ } + + This pattern matches values of type string + but a pattern was expected which matches values of type int \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/dict_pattern_inference_constrained.res.expected b/jscomp/build_tests/super_errors/expected/dict_pattern_inference_constrained.res.expected new file mode 100644 index 0000000000..ce340c0ae9 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/dict_pattern_inference_constrained.res.expected @@ -0,0 +1,17 @@ + + We've found a bug for you! + /.../fixtures/dict_pattern_inference_constrained.res:4:27-30 + + 2 ┆ switch dict { + 3 ┆ | dict{"one": 1} => + 4 ┆ let _: dict = dict + 5 ┆ Js.log("one") + 6 ┆ | _ => Js.log("not one") + + This has type: dict + But it's expected to have type: dict + + The incompatible parts: + int vs string + + You can convert int to string with Belt.Int.toString. \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/dict_pattern_regular_record.res.expected b/jscomp/build_tests/super_errors/expected/dict_pattern_regular_record.res.expected new file mode 100644 index 0000000000..69b1bb9e15 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/dict_pattern_regular_record.res.expected @@ -0,0 +1,12 @@ + + We've found a bug for you! + /.../fixtures/dict_pattern_regular_record.res:5:5-22 + + 3 │ let constrainedAsDict = (dict: x) => + 4 │ switch dict { + 5 │ | dict{"one": "one"} => Js.log("one") + 6 │ | _ => Js.log("not one") + 7 │ } + + This pattern matches values of type dict + but a pattern was expected which matches values of type x \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/dict_record_style_field_access.res.expected b/jscomp/build_tests/super_errors/expected/dict_record_style_field_access.res.expected new file mode 100644 index 0000000000..f9bcfc32dc --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/dict_record_style_field_access.res.expected @@ -0,0 +1,9 @@ + + We've found a bug for you! + /.../fixtures/dict_record_style_field_access.res:5:20-23 + + 3 │ } + 4 │ + 5 │ let x = stringDict.name + + Direct field access on a dict is not supported. Use Dict.get instead. \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/fixtures/dict_coercion.res b/jscomp/build_tests/super_errors/fixtures/dict_coercion.res new file mode 100644 index 0000000000..b58fe32d9a --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/dict_coercion.res @@ -0,0 +1,7 @@ +let dict = Js.Dict.empty() +dict->Js.Dict.set("someKey1", 1) +dict->Js.Dict.set("someKey2", 2) + +type fakeDict<'t> = {dictValuesType?: 't} + +let d = (dict :> fakeDict) diff --git a/jscomp/build_tests/super_errors/fixtures/dict_magic_field_on_non_dict.res b/jscomp/build_tests/super_errors/fixtures/dict_magic_field_on_non_dict.res new file mode 100644 index 0000000000..5f3e978589 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/dict_magic_field_on_non_dict.res @@ -0,0 +1,8 @@ +type fakeDict<'t> = {dictValuesType?: 't} + +let foo = (fakeDict: fakeDict<'a>) => { + switch fakeDict { + | {someUndefinedField: 1} => Js.log("one") + | _ => Js.log("not one") + } +} diff --git a/jscomp/build_tests/super_errors/fixtures/dict_pattern_inference.res b/jscomp/build_tests/super_errors/fixtures/dict_pattern_inference.res new file mode 100644 index 0000000000..b2b9e66b34 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/dict_pattern_inference.res @@ -0,0 +1,5 @@ +let foo = dict => + switch dict { + | dict{"one": 1, "two": "hello"} => Js.log("one") + | _ => Js.log("not one") + } diff --git a/jscomp/build_tests/super_errors/fixtures/dict_pattern_inference_constrained.res b/jscomp/build_tests/super_errors/fixtures/dict_pattern_inference_constrained.res new file mode 100644 index 0000000000..36b315487e --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/dict_pattern_inference_constrained.res @@ -0,0 +1,7 @@ +let foo = dict => + switch dict { + | dict{"one": 1} => + let _: dict = dict + Js.log("one") + | _ => Js.log("not one") + } diff --git a/jscomp/build_tests/super_errors/fixtures/dict_pattern_regular_record.res b/jscomp/build_tests/super_errors/fixtures/dict_pattern_regular_record.res new file mode 100644 index 0000000000..c5caecc489 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/dict_pattern_regular_record.res @@ -0,0 +1,7 @@ +type x = {one: int} + +let constrainedAsDict = (dict: x) => + switch dict { + | dict{"one": "one"} => Js.log("one") + | _ => Js.log("not one") + } diff --git a/jscomp/build_tests/super_errors/fixtures/dict_record_style_field_access.res b/jscomp/build_tests/super_errors/fixtures/dict_record_style_field_access.res new file mode 100644 index 0000000000..af20f04b3c --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/dict_record_style_field_access.res @@ -0,0 +1,5 @@ +let stringDict = dict{ + "name": "hello", +} + +let x = stringDict.name \ No newline at end of file diff --git a/jscomp/ml/dict_type_helpers.ml b/jscomp/ml/dict_type_helpers.ml new file mode 100644 index 0000000000..0f5a807b3d --- /dev/null +++ b/jscomp/ml/dict_type_helpers.ml @@ -0,0 +1,49 @@ +(* + An overview of the implementation of dicts in ReScript: + ### What is a dict? + Dicts are effectively an object with unknown fields, but a single known type of the values it holds. + + ### How are they implemented? + Dicts in ReScript are implemented as predefined record type, with a single (magic) field that holds + the type of the dict's values. This field is called `dictValuesType`, and it represent every possible + key in the dict. It's just an implementation detail - it's never actually exposed to the user, just + used internally. + + The compiler will route any label lookup on the dict record type to the magic field, which creates a + record with unknown keys, but of a single type. + + The reason for this seemingly convoluted implementation is that it allows us to piggyback on the + existing record pattern matching mechanism, which means we get pattern matching on dicts for free. + + ### Modifications to the type checker + We've made a few smaller modifications to the type checker to support this implementation: + + - We've added a new predefined type `dict` that is a record with a single field called `dictValuesType`. + This type is used to represent the type of the values in a dict. + - We've modified the type checker to recognize `dict` patterns, and route them to the predefined `dict` type. + This allows us to get full inference for dicts in patterns. + + ### Syntax + There's first class syntax support for dicts, both as expressions and as patterns. + A dict pattern is treated as a record pattern in the compiler and syntax, with an attriubute `@res.dictPattern` + attached to it. This attribute is used to tell the compiler that the pattern is a dict pattern, and is what + triggers the compiler to treat the dict record type differently to regular record types. + *) +let dict_magic_field_name = "dictValuesType" + +let has_dict_pattern_attribute attrs = + attrs + |> List.find_opt (fun (({txt}, _) : Parsetree.attribute) -> + txt = "res.dictPattern") + |> Option.is_some + +let has_dict_attribute attrs = + attrs + |> List.find_opt (fun (({txt}, _) : Parsetree.attribute) -> txt = "res.$dict") + |> Option.is_some + +let dict_attr : Parsetree.attribute = + (Location.mknoloc "res.$dict", Parsetree.PStr []) + +let dict_magic_field_attr : Parsetree.attribute = + (Location.mknoloc "res.$dictMagicField", Parsetree.PStr []) diff --git a/jscomp/ml/predef.ml b/jscomp/ml/predef.ml index c1fcd5ad3d..38760e67d8 100644 --- a/jscomp/ml/predef.ml +++ b/jscomp/ml/predef.ml @@ -112,6 +112,8 @@ and ident_failure = ident_create_predef_exn "Failure" and ident_ok = ident_create_predef_exn "Ok" and ident_error = ident_create_predef_exn "Error" +and ident_dict_magic_field_name = ident_create Dict_type_helpers.dict_magic_field_name + and ident_js_error = ident_create_predef_exn "JsError" and ident_not_found = ident_create_predef_exn "Not_found" @@ -218,10 +220,28 @@ let common_initial_env add_type add_extension empty_env = type_variance = [Variance.covariant; Variance.covariant]} and decl_dict = let tvar = newgenvar() in + (* Dicts are implemented as a single "magic" field record. This magic field + is the medium through which we can piggy back on the existing record pattern + matching mechanism. We do this by letting the compiler route any label lookup + for the dict record type to the magic field, which has the type of the values + of the dict. + + So, this definition is important for the dict pattern matching functionality, + but not something intended to be exposed to the user. *) {decl_abstr with + type_attributes = [Dict_type_helpers.dict_attr; (Location.mknoloc "live", Parsetree.PStr [])]; type_params = [tvar]; type_arity = 1; - type_variance = [Variance.full]} + type_variance = [Variance.full]; + type_kind = Type_record ([{ + ld_id = ident_dict_magic_field_name; + ld_attributes = [(Location.mknoloc "res.optional", Parsetree.PStr []); Dict_type_helpers.dict_magic_field_attr]; + ld_loc = Location.none; + ld_mutable = Immutable; + ld_type = newgenty (Tconstr (path_option, [tvar], ref Mnil)); + }], + Record_optional_labels [Ident.name ident_dict_magic_field_name]); + } and decl_uncurried = let tvar1, tvar2 = newgenvar(), newgenvar() in {decl_abstr with diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index 57895afe9b..e818e0ac89 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -75,6 +75,7 @@ type error = | Uncurried_arity_mismatch of type_expr * int * int | Field_not_optional of string * type_expr | Type_params_not_supported of Longident.t + | Field_access_on_dict_type exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -788,6 +789,8 @@ module NameChoice(Name : sig val get_name: t -> string val get_type: t -> type_expr val get_descrs: Env.type_descriptions -> t list + + val unsafe_do_not_use__add_with_name: t -> string -> t val unbound_name_error: Env.t -> Longident.t loc -> 'a end) = struct @@ -798,10 +801,18 @@ end) = struct | Tconstr(p, _, _) -> p | _ -> assert false - let lookup_from_type env tpath lid = + let lookup_from_type env tpath (lid : Longident.t loc) : Name.t = let descrs = get_descrs (Env.find_type_descrs tpath env) in Env.mark_type_used env (Path.last tpath) (Env.find_type tpath env); - match lid.txt with + if Path.same tpath Predef.path_dict then ( + (* [dict] Handle directing any label lookup to the magic dict field. *) + match lid.txt with + Longident.Lident s -> begin + let x = List.find (fun nd -> get_name nd = Dict_type_helpers.dict_magic_field_name) descrs in + unsafe_do_not_use__add_with_name x s + end + | _ -> raise Not_found) + else match lid.txt with Longident.Lident s -> begin try List.find (fun nd -> get_name nd = s) descrs @@ -884,6 +895,20 @@ module Label = NameChoice (struct type t = label_description let type_kind = "record" let get_name lbl = lbl.lbl_name + + let unsafe_do_not_use__add_with_name lbl name = + (* [dict] This is used in dicts and shouldn't be used anywhere else. + It adds a new field to an existing record type, to "fool" the pattern + matching into thinking the label exists. *) + let l = + {lbl with + lbl_name = name; + lbl_pos = Array.length lbl.lbl_all; + lbl_repres = Record_optional_labels [name]} in + let lbl_all_list = Array.to_list lbl.lbl_all @ [l] in + let lbl_all = Array.of_list lbl_all_list in + Ext_array.iter lbl_all (fun lbl -> lbl.lbl_all <- lbl_all); + l let get_type lbl = lbl.lbl_res let get_descrs = snd let unbound_name_error = Typetexp.unbound_label_error @@ -1040,6 +1065,8 @@ module Constructor = NameChoice (struct let type_kind = "variant" let get_name cstr = cstr.cstr_name let get_type cstr = cstr.cstr_res + + let unsafe_do_not_use__add_with_name _cstr _name = assert false let get_descrs = fst let unbound_name_error = Typetexp.unbound_constructor_error end) @@ -1348,12 +1375,17 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env | _ -> k None end | Ppat_record(lid_sp_list, closed) -> - let opath, record_ty = + let has_dict_pattern_attr = Dict_type_helpers.has_dict_pattern_attribute sp.ppat_attributes in + let opath, record_ty = ( + if has_dict_pattern_attr then ( + (* [dict] Make sure dict patterns are inferred as actual dicts *) + (Some (Predef.path_dict, Predef.path_dict), newgenty (Tconstr (Predef.path_dict, [newvar ()], ref Mnil))) + ) else try let (p0, p, _, _) = extract_concrete_record !env expected_ty in Some (p0, p), expected_ty with Not_found -> None, newvar () - in + ) in let get_jsx_component_error_info = get_jsx_component_error_info ~extract_concrete_typedecl opath !env record_ty in let process_optional_label (ld, pat) = let exp_optional_attr = check_optional_attr !env ld pat.ppat_attributes pat.ppat_loc in @@ -2983,8 +3015,16 @@ and type_label_access env srecord lid = let ty_exp = record.exp_type in let opath = try - let (p0, p, _, _) = extract_concrete_record env ty_exp in - Some(p0, p) + match extract_concrete_typedecl env ty_exp with + | (p0, _, {type_attributes}) + when Path.same p0 Predef.path_dict && Dict_type_helpers.has_dict_attribute type_attributes -> + (* [dict] Cover the case when trying to direct field access on a dict, e.g. `someDict.name`. + We need to disallow this because the fact that a dict is represented as a single magic + field record internally is just an implementation detail, and not intended to be exposed + to the user. *) + raise(Error(lid.loc, env, Field_access_on_dict_type)) + | (p0, p, {type_kind=Type_record _}) -> Some(p0, p) + | _ -> None with Not_found -> None in let labels = Typetexp.find_all_labels env lid.loc lid.txt in @@ -4101,6 +4141,8 @@ let report_error env ppf = function type_expr typ | Type_params_not_supported lid -> fprintf ppf "The type %a@ has type parameters, but type parameters is not supported here." longident lid + | Field_access_on_dict_type -> + fprintf ppf "Direct field access on a dict is not supported. Use Dict.get instead." let super_report_error_no_wrap_printing_env = report_error diff --git a/jscomp/ml/typecore.mli b/jscomp/ml/typecore.mli index d159b101c7..47d17a4336 100644 --- a/jscomp/ml/typecore.mli +++ b/jscomp/ml/typecore.mli @@ -108,6 +108,7 @@ type error = | Uncurried_arity_mismatch of type_expr * int * int | Field_not_optional of string * type_expr | Type_params_not_supported of Longident.t + | Field_access_on_dict_type exception Error of Location.t * Env.t * error exception Error_forward of Location.error diff --git a/jscomp/ml/types.ml b/jscomp/ml/types.ml index 16923025d2..3ec0bd46af 100644 --- a/jscomp/ml/types.ml +++ b/jscomp/ml/types.ml @@ -303,7 +303,7 @@ type label_description = lbl_arg: type_expr; (* Type of the argument *) lbl_mut: mutable_flag; (* Is this a mutable field? *) lbl_pos: int; (* Position in block *) - lbl_all: label_description array; (* All the labels in this type *) + mutable lbl_all: label_description array; (* All the labels in this type. This is mutable only because of a specific feature related to dicts, and should not be mutated elsewhere. *) lbl_repres: record_representation; (* Representation for this record *) lbl_private: private_flag; (* Read-only field? *) lbl_loc: Location.t; diff --git a/jscomp/ml/types.mli b/jscomp/ml/types.mli index 52ec4e8c93..c7e8f48f82 100644 --- a/jscomp/ml/types.mli +++ b/jscomp/ml/types.mli @@ -449,8 +449,7 @@ type label_description = lbl_arg: type_expr; (* Type of the argument *) lbl_mut: mutable_flag; (* Is this a mutable field? *) lbl_pos: int; (* Position in block *) - lbl_all: label_description array; (* All the labels in this type *) - lbl_repres: record_representation; (* Representation for this record *) + mutable lbl_all: label_description array; (* All the labels in this type. This is mutable only because of a specific feature related to dicts, and should not be mutated elsewhere. *) lbl_repres: record_representation; (* Representation for this record *) lbl_private: private_flag; (* Read-only field? *) lbl_loc: Location.t; lbl_attributes: Parsetree.attributes; diff --git a/jscomp/syntax/src/res_core.ml b/jscomp/syntax/src/res_core.ml index 08910341c6..a4779d7b90 100644 --- a/jscomp/syntax/src/res_core.ml +++ b/jscomp/syntax/src/res_core.ml @@ -1127,6 +1127,9 @@ let rec parse_pattern ?(alias = true) ?(or_ = true) p = | List -> Parser.next p; parse_list_pattern ~start_pos ~attrs p + | Dict -> + Parser.next p; + parse_dict_pattern ~start_pos ~attrs p | Module -> parse_module_pattern ~attrs p | Percent -> let extension = parse_extension p in @@ -1397,6 +1400,29 @@ and parse_list_pattern ~start_pos ~attrs p = let pat = make_list_pattern loc patterns None in {pat with ppat_loc = loc; ppat_attributes = attrs} +and parse_dict_pattern_row p = + match p.Parser.token with + | String s -> + let loc = mk_loc p.start_pos p.end_pos in + Parser.next p; + let fieldName = Location.mkloc (Longident.Lident s) loc in + Parser.expect Colon p; + let optional = parse_optional_label p in + let pat = parse_pattern p in + Some (fieldName, make_pattern_optional ~optional pat) + | _ -> None + +and parse_dict_pattern ~start_pos ~attrs (p : Parser.t) = + let fields = + parse_comma_delimited_region p ~grammar:DictRows ~closing:Rbrace + ~f:parse_dict_pattern_row + in + Parser.expect Rbrace p; + let loc = mk_loc start_pos p.prev_end_pos in + Ast_helper.Pat.record ~loc + ~attrs:((Location.mknoloc "res.dictPattern", PStr []) :: attrs) + fields Open + and parse_array_pattern ~attrs p = let start_pos = p.start_pos in Parser.expect Lbracket p; diff --git a/jscomp/syntax/src/res_grammar.ml b/jscomp/syntax/src/res_grammar.ml index 7e06e79c2e..35a5a498da 100644 --- a/jscomp/syntax/src/res_grammar.ml +++ b/jscomp/syntax/src/res_grammar.ml @@ -131,7 +131,7 @@ let is_signature_item_start = function let is_atomic_pattern_start = function | Token.Int _ | String _ | Codepoint _ | Backtick | Lparen | Lbracket | Lbrace - | Underscore | Lident _ | Uident _ | List | Exception | Percent -> + | Underscore | Lident _ | Uident _ | List | Dict | Exception | Percent -> true | _ -> false @@ -170,8 +170,8 @@ let is_structure_item_start = function let is_pattern_start = function | Token.Int _ | Float _ | String _ | Codepoint _ | Backtick | True | False - | Minus | Plus | Lparen | Lbracket | Lbrace | List | Underscore | Lident _ - | Uident _ | Hash | Exception | Percent | Module | At -> + | Minus | Plus | Lparen | Lbracket | Lbrace | List | Dict | Underscore + | Lident _ | Uident _ | Hash | Exception | Percent | Module | At -> true | _ -> false diff --git a/jscomp/syntax/src/res_parsetree_viewer.ml b/jscomp/syntax/src/res_parsetree_viewer.ml index 9edb373b1f..0b3b0ae857 100644 --- a/jscomp/syntax/src/res_parsetree_viewer.ml +++ b/jscomp/syntax/src/res_parsetree_viewer.ml @@ -105,6 +105,12 @@ let has_res_pat_variant_spread_attribute attrs = | _ -> false) attrs +let has_dict_pattern_attribute attrs = + attrs + |> List.find_opt (fun (({txt}, _) : Parsetree.attribute) -> + txt = "res.dictPattern") + |> Option.is_some + let collect_array_expressions expr = match expr.pexp_desc with | Pexp_array exprs -> (exprs, None) @@ -228,7 +234,7 @@ let filter_parsing_attrs attrs = ( "res.arity" | "res.braces" | "ns.braces" | "res.iflet" | "res.namedArgLoc" | "res.optional" | "res.ternary" | "res.async" | "res.await" | "res.template" | "res.taggedTemplate" - | "res.patVariantSpread" ); + | "res.patVariantSpread" | "res.dictPattern" ); }, _ ) -> false diff --git a/jscomp/syntax/src/res_parsetree_viewer.mli b/jscomp/syntax/src/res_parsetree_viewer.mli index e84691dd25..56e68a307b 100644 --- a/jscomp/syntax/src/res_parsetree_viewer.mli +++ b/jscomp/syntax/src/res_parsetree_viewer.mli @@ -28,6 +28,7 @@ val process_function_attributes : val has_await_attribute : Parsetree.attributes -> bool val has_res_pat_variant_spread_attribute : Parsetree.attributes -> bool +val has_dict_pattern_attribute : Parsetree.attributes -> bool type if_condition_kind = | If of Parsetree.expression diff --git a/jscomp/syntax/src/res_printer.ml b/jscomp/syntax/src/res_printer.ml index 507ed42034..0c53e9cc00 100644 --- a/jscomp/syntax/src/res_printer.ml +++ b/jscomp/syntax/src/res_printer.ml @@ -2416,6 +2416,25 @@ and print_pattern ~state (p : Parsetree.pattern) cmt_tbl = Doc.concat [Doc.text "..."; print_ident_path ident cmt_tbl] | Ppat_type ident -> Doc.concat [Doc.text "#..."; print_ident_path ident cmt_tbl] + | Ppat_record (rows, _) + when ParsetreeViewer.has_dict_pattern_attribute p.ppat_attributes -> + Doc.concat + [ + Doc.text "dict{"; + Doc.indent + (Doc.concat + [ + Doc.soft_line; + Doc.join + ~sep:(Doc.concat [Doc.text ","; Doc.line]) + (List.map + (fun row -> print_pattern_dict_row ~state row cmt_tbl) + rows); + ]); + Doc.if_breaks (Doc.text ",") Doc.nil; + Doc.soft_line; + Doc.rbrace; + ] | Ppat_record (rows, open_flag) -> Doc.group (Doc.concat @@ -2582,6 +2601,35 @@ and print_pattern_record_row ~state row cmt_tbl = in print_comments doc cmt_tbl loc_for_comments +and print_pattern_dict_row ~state + ((longident, pattern) : Longident.t Location.loc * Parsetree.pattern) + cmt_tbl = + let loc_for_comments = + {longident.loc with loc_end = pattern.ppat_loc.loc_end} + in + let rhs_doc = + let doc = print_pattern ~state pattern cmt_tbl in + let doc = + if Parens.pattern_record_row_rhs pattern then add_parens doc else doc + in + Doc.concat [print_optional_label pattern.ppat_attributes; doc] + in + let lbl_doc = + Doc.concat [Doc.text "\""; print_longident longident.txt; Doc.text "\""] + in + let doc = + Doc.group + (Doc.concat + [ + lbl_doc; + Doc.text ":"; + (if ParsetreeViewer.is_huggable_pattern pattern then + Doc.concat [Doc.space; rhs_doc] + else Doc.indent (Doc.concat [Doc.line; rhs_doc])); + ]) + in + print_comments doc cmt_tbl loc_for_comments + and print_expression_with_comments ~state expr cmt_tbl : Doc.t = let doc = print_expression ~state expr cmt_tbl in print_comments doc cmt_tbl expr.Parsetree.pexp_loc diff --git a/jscomp/syntax/tests/parsing/grammar/pattern/dict.res b/jscomp/syntax/tests/parsing/grammar/pattern/dict.res new file mode 100644 index 0000000000..cd938eaac5 --- /dev/null +++ b/jscomp/syntax/tests/parsing/grammar/pattern/dict.res @@ -0,0 +1,47 @@ +let someDict = dict{ + "one": "one", +} + +let dict{"one": ?one} = someDict + +let foo = () => switch someDict { +| dict{"one": "one"} => Js.log("one") +| _ => Js.log("not one") +} + +@unboxed +type rec json = + | Boolean(bool) + | @as(null) Null + | String(string) + | Number(float) + | Object(dict) + | Array(array) + +type user = { + name: string, + age?: float, +} + +let decodeUser = (json: json): option => { + switch json { + | Object(dict{ + "name": String(name), + "age": ageJson + }) => + Some({ + name, + age: ?switch ageJson { + | Number(age) => Some(age) + | _ => + /* Invalid age JSON type */ + None + }, + }) + | _ => + Js.log("Not an object.") + None + } +} + +Js.log(decodeUser(jsonParse(`{"name": "John", "age": 30}`))) \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/pattern/expected/dict.res.txt b/jscomp/syntax/tests/parsing/grammar/pattern/expected/dict.res.txt new file mode 100644 index 0000000000..752fce10ed --- /dev/null +++ b/jscomp/syntax/tests/parsing/grammar/pattern/expected/dict.res.txt @@ -0,0 +1,41 @@ +let someDict = Primitive_dict.make [|("one", {js|one|js})|] +let (({ one = ((one)[@res.optional ]);_})[@res.dictPattern ]) = someDict +let foo = + ((Function$ + (fun () -> + match someDict with + | (({ one = {js|one|js};_})[@res.dictPattern ]) -> + Js.log {js|one|js} + | _ -> Js.log {js|not one|js})) + [@res.arity 1]) +type json = + | Boolean of bool + | Null [@as null] + | String of string + | Number of float + | Object of json dict + | Array of t array [@@unboxed ] +type nonrec user = { + name: string ; + age: float [@res.optional ]} +let decodeUser = + ((Function$ + (fun (json : json) -> + (((match json with + | Object + (({ name = String name; age = ageJson;_})[@res.dictPattern ]) + -> + Some + { + name; + age = + (((match ageJson with + | Number age -> Some age + | _ -> None))[@res.optional ]) + } + | _ -> (Js.log {js|Not an object.|js}; None)) + [@res.braces ]) : user option))) + [@res.arity 1]) +;;Js.log + (decodeUser + (jsonParse (({js|{"name": "John", "age": 30}|js})[@res.template ]))) \ No newline at end of file diff --git a/jscomp/syntax/tests/printer/pattern/dict.res b/jscomp/syntax/tests/printer/pattern/dict.res new file mode 100644 index 0000000000..7bd4ee0bf5 --- /dev/null +++ b/jscomp/syntax/tests/printer/pattern/dict.res @@ -0,0 +1,49 @@ +let someDict = dict{ + "one": "one", +} + +let dict{"one": ?one} = someDict + +let foo = () => { + let _ = switch someDict { + // Comment here + | dict{ + // Comment above the pattern + "one": + // Comment right in the pattern + "one", + } => + Js.log("one") + | _ => Js.log("not one") + } + + let _ = switch someDict { + | dict{ + // foo + "one": "one", + // bar + "twoooooooooo": 2, + // baz + "three": 3, + "fooooour": 4, + "fiiiive": 5, + } => + Js.log("one") + | _ => Js.log("not one") + } + + let _ = switch someDict { + | dict{ + /* foo */ + /* baz */ "one": "one", + /* bar */ + /* baz */ "twoooooooooo": 2, + /* baz */ + /* baz */ "three": 3, + "fooooour": 4, + "fiiiive": 5, + } => + Js.log("one") + | _ => Js.log("not one") + } +} diff --git a/jscomp/syntax/tests/printer/pattern/expected/dict.res.txt b/jscomp/syntax/tests/printer/pattern/expected/dict.res.txt new file mode 100644 index 0000000000..7bd4ee0bf5 --- /dev/null +++ b/jscomp/syntax/tests/printer/pattern/expected/dict.res.txt @@ -0,0 +1,49 @@ +let someDict = dict{ + "one": "one", +} + +let dict{"one": ?one} = someDict + +let foo = () => { + let _ = switch someDict { + // Comment here + | dict{ + // Comment above the pattern + "one": + // Comment right in the pattern + "one", + } => + Js.log("one") + | _ => Js.log("not one") + } + + let _ = switch someDict { + | dict{ + // foo + "one": "one", + // bar + "twoooooooooo": 2, + // baz + "three": 3, + "fooooour": 4, + "fiiiive": 5, + } => + Js.log("one") + | _ => Js.log("not one") + } + + let _ = switch someDict { + | dict{ + /* foo */ + /* baz */ "one": "one", + /* bar */ + /* baz */ "twoooooooooo": 2, + /* baz */ + /* baz */ "three": 3, + "fooooour": 4, + "fiiiive": 5, + } => + Js.log("one") + | _ => Js.log("not one") + } +} diff --git a/jscomp/test/DictInference.res b/jscomp/test/DictInference.res index cabae911e5..a267ae2e6e 100644 --- a/jscomp/test/DictInference.res +++ b/jscomp/test/DictInference.res @@ -2,3 +2,5 @@ let dict = Js.Dict.empty() dict->Js.Dict.set("someKey1", 1) dict->Js.Dict.set("someKey2", 2) let asArray = dict->Js.Dict.values + +let _: dict = dict diff --git a/jscomp/test/DictInternalRepresentation.js b/jscomp/test/DictInternalRepresentation.js new file mode 100644 index 0000000000..641a311cdb --- /dev/null +++ b/jscomp/test/DictInternalRepresentation.js @@ -0,0 +1,28 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +'use strict'; + + +let stringDict = { + first: "hello" +}; + +let intDict = { + first: 1 +}; + +function foo() { + let first = stringDict.first; + let first$1 = first !== undefined ? first + "2" : "hello"; + console.log(first$1); + let first$2 = intDict.first; + let second = first$2 !== undefined ? first$2 + 2 | 0 : 1; + console.log(second); + let first$3 = stringDict.first; + let third = first$3 !== undefined ? first$3 + "2" : "hello"; + console.log(third); +} + +exports.stringDict = stringDict; +exports.intDict = intDict; +exports.foo = foo; +/* No side effect */ diff --git a/jscomp/test/DictInternalRepresentation.res b/jscomp/test/DictInternalRepresentation.res new file mode 100644 index 0000000000..a7ba45b640 --- /dev/null +++ b/jscomp/test/DictInternalRepresentation.res @@ -0,0 +1,26 @@ +// Make sure labels matched don't "stick" on the builtin dict type +let stringDict = dict{ + "first": "hello", +} + +let intDict = dict{ + "first": 1, +} + +let foo = () => { + let first = switch stringDict { + | dict{"first": first} => first ++ "2" + | _ => "hello" + } + Js.log(first) + let second = switch intDict { + | dict{"first": first} => first + 2 + | _ => 1 + } + Js.log(second) + let third = switch stringDict { + | dict{"first": first} => first ++ "2" + | _ => "hello" + } + Js.log(third) +} diff --git a/jscomp/test/DictTests.js b/jscomp/test/DictTests.js index 8228a11d00..5d9df63325 100644 --- a/jscomp/test/DictTests.js +++ b/jscomp/test/DictTests.js @@ -17,10 +17,47 @@ let intDict = { three: 3 }; +function inferDictByPattern(dict) { + let match = dict.one; + if (match === 1) { + let match$1 = dict.three; + if (match$1 === 3) { + let match$2 = dict.four; + if (match$2 === 4) { + dict["five"] = 5; + return; + } + + } + + } + let match$3 = dict.two; + if (match$3 === 1) { + console.log("two"); + } else { + console.log("not one"); + } +} + +function constrainedAsDict(dict) { + let match = dict.one; + if (match === 1) { + console.log("one"); + } else { + console.log("not one"); + } +} + +let PatternMatching = { + inferDictByPattern: inferDictByPattern, + constrainedAsDict: constrainedAsDict +}; + let three = 3; exports.someString = someString; exports.createdDict = createdDict; exports.three = three; exports.intDict = intDict; +exports.PatternMatching = PatternMatching; /* No side effect */ diff --git a/jscomp/test/DictTests.res b/jscomp/test/DictTests.res index abf0bad193..e1d2523cac 100644 --- a/jscomp/test/DictTests.res +++ b/jscomp/test/DictTests.res @@ -14,3 +14,22 @@ let intDict = dict{ "two": 2, "three": three, } + +module PatternMatching = { + let inferDictByPattern = dict => + switch dict { + | dict{"one": 1, "three": 3, "four": 4} => + // Make sure that the dict is of correct type + dict->Js.Dict.set("five", 5) + | dict{"two": 1} => Js.log("two") + | _ => Js.log("not one") + } + + let constrainedAsDict = (dict: dict) => + switch dict { + | dict{"one": 1} => + let _d: dict = dict + Js.log("one") + | _ => Js.log("not one") + } +} diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index 1057a91a41..db4def6feb 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -13,6 +13,7 @@ o test/Coercion.cmi test/Coercion.cmj : cc test/Coercion.res | $bsc others runti o test/DerivingAccessorsCurried.cmi test/DerivingAccessorsCurried.cmj : cc test/DerivingAccessorsCurried.res | $bsc others runtime o test/DerivingAccessorsUncurried.cmi test/DerivingAccessorsUncurried.cmj : cc test/DerivingAccessorsUncurried.res | $bsc others runtime o test/DictInference.cmi test/DictInference.cmj : cc test/DictInference.res | $bsc others runtime +o test/DictInternalRepresentation.cmi test/DictInternalRepresentation.cmj : cc test/DictInternalRepresentation.res | $bsc others runtime o test/DictTests.cmi test/DictTests.cmj : cc test/DictTests.res | $bsc others runtime o test/DisambiguateOptionalFields.cmi test/DisambiguateOptionalFields.cmj : cc test/DisambiguateOptionalFields.res | $bsc others runtime o test/DotDotDot.cmi test/DotDotDot.cmj : cc test/DotDotDot.res | $bsc others runtime @@ -623,4 +624,4 @@ o test/update_record_test.cmi test/update_record_test.cmj : cc test/update_recor o test/variant.cmi test/variant.cmj : cc test/variant.res | $bsc others runtime o test/variantsMatching.cmi test/variantsMatching.cmj : cc test/variantsMatching.res | $bsc others runtime o test/webpack_config.cmi test/webpack_config.cmj : cc test/webpack_config.res | $bsc others runtime -o test : phony test/AsInUncurriedExternals.cmi test/AsInUncurriedExternals.cmj test/Coercion.cmi test/Coercion.cmj test/DerivingAccessorsCurried.cmi test/DerivingAccessorsCurried.cmj test/DerivingAccessorsUncurried.cmi test/DerivingAccessorsUncurried.cmj test/DictInference.cmi test/DictInference.cmj test/DictTests.cmi test/DictTests.cmj test/DisambiguateOptionalFields.cmi test/DisambiguateOptionalFields.cmj test/DotDotDot.cmi test/DotDotDot.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/ExternalArity.cmi test/ExternalArity.cmj test/FFI.cmi test/FFI.cmj test/Import.cmi test/Import.cmj test/ImportAttributes.cmi test/ImportAttributes.cmj test/PartialApplicationNoRuntimeCurry.cmi test/PartialApplicationNoRuntimeCurry.cmj test/RecordCoercion.cmi test/RecordCoercion.cmj test/RecordOrObject.cmi test/RecordOrObject.cmj test/SafePromises.cmi test/SafePromises.cmj test/UncurriedAlways.cmi test/UncurriedAlways.cmj test/UncurriedExternals.cmi test/UncurriedExternals.cmj test/UncurriedPervasives.cmi test/UncurriedPervasives.cmj test/UntaggedVariants.cmi test/UntaggedVariants.cmj test/VariantCoercion.cmi test/VariantCoercion.cmj test/VariantPatternMatchingSpreads.cmi test/VariantPatternMatchingSpreads.cmj test/VariantPatternMatchingSpreadsWithPayloads.cmi test/VariantPatternMatchingSpreadsWithPayloads.cmj test/VariantSpreads.cmi test/VariantSpreads.cmj test/a.cmi test/a.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_default_value_test.cmi test/alias_default_value_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/as_inline_record_test.cmi test/as_inline_record_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_await.cmi test/async_await.cmj test/async_inline.cmi test/async_inline.cmj test/async_inside_loop.cmi test/async_inside_loop.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_float_ntest.cmi test/belt_float_ntest.cmj test/belt_hashmap_ntest.cmi test/belt_hashmap_ntest.cmj test/belt_hashset_int_ntest.cmi test/belt_hashset_int_ntest.cmj test/belt_int_ntest.cmi test/belt_int_ntest.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_list_ntest.cmi test/belt_list_ntest.cmj test/belt_mapint_ntest.cmi test/belt_mapint_ntest.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/belt_sortarray_ntest.cmi test/belt_sortarray_ntest.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/bigint_test.cmi test/bigint_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/caml_compare_bigint_test.cmi test/caml_compare_bigint_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/directives.cmi test/directives.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exotic_labels_test.cmi test/exotic_labels_test.cmj test/exponentiation_precedence_test.cmi test/exponentiation_precedence_test.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/function_directives.cmi test/function_directives.cmj test/function_directives_no_inline.cmi test/function_directives_no_inline.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5557.cmi test/gpr_5557.cmj test/gpr_5753.cmi test/gpr_5753.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_7012_test.cmi test/gpr_7012_test.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/ignore_test.cmi test/ignore_test.cmj test/ignore_uncurry_attribute.cmi test/ignore_uncurry_attribute.cmj test/import2.cmi test/import2.cmj test/import_external.cmi test/import_external.cmj test/import_side_effect.cmi test/import_side_effect.cmj test/import_side_effect_free.cmi test/import_side_effect_free.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_condition_with_pattern_matching.cmi test/inline_condition_with_pattern_matching.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/jsxv4_newtype.cmi test/jsxv4_newtype.cmj test/keep_uncurry_attribute.cmi test/keep_uncurry_attribute.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_test.cmi test/list_test.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/mario_game.cmi test/mario_game.cmj test/meth_annotation.cmi test/meth_annotation.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_assert.cmi test/node_assert.cmj test/node_path_test.cmi test/node_path_test.cmj test/node_test.cmi test/node_test.cmj test/node_test_util.cmi test/node_test_util.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/offset.cmi test/offset.cmj test/omit_trailing_undefined_in_external_calls.cmi test/omit_trailing_undefined_in_external_calls.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/queue_402.cmi test/queue_402.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/recmodule.cmi test/recmodule.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_type_spread.cmi test/record_type_spread.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_annotation.cmi test/set_annotation.cmj test/set_gen.cmi test/set_gen.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect2.cmi test/side_effect2.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_constant_compare.cmi test/string_constant_compare.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/switch_string.cmi test/switch_string.cmj test/tagged_template_test.cmi test/tagged_template_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test2.cmi test/test2.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type-coercion-free-vars.cmi test/type-coercion-free-vars.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurried_cast.cmi test/uncurried_cast.cmj test/uncurried_default.args.cmi test/uncurried_default.args.cmj test/uncurried_pipe.cmi test/uncurried_pipe.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/update_record_test.cmi test/update_record_test.cmj test/variant.cmi test/variant.cmj test/variantsMatching.cmi test/variantsMatching.cmj test/webpack_config.cmi test/webpack_config.cmj +o test : phony test/AsInUncurriedExternals.cmi test/AsInUncurriedExternals.cmj test/Coercion.cmi test/Coercion.cmj test/DerivingAccessorsCurried.cmi test/DerivingAccessorsCurried.cmj test/DerivingAccessorsUncurried.cmi test/DerivingAccessorsUncurried.cmj test/DictInference.cmi test/DictInference.cmj test/DictInternalRepresentation.cmi test/DictInternalRepresentation.cmj test/DictTests.cmi test/DictTests.cmj test/DisambiguateOptionalFields.cmi test/DisambiguateOptionalFields.cmj test/DotDotDot.cmi test/DotDotDot.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/ExternalArity.cmi test/ExternalArity.cmj test/FFI.cmi test/FFI.cmj test/Import.cmi test/Import.cmj test/ImportAttributes.cmi test/ImportAttributes.cmj test/PartialApplicationNoRuntimeCurry.cmi test/PartialApplicationNoRuntimeCurry.cmj test/RecordCoercion.cmi test/RecordCoercion.cmj test/RecordOrObject.cmi test/RecordOrObject.cmj test/SafePromises.cmi test/SafePromises.cmj test/UncurriedAlways.cmi test/UncurriedAlways.cmj test/UncurriedExternals.cmi test/UncurriedExternals.cmj test/UncurriedPervasives.cmi test/UncurriedPervasives.cmj test/UntaggedVariants.cmi test/UntaggedVariants.cmj test/VariantCoercion.cmi test/VariantCoercion.cmj test/VariantPatternMatchingSpreads.cmi test/VariantPatternMatchingSpreads.cmj test/VariantPatternMatchingSpreadsWithPayloads.cmi test/VariantPatternMatchingSpreadsWithPayloads.cmj test/VariantSpreads.cmi test/VariantSpreads.cmj test/a.cmi test/a.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_default_value_test.cmi test/alias_default_value_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/as_inline_record_test.cmi test/as_inline_record_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_await.cmi test/async_await.cmj test/async_inline.cmi test/async_inline.cmj test/async_inside_loop.cmi test/async_inside_loop.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_float_ntest.cmi test/belt_float_ntest.cmj test/belt_hashmap_ntest.cmi test/belt_hashmap_ntest.cmj test/belt_hashset_int_ntest.cmi test/belt_hashset_int_ntest.cmj test/belt_int_ntest.cmi test/belt_int_ntest.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_list_ntest.cmi test/belt_list_ntest.cmj test/belt_mapint_ntest.cmi test/belt_mapint_ntest.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/belt_sortarray_ntest.cmi test/belt_sortarray_ntest.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/bigint_test.cmi test/bigint_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/caml_compare_bigint_test.cmi test/caml_compare_bigint_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/directives.cmi test/directives.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exotic_labels_test.cmi test/exotic_labels_test.cmj test/exponentiation_precedence_test.cmi test/exponentiation_precedence_test.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/function_directives.cmi test/function_directives.cmj test/function_directives_no_inline.cmi test/function_directives_no_inline.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5557.cmi test/gpr_5557.cmj test/gpr_5753.cmi test/gpr_5753.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_7012_test.cmi test/gpr_7012_test.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/ignore_test.cmi test/ignore_test.cmj test/ignore_uncurry_attribute.cmi test/ignore_uncurry_attribute.cmj test/import2.cmi test/import2.cmj test/import_external.cmi test/import_external.cmj test/import_side_effect.cmi test/import_side_effect.cmj test/import_side_effect_free.cmi test/import_side_effect_free.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_condition_with_pattern_matching.cmi test/inline_condition_with_pattern_matching.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/jsxv4_newtype.cmi test/jsxv4_newtype.cmj test/keep_uncurry_attribute.cmi test/keep_uncurry_attribute.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_test.cmi test/list_test.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/mario_game.cmi test/mario_game.cmj test/meth_annotation.cmi test/meth_annotation.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_assert.cmi test/node_assert.cmj test/node_path_test.cmi test/node_path_test.cmj test/node_test.cmi test/node_test.cmj test/node_test_util.cmi test/node_test_util.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/offset.cmi test/offset.cmj test/omit_trailing_undefined_in_external_calls.cmi test/omit_trailing_undefined_in_external_calls.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/queue_402.cmi test/queue_402.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/recmodule.cmi test/recmodule.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_type_spread.cmi test/record_type_spread.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_annotation.cmi test/set_annotation.cmj test/set_gen.cmi test/set_gen.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect2.cmi test/side_effect2.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_constant_compare.cmi test/string_constant_compare.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/switch_string.cmi test/switch_string.cmj test/tagged_template_test.cmi test/tagged_template_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test2.cmi test/test2.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type-coercion-free-vars.cmi test/type-coercion-free-vars.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurried_cast.cmi test/uncurried_cast.cmj test/uncurried_default.args.cmi test/uncurried_default.args.cmj test/uncurried_pipe.cmi test/uncurried_pipe.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/update_record_test.cmi test/update_record_test.cmj test/variant.cmi test/variant.cmj test/variantsMatching.cmi test/variantsMatching.cmj test/webpack_config.cmi test/webpack_config.cmj