diff --git a/CHANGELOG.md b/CHANGELOG.md index 581b0d1b21..6d60dabe66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The `make` function of components is generated as an uncurried function. Use best effort to determine the config when formatting a file. https://github.com/rescript-lang/rescript-compiler/pull/5968 https://github.com/rescript-lang/rescript-compiler/pull/6080 https://github.com/rescript-lang/rescript-compiler/pull/6086 https://github.com/rescript-lang/rescript-compiler/pull/6087 - Customization of runtime representation of variants. This is work in progress. E.g. some restrictions on the input. See comments of the form "TODO: put restriction on the variant definitions allowed, to make sure this never happens". https://github.com/rescript-lang/rescript-compiler/pull/6095 +- Introduce untagged variants https://github.com/rescript-lang/rescript-compiler/pull/6103 #### :boom: Breaking Change diff --git a/jscomp/core/j.ml b/jscomp/core/j.ml index 815779fa2f..35edaf8e71 100644 --- a/jscomp/core/j.ml +++ b/jscomp/core/j.ml @@ -76,7 +76,7 @@ and for_ident = ident and for_direction = Js_op.direction_flag and property_map = (property_name * expression) list and length_object = Js_op.length_object -and delim = External_arg_spec.delim = | DNone | DStarJ | DJson +and delim = External_arg_spec.delim = | DNone | DStarJ | DNoQuotes and expression_desc = | Length of expression * length_object @@ -244,7 +244,7 @@ and case_clause = { comment : string option; } -and string_clause = Lambda.as_value * case_clause +and string_clause = Lambda.literal * case_clause and int_clause = int * case_clause and statement_desc = diff --git a/jscomp/core/js_dump.ml b/jscomp/core/js_dump.ml index 2a84bfe921..3e895589fe 100644 --- a/jscomp/core/js_dump.ml +++ b/jscomp/core/js_dump.ml @@ -600,7 +600,7 @@ and expression_desc cxt ~(level : int) f x : cxt = let () = match delim with | DStarJ -> P.string f ("\"" ^ txt ^ "\"") - | DJson -> P.string f txt + | DNoQuotes -> P.string f txt | DNone -> Js_dump_string.pp_string f txt in cxt @@ -751,6 +751,7 @@ and expression_desc cxt ~(level : int) f x : cxt = | Caml_block (el, _, _, ((Blk_extension | Blk_record_ext _) as ext)) -> expression_desc cxt ~level f (exn_block_as_obj ~stack:false el ext) | Caml_block (el, _, tag, Blk_record_inlined p) -> + let untagged = Ast_attributes.process_untagged p.attrs in let objs = let tails = Ext_list.combine_array_append p.fields el @@ -774,16 +775,20 @@ and expression_desc cxt ~(level : int) f x : cxt = | Undefined when is_optional f -> None | _ -> Some (f, x)) in - ( Js_op.Lit tag_name, (* TAG:xx for inline records *) - match Ast_attributes.process_as_value p.attrs with - | None -> E.str p.name - | Some as_value -> E.as_value as_value ) - :: tails + if untagged then + tails + else + (Js_op.Lit tag_name, (* TAG:xx for inline records *) + match Ast_attributes.process_as_value p.attrs with + | None -> E.str p.name + | Some literal -> E.literal literal ) + :: tails in expression_desc cxt ~level f (Object objs) | Caml_block (el, _, tag, Blk_constructor p) -> let not_is_cons = p.name <> Literals.cons in - let as_value = Ast_attributes.process_as_value p.attrs in + let literal = Ast_attributes.process_as_value p.attrs in + let untagged = Ast_attributes.process_untagged p.attrs in let tag_name = match Ast_attributes.process_tag_name p.attrs with | None -> L.tag | Some s -> s in @@ -800,17 +805,17 @@ and expression_desc cxt ~(level : int) f x : cxt = [ (name_symbol, E.str p.name) ] else []) in - if (as_value = Some AsUnboxed || not_is_cons = false) && p.num_nonconst = 1 then tails + if untagged || (not_is_cons = false) && p.num_nonconst = 1 then tails else ( Js_op.Lit tag_name, (* TAG:xx *) - match as_value with + match literal with | None -> E.str p.name - | Some as_value -> E.as_value as_value ) + | Some literal -> E.literal literal ) :: tails in let exp = match objs with - | [(_, e)] when as_value = Some AsUnboxed -> e.expression_desc - | _ when as_value = Some AsUnboxed -> assert false (* should not happen *) + | [(_, e)] when untagged -> e.expression_desc + | _ when untagged -> assert false (* should not happen *) (* TODO: put restriction on the variant definitions allowed, to make sure this never happens. *) | _ -> J.Object objs in expression_desc cxt ~level f exp @@ -1205,8 +1210,8 @@ and statement_desc top cxt f (s : J.statement_desc) : cxt = let cxt = P.paren_group f 1 (fun _ -> expression ~level:0 cxt f e) in P.space f; P.brace_vgroup f 1 (fun _ -> - let pp_as_value f (as_value: Lambda.as_value) = - let e = E.as_value as_value in + let pp_as_value f (literal: Lambda.literal) = + let e = E.literal literal in ignore @@ expression_desc cxt ~level:0 f e.expression_desc in let cxt = loop_case_clauses cxt f pp_as_value cc in match def with diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index e71db5c86a..bf9fd5b272 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -173,6 +173,9 @@ let typeof ?comment (e : t) : t = | Bool _ -> str ?comment L.js_type_boolean | _ -> { expression_desc = Typeof e; comment } +let instanceof ?comment (e0 : t) (e1: t) : t = + { expression_desc = Bin (InstanceOf, e0, e1); comment } + let new_ ?comment e0 args : t = { expression_desc = New (e0, Some args); comment } @@ -328,15 +331,21 @@ let zero_float_lit : t = let float_mod ?comment e1 e2 : J.expression = { comment; expression_desc = Bin (Mod, e1, e2) } -let as_value = function - | Lambda.AsString s -> str s ~delim:DStarJ - | AsInt i -> small_int i - | AsFloat f -> float f - | AsBool b -> bool b - | AsNull -> nil - | AsUndefined -> undefined - | AsUnboxed -> assert false (* Should not emit tags for unboxed *) - (* TODO: put restriction on the variant definitions allowed, to make sure this never happens. *) +let literal = function + | Lambda.String s -> str s ~delim:DStarJ + | Int i -> small_int i + | Float f -> float f + | Bool b -> bool b + | Null -> nil + | Undefined -> undefined + | Block IntType -> str "number" + | Block FloatType -> str "number" + | Block StringType -> str "string" + | Block Array -> str "Array" ~delim:DNoQuotes + | Block Object -> str "object" + | Block Unknown -> + (* TODO: clean up pattern mathing algo whih confuses literal with blocks *) + assert false let array_index ?comment (e0 : t) (e1 : t) : t = match (e0.expression_desc, e1.expression_desc) with @@ -762,7 +771,35 @@ let string_equal ?comment (e0 : t) (e1 : t) : t = let is_type_number ?comment (e : t) : t = string_equal ?comment (typeof e) (str "number") -let is_tag ?(has_null_undefined_other=(false, false, false)) (e : t) : t = +let rec is_a_literal_case ~(literal_cases : Lambda.literal list) ~block_cases (e:t) : t = + let is_literal_case (l:Lambda.literal) : t = bin EqEqEq e (literal l) in + let is_block_case (c:Lambda.block_type) : t = match c with + | StringType -> bin NotEqEq (typeof e) (str "string") + | IntType -> bin NotEqEq (typeof e) (str "number") + | FloatType -> bin NotEqEq (typeof e) (str "number") + | Array -> not (bin InstanceOf e (str "Array" ~delim:DNoQuotes)) + | Object -> { expression_desc = Bin (NotEqEq, typeof e, str "object"); comment=None } + | Unknown -> + (* We don't know the type of unknown, so we need to express: + this is not one of the literals *) + (match literal_cases with + | [] -> + (* this should not happen *) + assert false + | l1 :: others -> + let is_literal_1 = is_literal_case l1 in + Ext_list.fold_right others is_literal_1 (fun literal_n acc -> + bin Or (is_literal_case literal_n) acc + ) + ) + in + match block_cases with + | [c] -> is_block_case c + | c1 :: (_::_ as rest) -> + bin And (is_block_case c1) (is_a_literal_case ~literal_cases ~block_cases:rest e) + | [] -> assert false + +let is_int_tag ?(has_null_undefined_other=(false, false, false)) (e : t) : t = let (has_null, has_undefined, has_other) = has_null_undefined_other in if has_null && (has_undefined = false) && (has_other = false) then (* null *) { expression_desc = Bin (EqEqEq, e, nil); comment=None } diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index 565b03d27b..d2590e422b 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -185,7 +185,7 @@ val assign_by_exp : t -> t -> t -> t val assign : ?comment:string -> t -> t -> t -val as_value : Lambda.as_value -> t +val literal : Lambda.literal -> t val triple_equal : ?comment:string -> t -> t -> t (* TODO: reduce [triple_equal] use *) @@ -202,13 +202,16 @@ val neq_null_undefined_boolean : ?comment:string -> t -> t -> t val is_type_number : ?comment:string -> t -> t -val is_tag : ?has_null_undefined_other:(bool * bool * bool) -> t -> t +val is_int_tag : ?has_null_undefined_other:(bool * bool * bool) -> t -> t + +val is_a_literal_case : literal_cases:Lambda.literal list -> block_cases:Lambda.block_type list -> t -> t val is_type_string : ?comment:string -> t -> t val is_type_object : t -> t val typeof : ?comment:string -> t -> t +val instanceof : ?comment:string -> t -> t -> t val to_int32 : ?comment:string -> t -> t diff --git a/jscomp/core/js_of_lam_variant.ml b/jscomp/core/js_of_lam_variant.ml index 6c3b6fb499..5c8d419550 100644 --- a/jscomp/core/js_of_lam_variant.ml +++ b/jscomp/core/js_of_lam_variant.ml @@ -40,7 +40,7 @@ let eval (arg : J.expression) (dispatches : (string * string) list) : E.t = [ S.string_switch arg (Ext_list.map dispatches (fun (s, r) -> - ( Lambda.AsString s, + ( Lambda.String s, J. { switch_body = [ S.return_stmt (E.str r) ]; @@ -80,7 +80,7 @@ let eval_as_event (arg : J.expression) S.string_switch (E.poly_var_tag_access arg) (Ext_list.map dispatches (fun (s, r) -> - ( Lambda.AsString s, + ( Lambda.String s, J. { switch_body = [ S.return_stmt (E.str r) ]; @@ -108,7 +108,7 @@ let eval_as_int (arg : J.expression) (dispatches : (string * int) list) : E.t = [ S.string_switch arg (Ext_list.map dispatches (fun (s, r) -> - ( Lambda.AsString s, + ( Lambda.String s, J. { switch_body = diff --git a/jscomp/core/js_op.ml b/jscomp/core/js_op.ml index 4e40d3eb5b..abf1e7a25d 100644 --- a/jscomp/core/js_op.ml +++ b/jscomp/core/js_op.ml @@ -48,6 +48,7 @@ type binop = | Mul | Div | Mod + | InstanceOf (** note that we don't need raise [Div_by_zero] in ReScript diff --git a/jscomp/core/js_op_util.ml b/jscomp/core/js_op_util.ml index 2bbb3a34f4..6431b16fc8 100644 --- a/jscomp/core/js_op_util.ml +++ b/jscomp/core/js_op_util.ml @@ -34,7 +34,7 @@ let op_prec (op : Js_op.binop) = | Or -> (3, 3, 3) | And -> (4, 4, 4) | EqEqEq | NotEqEq -> (8, 8, 9) - | Gt | Ge | Lt | Le (* | InstanceOf *) -> (9, 9, 10) + | Gt | Ge | Lt | Le | InstanceOf -> (9, 9, 10) | Bor -> (5, 5, 5) | Bxor -> (6, 6, 6) | Band -> (7, 7, 7) @@ -73,7 +73,7 @@ let op_str (op : Js_op.binop) = | Le -> "<=" | Gt -> ">" | Ge -> ">=" -(* | InstanceOf -> "instanceof" *) + | InstanceOf -> "instanceof" let op_int_str (op : Js_op.int_op) = match op with diff --git a/jscomp/core/js_stmt_make.ml b/jscomp/core/js_stmt_make.ml index 4ce4a8ddab..0636f33e0b 100644 --- a/jscomp/core/js_stmt_make.ml +++ b/jscomp/core/js_stmt_make.ml @@ -129,16 +129,18 @@ let int_switch ?(comment : string option) let string_switch ?(comment : string option) ?(declaration : (J.property * Ident.t) option) ?(default : J.block option) - (e : J.expression) (clauses : (Lambda.as_value * J.case_clause) list) : t = + (e : J.expression) (clauses : (Lambda.literal * J.case_clause) list) : t = match e.expression_desc with | Str {txt} -> ( let continuation = match Ext_list.find_opt clauses (fun (switch_case, x) -> match switch_case with - | AsString s -> + | String s -> if s = txt then Some x.switch_body else None - | AsInt _ | AsFloat _| AsBool _ | AsNull | AsUnboxed | AsUndefined -> None) + | Int _ | Float _| Bool _ | Null + | Undefined + | Block _ -> None) with | Some case -> case | None -> ( match default with Some x -> x | None -> assert false) diff --git a/jscomp/core/js_stmt_make.mli b/jscomp/core/js_stmt_make.mli index adda763c25..d0248625c4 100644 --- a/jscomp/core/js_stmt_make.mli +++ b/jscomp/core/js_stmt_make.mli @@ -77,7 +77,7 @@ val string_switch : ?declaration:Lam_compat.let_kind * Ident.t -> ?default:J.block -> J.expression -> - (Lambda.as_value * J.case_clause) list -> + (Lambda.literal * J.case_clause) list -> t val declare_variable : diff --git a/jscomp/core/lam_compile.ml b/jscomp/core/lam_compile.ml index 189bd1559b..24943156c0 100644 --- a/jscomp/core/lam_compile.ml +++ b/jscomp/core/lam_compile.ml @@ -153,15 +153,41 @@ let get_tag_name (sw_names : Lambda.switch_names option) = | _ -> Js_dump_lit.tag ) +let get_block_cases (sw_names : Lambda.switch_names option) = + let res = ref [] in + (match sw_names with + | None -> res := [] + | Some { blocks } -> + Ext_array.iter blocks (function + | {block_type = Some block_type} -> res := block_type :: !res + | {block_type = None} -> () + ) + ); + !res + +let get_literal_cases (sw_names : Lambda.switch_names option) = + let res = ref [] in + (match sw_names with + | None -> res := [] + | Some { consts } -> + Ext_array.iter consts (function + | {literal = Some literal} -> res := literal :: !res + | {name; literal = None} -> res := String name :: !res + ) + ); + !res + + let has_null_undefined_other (sw_names : Lambda.switch_names option) = let (null, undefined, other) = (ref false, ref false, ref false) in (match sw_names with | None -> () - | Some { consts } -> - Ext_array.iter consts (fun x -> match x.as_value with - | Some AsUndefined -> undefined := true - | Some AsNull -> null := true - | _ -> other := true)); + | Some { consts; blocks } -> + Ext_array.iter consts (fun x -> match x.literal with + | Some Undefined -> undefined := true + | Some Null -> null := true + | _ -> other := true); + ); (!null, !undefined, !other) let no_effects_const = lazy true @@ -476,7 +502,7 @@ and compile_general_cases : 'a . ('a -> Lambda.cstr_name option) -> ('a -> J.expression) -> - (J.expression -> J.expression -> J.expression) -> + ('a option -> J.expression -> 'a option -> J.expression -> J.expression) -> Lam_compile_context.t -> (?default:J.block -> ?declaration:Lam_compat.let_kind * Ident.t -> @@ -488,7 +514,7 @@ and compile_general_cases : default_case -> J.block = fun (get_cstr_name : _ -> Lambda.cstr_name option) (make_exp : _ -> J.expression) - (eq_exp : J.expression -> J.expression -> J.expression) + (eq_exp : 'a option -> J.expression -> 'a option -> J.expression -> J.expression) (cxt : Lam_compile_context.t) (switch : ?default:J.block -> @@ -512,7 +538,7 @@ and compile_general_cases : morph_declare_to_assign cxt (fun cxt define -> [ S.if_ ?declaration:define - (eq_exp switch_exp (make_exp id)) + (eq_exp None switch_exp (Some id) (make_exp id)) (Js_output.output_as_block (compile_lambda cxt lam)); ]) | [ (id, lam) ], Default x | [ (id, lam); (_, x) ], Complete -> @@ -521,7 +547,7 @@ and compile_general_cases : let then_block = Js_output.output_as_block (compile_lambda cxt lam) in [ S.if_ ?declaration:define - (eq_exp switch_exp (make_exp id)) + (eq_exp None switch_exp (Some id) (make_exp id)) then_block ~else_:else_block; ]) | _, _ -> @@ -590,23 +616,27 @@ and compile_general_cases : [ switch ?default ?declaration switch_exp body ]) -and all_cases_have_name table get_name = +and use_compile_literal_cases table get_name = List.fold_right (fun (i, lam) acc -> match get_name i, acc with - | Some {Lambda.as_value= Some as_value}, Some string_table -> Some ((as_value, lam) :: string_table) - | Some {name; as_value = None}, Some string_table -> Some ((AsString name, lam) :: string_table) + | Some {Lambda.literal = Some literal}, Some string_table -> + Some ((literal, lam) :: string_table) + | Some {name; literal = None}, Some string_table -> Some ((String name, lam) :: string_table) | _, _ -> None ) table (Some []) -and compile_cases cxt (switch_exp : E.t) table default get_name = - match all_cases_have_name table get_name with - | Some string_table -> compile_string_cases cxt switch_exp string_table default +and compile_cases ?(untagged=false) cxt (switch_exp : E.t) table default get_name = + match use_compile_literal_cases table get_name with + | Some string_table -> + if untagged + then compile_untagged_cases cxt switch_exp string_table default + else compile_string_cases cxt switch_exp string_table default | None -> compile_general_cases get_name (fun i -> match get_name i with | None -> E.small_int i - | Some {as_value = Some(AsString s)} -> E.str s + | Some {literal = Some(String s)} -> E.str s | Some {name} -> E.str name) - E.int_equal cxt + (fun _ x _ y -> E.int_equal x y) cxt (fun ?default ?declaration e clauses -> S.int_switch ?default ?declaration e clauses) switch_exp table default @@ -637,10 +667,15 @@ and compile_switch (switch_arg : Lam.t) (sw : Lam.lambda_switch) in let get_const_name i = get_const_name i sw_names in let get_block i = get_block i sw_names in + let block_cases = get_block_cases sw_names in let get_block_name i = match get_block i with | None -> None - | Some {cstr_name} -> Some cstr_name in + | Some ({block_type = Some block_type} as block) -> + Some {block.cstr_name with literal = Some (Block block_type)} + | Some ({block_type = None; cstr_name}) -> + Some cstr_name in let tag_name = get_tag_name sw_names in + let untagged = block_cases <> [] in let compile_whole (cxt : Lam_compile_context.t) = match compile_lambda { cxt with continuation = NeedValue Not_tail } switch_arg @@ -650,17 +685,22 @@ and compile_switch (switch_arg : Lam.t) (sw : Lam.lambda_switch) block @ if sw_consts_full && sw_consts = [] then - compile_cases cxt (E.tag ~name:tag_name e) sw_blocks sw_blocks_default get_block_name + compile_cases ~untagged cxt (if untagged then e else E.tag ~name:tag_name e) sw_blocks sw_blocks_default get_block_name else if sw_blocks_full && sw_blocks = [] then compile_cases cxt e sw_consts sw_num_default get_const_name else (* [e] will be used twice *) let dispatch e = - S.if_ (E.is_tag ~has_null_undefined_other:(has_null_undefined_other sw_names) e) + let is_a_literal_case = + if block_cases <> [] + then + E.is_a_literal_case ~literal_cases:(get_literal_cases sw_names) ~block_cases e + else + E.is_int_tag ~has_null_undefined_other:(has_null_undefined_other sw_names) e in + S.if_ is_a_literal_case (compile_cases cxt e sw_consts sw_num_default get_const_name) - (* default still needed, could simplified*) ~else_: - (compile_cases cxt (E.tag ~name:tag_name e) sw_blocks sw_blocks_default + (compile_cases ~untagged cxt (if untagged then e else E.tag ~name:tag_name e) sw_blocks sw_blocks_default get_block_name) in match e.expression_desc with @@ -689,22 +729,64 @@ and compile_switch (switch_arg : Lam.t) (sw : Lam.lambda_switch) | EffectCall _ | Assign _ -> Js_output.make (compile_whole lambda_cxt) and compile_string_cases cxt switch_exp table default = + let literal = function + | literal -> E.literal literal + in compile_general_cases (fun _ -> None) - E.as_value - E.string_equal cxt + literal + (fun _ x _ y -> E.string_equal x y) + cxt (fun ?default ?declaration e clauses -> S.string_switch ?default ?declaration e clauses) switch_exp table default -(* TODO: optional arguments are not good - for high order currying *) +and compile_untagged_cases cxt switch_exp table default = + let literal = function + | literal -> E.literal literal + in + let add_runtime_type_check (literal: Lambda.literal) x y = match literal with + | Block IntType + | Block StringType + | Block FloatType + | Block Object -> E.string_equal (E.typeof y) x + | Block Array -> E.instanceof y x + | Block Unknown -> + (* This should not happen because unknown must be the only non-literal case *) + assert false + | Bool _ | Float _ | Int _ | String _ | Null | Undefined -> x in + let mk_eq (i : Lambda.literal option) x j y = match i, j with + | Some literal, _ -> (* XX *) + add_runtime_type_check literal x y + | _, Some literal -> + add_runtime_type_check literal y x + | _ -> E.string_equal x y + in + let is_array (l, _) = l = Lambda.Block Array in + let body ?default ?declaration e clauses = + let array_clauses = Ext_list.filter clauses is_array in + match array_clauses with + | [(l, {J.switch_body})] when List.length clauses > 1 -> + let rest = Ext_list.filter clauses (fun c -> not (is_array c)) in + S.if_ (E.instanceof e (E.literal l)) + (switch_body) + ~else_:([S.string_switch ?default ?declaration (E.typeof e) rest]) + | _ :: _ :: _ -> assert false (* at most 1 array case *) + | _ -> + S.string_switch ?default ?declaration (E.typeof e) clauses in + compile_general_cases + (fun _ -> None) + literal + mk_eq + cxt + body + switch_exp table default and compile_stringswitch l cases default (lambda_cxt : Lam_compile_context.t) = (* TODO might better optimization according to the number of cases Be careful: we should avoid multiple evaluation of l, The [gen] can be elimiated when number of [cases] is less than 3 *) - let cases = cases |> List.map (fun (s,l) -> Lambda.AsString s, l) in + let cases = cases |> List.map (fun (s,l) -> Lambda.String s, l) in match compile_lambda { lambda_cxt with continuation = NeedValue Not_tail } l with diff --git a/jscomp/core/lam_compile_const.ml b/jscomp/core/lam_compile_const.ml index 538f209113..f4cfe70ec5 100644 --- a/jscomp/core/lam_compile_const.ml +++ b/jscomp/core/lam_compile_const.ml @@ -47,10 +47,10 @@ and translate (x : Lam_constant.t) : J.expression = | Const_js_false -> E.bool false | Const_js_null -> E.nil | Const_js_undefined -> E.undefined - | Const_int { i; comment = Pt_constructor {cstr_name={name; as_value=None}}} when name <> "[]" -> + | Const_int { i; comment = Pt_constructor {cstr_name={name; literal=None}}} when name <> "[]" -> E.str name - | Const_int { i; comment = Pt_constructor {cstr_name={as_value = Some as_value}}} -> - E.as_value as_value + | Const_int { i; comment = Pt_constructor {cstr_name={literal = Some literal}}} -> + E.literal literal | Const_int { i; comment } -> E.int i ?comment:(Lam_constant.string_of_pointer_info comment) | Const_char i -> Js_of_lam_string.const_char i diff --git a/jscomp/core/lam_constant_convert.ml b/jscomp/core/lam_constant_convert.ml index 7fe9a4ca51..39437c3dd4 100644 --- a/jscomp/core/lam_constant_convert.ml +++ b/jscomp/core/lam_constant_convert.ml @@ -49,11 +49,11 @@ let rec convert_constant (const : Lambda.structured_constant) : Lam_constant.t = | Pt_assertfalse -> Const_int { i = Int32.of_int i; comment = Pt_assertfalse } | Pt_constructor { name; const; non_const; attrs } -> - let as_value = Ast_attributes.process_as_value attrs in + let literal = Ast_attributes.process_as_value attrs in Const_int { i = Int32.of_int i; - comment = Pt_constructor { cstr_name={name; as_value}; const; non_const }; + comment = Pt_constructor { cstr_name={name; literal}; const; non_const }; } | Pt_variant { name } -> if Ext_string.is_valid_hash_number name then diff --git a/jscomp/core/matching_polyfill.ml b/jscomp/core/matching_polyfill.ml index 2b6cc9e6bb..b7502cb8a1 100644 --- a/jscomp/core/matching_polyfill.ml +++ b/jscomp/core/matching_polyfill.ml @@ -25,26 +25,77 @@ let is_nullary_variant (x : Types.constructor_arguments) = match x with Types.Cstr_tuple [] -> true | _ -> false +let checkUntaggedVariant ~(blocks : (Location.t * Lambda.block) list) = + let arrays = ref 0 in + let objects = ref 0 in + let unknowns = ref 0 in + let invariant loc = + if !unknowns <> 0 && (List.length blocks <> 1) + then Bs_syntaxerr.err loc InvalidUntaggedVariantDefinition; + if !objects > 1 || !arrays > 1 + then Bs_syntaxerr.err loc InvalidUntaggedVariantDefinition; + () in + Ext_list.rev_iter blocks (fun (loc, block) -> match block.block_type with + | Some Unknown -> + incr unknowns; + invariant loc + | Some Object -> + incr objects; + invariant loc + | Some Array -> + incr arrays; + invariant loc + | _ -> ()) + let names_from_construct_pattern (pat : Typedtree.pattern) = let names_from_type_variant (cstrs : Types.constructor_declaration list) = let get_cstr_name (cstr: Types.constructor_declaration) = { Lambda.name = Ident.name cstr.cd_id; - as_value = Ast_attributes.process_as_value cstr.cd_attributes } in + literal = Ast_attributes.process_as_value cstr.cd_attributes } in let get_tag_name (cstr: Types.constructor_declaration) = Ast_attributes.process_tag_name cstr.cd_attributes in + let get_untagged (cstr: Types.constructor_declaration) : Lambda.block_type option = + match Ast_attributes.process_untagged cstr.cd_attributes, cstr.cd_args with + | false, _ -> None + | true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_string -> + Some StringType + | true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_int -> + Some IntType + | true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_float -> + Some FloatType + | true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_array -> + Some Array + | true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path. same path Predef.path_string -> + Some StringType + | true, Cstr_tuple [{desc = Tconstr (path, _, _)}] -> + (match Path.name path with + | "Js.Dict.t" + | "Js_dict.t" -> Some Object + | _ -> Some Unknown) + | true, Cstr_tuple (_ :: _ :: _) -> + (* C(_, _) with at least 2 args is an object *) + Some Object + | true, Cstr_tuple [_] -> + (* Every other single payload is unknown *) + Some Unknown + | true, Cstr_record _ -> + (* inline record is an object *) + Some Object + | true, _ -> None (* TODO: add restrictions here *) + in let get_block cstr : Lambda.block = - {cstr_name = get_cstr_name cstr; tag_name = get_tag_name cstr} in + {cstr_name = get_cstr_name cstr; tag_name = get_tag_name cstr; block_type = get_untagged cstr} in let consts, blocks = Ext_list.fold_left cstrs ([], []) (fun (consts, blocks) cstr -> if is_nullary_variant cstr.cd_args then (get_cstr_name cstr :: consts, blocks) - else (consts, get_block cstr :: blocks)) + else (consts, (cstr.cd_loc, get_block cstr) :: blocks)) in - Some - { - Lambda.consts = Ext_array.reverse_of_list consts; - blocks = Ext_array.reverse_of_list blocks; - } + checkUntaggedVariant ~blocks; + let blocks = blocks |> List.map snd in + let consts = Ext_array.reverse_of_list consts in + let blocks = Ext_array.reverse_of_list blocks in + Some { Lambda.consts; blocks } in let rec resolve_path n (path : Path.t) = match Env.find_type path pat.pat_env with diff --git a/jscomp/frontend/ast_attributes.ml b/jscomp/frontend/ast_attributes.ml index 1204d90ac7..440b6b54bd 100644 --- a/jscomp/frontend/ast_attributes.ml +++ b/jscomp/frontend/ast_attributes.ml @@ -315,7 +315,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) = | Some delim -> delim in st := Some (Str (s, delim)); - if delim = DJson then + if delim = DNoQuotes then (* check that it is a valid object literal *) match Classify_function.classify @@ -335,7 +335,7 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) = !st let process_as_value (attrs : t) = - let st : Lambda.as_value option ref = ref None in + let st : Lambda.literal option ref = ref None in Ext_list.iter attrs (fun (({ txt; loc }, payload) as attr) -> match txt with | "bs.as" | "as" -> @@ -344,33 +344,30 @@ let process_as_value (attrs : t) = | None -> () | Some (s, _dec) -> Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some (AsString s)); + st := Some (String s)); (match Ast_payload.is_single_int payload with | None -> () | Some i -> Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some (AsInt i)); + st := Some (Int i)); (match Ast_payload.is_single_float payload with | None -> () | Some f -> Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some (AsFloat f)); + st := Some (Float f)); (match Ast_payload.is_single_bool payload with | None -> () | Some b -> Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some (AsBool b)); + st := Some (Bool b)); (match Ast_payload.is_single_ident payload with | None -> () | Some Lident "null" -> Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some AsNull + st := Some Null | Some Lident "undefined" -> Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some AsUndefined - | Some Lident "unboxed" -> - Bs_ast_invariant.mark_used_bs_attribute attr; - st := Some AsUnboxed + st := Some Undefined | Some _ -> Bs_syntaxerr.err loc InvalidVariantAsAnnotation); if !st = None then Bs_syntaxerr.err loc InvalidVariantAsAnnotation ) @@ -395,6 +392,15 @@ let process_tag_name (attrs : t) = | _ -> ()); !st +let process_untagged (attrs : t) = + let st = ref false in + Ext_list.iter attrs (fun (({ txt }, _)) -> + match txt with + | "unboxed" -> st := true + | _ -> ()); + !st + + let locg = Location.none (* let bs : attr = {txt = "bs" ; loc = locg}, Ast_payload.empty *) diff --git a/jscomp/frontend/ast_attributes.mli b/jscomp/frontend/ast_attributes.mli index 7ab5bdcc05..fe2683d584 100644 --- a/jscomp/frontend/ast_attributes.mli +++ b/jscomp/frontend/ast_attributes.mli @@ -92,6 +92,7 @@ val rs_externals : t -> string list -> bool val process_send_pipe : t -> (Parsetree.core_type * t) option -val process_as_value : t -> Lambda.as_value option +val process_as_value : t -> Lambda.literal option val process_tag_name : t -> string option +val process_untagged : t -> bool diff --git a/jscomp/frontend/ast_utf8_string_interp.ml b/jscomp/frontend/ast_utf8_string_interp.ml index bd48760007..79f627d102 100644 --- a/jscomp/frontend/ast_utf8_string_interp.ml +++ b/jscomp/frontend/ast_utf8_string_interp.ml @@ -272,7 +272,7 @@ let transform_test s = module Delim = struct let parse_processed = function | None -> Some External_arg_spec.DNone - | Some "json" -> Some DJson + | Some "json" -> Some DNoQuotes | Some "*j" -> Some DStarJ | _ -> None diff --git a/jscomp/frontend/bs_syntaxerr.ml b/jscomp/frontend/bs_syntaxerr.ml index 4ba70fcf3d..bab7ea0abc 100644 --- a/jscomp/frontend/bs_syntaxerr.ml +++ b/jscomp/frontend/bs_syntaxerr.ml @@ -53,6 +53,7 @@ type error = | Bs_uncurried_arity_too_large | InvalidVariantAsAnnotation | InvalidVariantTagAnnotation + | InvalidUntaggedVariantDefinition let pp_error fmt err = Format.pp_print_string fmt @@ -103,6 +104,8 @@ let pp_error fmt err = "A variant case annotation @as(...) must be a string or integer, boolean, null, undefined" | InvalidVariantTagAnnotation -> "A variant tag annotation @tag(...) must be a string" + | InvalidUntaggedVariantDefinition -> + "This untagged variant definition is invalid. But since I'm still work in progress I am not able to tell you why." ) type exn += Error of Location.t * error diff --git a/jscomp/frontend/bs_syntaxerr.mli b/jscomp/frontend/bs_syntaxerr.mli index 15c39baee0..bc6101e698 100644 --- a/jscomp/frontend/bs_syntaxerr.mli +++ b/jscomp/frontend/bs_syntaxerr.mli @@ -53,6 +53,7 @@ type error = | Bs_uncurried_arity_too_large | InvalidVariantAsAnnotation | InvalidVariantTagAnnotation + | InvalidUntaggedVariantDefinition val err : Location.t -> error -> 'a diff --git a/jscomp/frontend/external_arg_spec.ml b/jscomp/frontend/external_arg_spec.ml index 049c44a9e9..0b8474682b 100644 --- a/jscomp/frontend/external_arg_spec.ml +++ b/jscomp/frontend/external_arg_spec.ml @@ -24,7 +24,7 @@ (** type definitions for arguments to a function declared external *) -type delim = | DNone | DStarJ | DJson +type delim = | DNone | DStarJ | DNoQuotes type cst = | Arg_int_lit of int diff --git a/jscomp/frontend/external_arg_spec.mli b/jscomp/frontend/external_arg_spec.mli index b3a21e7791..b08827a228 100644 --- a/jscomp/frontend/external_arg_spec.mli +++ b/jscomp/frontend/external_arg_spec.mli @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -type delim = | DNone | DStarJ | DJson +type delim = | DNone | DStarJ | DNoQuotes type cst = private | Arg_int_lit of int diff --git a/jscomp/gentype/GenTypeCommon.ml b/jscomp/gentype/GenTypeCommon.ml index ec3431c1a8..1de0238563 100644 --- a/jscomp/gentype/GenTypeCommon.ml +++ b/jscomp/gentype/GenTypeCommon.ml @@ -68,7 +68,7 @@ type type_ = | Promise of type_ | Tuple of type_ list | TypeVar of string - | Variant of variant + | Variant of variant (* ordinary and polymorphic variants *) and fields = field list and argType = {aName: string; aType: type_} @@ -95,7 +95,7 @@ and variant = { inherits: type_ list; noPayloads: case list; payloads: payload list; - polymorphic: bool; + polymorphic: bool; (* If true, this is a polymorphic variant *) unboxed: bool; } @@ -165,8 +165,8 @@ let rec depToResolvedName (dep : dep) = | Internal resolvedName -> resolvedName | Dot (p, s) -> ResolvedName.dot s (p |> depToResolvedName) -let createVariant ~bsStringOrInt ~inherits ~noPayloads ~payloads ~polymorphic = - let unboxed = payloads = [] in +let createVariant ~bsStringOrInt ~inherits ~noPayloads ~payloads ~polymorphic + ~unboxed = Variant {bsStringOrInt; inherits; noPayloads; payloads; polymorphic; unboxed} let ident ?(builtin = true) ?(typeArgs = []) name = diff --git a/jscomp/gentype/TranslateCoreType.ml b/jscomp/gentype/TranslateCoreType.ml index 8563745d3d..d97aff69b4 100644 --- a/jscomp/gentype/TranslateCoreType.ml +++ b/jscomp/gentype/TranslateCoreType.ml @@ -225,7 +225,7 @@ and translateCoreType_ ~config ~typeVarsGen let inherits = inheritsTranslations |> List.map (fun {type_} -> type_) in let type_ = createVariant ~bsStringOrInt:(asString || asInt) ~noPayloads ~payloads - ~inherits ~polymorphic:true + ~inherits ~polymorphic:true ~unboxed:false in let dependencies = (inheritsTranslations diff --git a/jscomp/gentype/TranslateTypeDeclarations.ml b/jscomp/gentype/TranslateTypeDeclarations.ml index 3d662766cf..45f7365d87 100644 --- a/jscomp/gentype/TranslateTypeDeclarations.ml +++ b/jscomp/gentype/TranslateTypeDeclarations.ml @@ -26,9 +26,9 @@ let createCase (label, attributes) = (match attributes |> Annotation.getAttributePayload Annotation.tagIsAs with - | Some (_, IdentPayload (Lident "null")) -> NullLabel - | Some (_, IdentPayload (Lident "undefined")) -> UndefinedLabel - | Some (_, BoolPayload b) -> BoolLabel b + | Some (_, IdentPayload (Lident "null")) -> NullLabel + | Some (_, IdentPayload (Lident "undefined")) -> UndefinedLabel + | Some (_, BoolPayload b) -> BoolLabel b | Some (_, FloatPayload s) -> FloatLabel s | Some (_, IntPayload i) -> IntLabel i | Some (_, StringPayload asLabel) -> StringLabel asLabel @@ -197,7 +197,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver else variant.payloads in createVariant ~bsStringOrInt:false ~inherits:variant.inherits - ~noPayloads ~payloads ~polymorphic:true + ~noPayloads ~payloads ~polymorphic:true ~unboxed:false | _ -> translation.type_ in {translation with type_} |> handleGeneralDeclaration @@ -311,11 +311,8 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver }) in let variantTyp = - match (noPayloads, payloads) with - | [], [{t = type_}] when unboxedAnnotation -> type_ - | _ -> - createVariant ~bsStringOrInt:false ~inherits:[] ~noPayloads ~payloads - ~polymorphic:false + createVariant ~bsStringOrInt:false ~inherits:[] ~noPayloads ~payloads + ~polymorphic:false ~unboxed:unboxedAnnotation in let resolvedTypeName = typeName |> TypeEnv.addModulePath ~typeEnv in let exportFromTypeDeclaration = diff --git a/jscomp/gentype/TranslateTypeExprFromTypes.ml b/jscomp/gentype/TranslateTypeExprFromTypes.ml index 4e0edb6bf4..8e11707fc6 100644 --- a/jscomp/gentype/TranslateTypeExprFromTypes.ml +++ b/jscomp/gentype/TranslateTypeExprFromTypes.ml @@ -146,7 +146,7 @@ let translateConstr ~config ~paramsTranslation ~(path : Path.t) ~typeEnv = case 0 "Ok" paramTranslation1.type_; case 1 "Error" paramTranslation2.type_; ] - ~polymorphic:false + ~polymorphic:false ~unboxed:false in { dependencies = @@ -408,7 +408,7 @@ and translateTypeExprFromTypes_ ~config ~typeVarsGen ~typeEnv in let type_ = createVariant ~bsStringOrInt:false ~inherits:[] ~noPayloads ~payloads:[] - ~polymorphic:true + ~polymorphic:true ~unboxed:false in {dependencies = []; type_} | {noPayloads = []; payloads = [(_label, t)]; unknowns = []} -> @@ -439,7 +439,7 @@ and translateTypeExprFromTypes_ ~config ~typeVarsGen ~typeEnv in let type_ = createVariant ~bsStringOrInt:false ~inherits:[] ~noPayloads ~payloads - ~polymorphic:true + ~polymorphic:true ~unboxed:false in let dependencies = payloadTranslations diff --git a/jscomp/ml/lambda.ml b/jscomp/ml/lambda.ml index bd5f6684f3..c85dd5bd0f 100644 --- a/jscomp/ml/lambda.ml +++ b/jscomp/ml/lambda.ml @@ -38,8 +38,6 @@ type record_repr = | Record_regular | Record_optional -type as_value = AsString of string | AsInt of int | AsFloat of string | AsBool of bool | AsNull | AsUndefined | AsUnboxed -type cstr_name = {name: string; as_value: as_value option} type tag_info = | Blk_constructor of {name : string ; num_nonconst : int ; tag : int; attrs : Parsetree.attributes } @@ -273,7 +271,14 @@ type function_attribute = { return_unit : bool; async : bool; } -type block = {cstr_name: cstr_name; tag_name: string option} + +type block_type = + | IntType | StringType | FloatType | Array | Object | Unknown +type literal = + | String of string | Int of int | Float of string | Bool of bool | Null | Undefined + | Block of block_type +type cstr_name = {name: string; literal: literal option} +type block = {cstr_name: cstr_name; tag_name: string option; block_type : block_type option} type switch_names = {consts: cstr_name array; blocks: block array} type lambda = diff --git a/jscomp/ml/lambda.mli b/jscomp/ml/lambda.mli index 5718493ecf..7077c8f6e4 100644 --- a/jscomp/ml/lambda.mli +++ b/jscomp/ml/lambda.mli @@ -38,9 +38,6 @@ type record_repr = | Record_regular | Record_optional -type as_value = AsString of string | AsInt of int | AsFloat of string | AsBool of bool | AsNull | AsUndefined | AsUnboxed -type cstr_name = {name:string; as_value: as_value option} - type tag_info = | Blk_constructor of { name : string ; num_nonconst : int; tag : int; attrs : Parsetree.attributes } | Blk_record_inlined of { name : string ; num_nonconst : int ; tag : int; optional_labels: string list; fields : string array; mutable_flag : mutable_flag; attrs : Parsetree.attributes } @@ -276,7 +273,12 @@ type function_attribute = { async : bool; } -type block = {cstr_name: cstr_name; tag_name: string option} +type block_type = IntType | StringType | FloatType | Array | Object | Unknown +type literal = + | String of string | Int of int | Float of string | Bool of bool | Null | Undefined + | Block of block_type +type cstr_name = {name:string; literal: literal option} +type block = {cstr_name: cstr_name; tag_name: string option; block_type : block_type option} type switch_names = {consts: cstr_name array; blocks: block array} type lambda = diff --git a/jscomp/ml/matching.ml b/jscomp/ml/matching.ml index 8925357c3f..cbc6c51b44 100644 --- a/jscomp/ml/matching.ml +++ b/jscomp/ml/matching.ml @@ -1329,12 +1329,10 @@ let make_constr_matching p def ctx = function [] -> fatal_error "Matching.make_constr_matching" | ((arg, _mut) :: argl) -> let cstr = pat_as_constr p in + let untagged = + Ext_list.exists cstr.cstr_attributes (function ({txt}, _) -> txt = "unboxed") in let newargs = - if cstr.cstr_inlined <> None || - Ext_list.exists cstr.cstr_attributes (function - | ({txt="as"}, PStr [{pstr_desc = Pstr_eval - ({pexp_desc = Pexp_ident {txt= Lident "unboxed"}}, _)}]) -> true - | _ -> false) then + if cstr.cstr_inlined <> None || (untagged && cstr.cstr_args <> []) then (arg, Alias) :: argl else match cstr.cstr_tag with | Cstr_block _ when diff --git a/jscomp/ml/typedecl.ml b/jscomp/ml/typedecl.ml index c1a1e825c6..f7bde76c2b 100644 --- a/jscomp/ml/typedecl.ml +++ b/jscomp/ml/typedecl.ml @@ -303,7 +303,18 @@ let transl_declaration env sdecl id = sdecl.ptype_cstrs in let raw_status = get_unboxed_from_attributes sdecl in - if raw_status.unboxed && not raw_status.default then begin + + let checkUntaggedVariant = match sdecl.ptype_kind with + | Ptype_variant cds -> Ext_list.for_all cds (function + | {pcd_args = Pcstr_tuple ([] | [_])} -> + (* at most one payload allowed for untagged variants *) + true + | {pcd_args = Pcstr_record _} -> true + | _ -> false ) + | _ -> false + in + + if raw_status.unboxed && not raw_status.default && not checkUntaggedVariant then begin match sdecl.ptype_kind with | Ptype_abstract -> raise(Error(sdecl.ptype_loc, Bad_unboxed_attribute @@ -338,7 +349,7 @@ let transl_declaration env sdecl id = end; let unboxed_status = match sdecl.ptype_kind with - | Ptype_variant [{pcd_args = Pcstr_tuple [_]; _}] + | Ptype_variant [{pcd_args = Pcstr_tuple _; _}] | Ptype_variant [{pcd_args = Pcstr_record [{pld_mutable = Immutable; _}]; _}] | Ptype_record [{pld_mutable = Immutable; _}] -> @@ -380,8 +391,8 @@ let transl_declaration env sdecl id = all_constrs := StringSet.add name !all_constrs) scstrs; let copy_tag_attr_from_decl attr = - let tag_attr = Ext_list.filter sdecl.ptype_attributes (fun ({txt}, _) -> txt = "tag") in - if tag_attr = [] then attr else tag_attr @ attr in + let tag_attrs = Ext_list.filter sdecl.ptype_attributes (fun ({txt}, _) -> txt = "tag" || txt = "unboxed") in + if tag_attrs = [] then attr else tag_attrs @ attr in let make_cstr scstr = let name = Ident.create scstr.pcd_name.txt in let targs, tret_type, args, ret_type, _cstr_params = diff --git a/jscomp/test/UntaggedVariants.js b/jscomp/test/UntaggedVariants.js new file mode 100644 index 0000000000..79b0d8c375 --- /dev/null +++ b/jscomp/test/UntaggedVariants.js @@ -0,0 +1,272 @@ +'use strict'; + + +function classify(x) { + if (typeof x !== "string" && typeof x !== "number") { + return "A"; + } else if (typeof x === "number") { + return "An integer"; + } else { + return "A string" + x; + } +} + +function classify2(x) { + if (typeof x === "string") { + return "A string" + x; + } else { + return "A float"; + } +} + +function cls(x) { + if (typeof x !== "object") { + if (x === "One") { + return "one"; + } else { + return "two"; + } + } else { + return "object" + x.y; + } +} + +var ListWithTuples = {}; + +var ListWithObjects = {}; + +function tuplesToObjects(l) { + if (l === undefined) { + return null; + } else { + return { + hd: l[0], + tl: tuplesToObjects(l[1]) + }; + } +} + +var l1 = [ + 1, + [ + 2, + [ + 3, + undefined + ] + ] +]; + +var l2 = tuplesToObjects(l1); + +console.log("l1", l1); + +console.log("l2", l2); + +function isTrue(x) { + if (typeof x !== "object") { + return true; + } else { + return x.flag; + } +} + +var Truthy = { + isTrue: isTrue +}; + +function classify$1(x) { + if (typeof x !== "object") { + if (x === null) { + return "null"; + } else { + return "undefined"; + } + } else { + return "object" + x.name; + } +} + +var TwoObjects = { + classify: classify$1 +}; + +function classify$2(x) { + if (x === "A" || x === "B") { + if (x === "A") { + return "a"; + } else { + return "b"; + } + } + console.log(x); + return "Unknown"; +} + +var Unknown = { + classify: classify$2 +}; + +function classify$3(x) { + if (typeof x !== "object" && typeof x !== "number" && typeof x !== "string") { + switch (x) { + case "A" : + return "a"; + case "B" : + return "b"; + case "C" : + return "c"; + case "D" : + return "d"; + + } + } else { + switch (typeof x) { + case "string" : + return "string"; + case "number" : + return "int"; + case "object" : + return "Object" + x.name; + + } + } +} + +var MultipleBlocks = { + classify: classify$3 +}; + +function classify$4(x) { + switch (typeof x) { + case "string" : + return "string"; + case "number" : + return "int"; + case "object" : + return "Object" + x.name; + + } +} + +var OnlyBlocks = { + classify: classify$4 +}; + +function classify$5(x) { + if (x instanceof Array) { + return "array"; + } + switch (typeof x) { + case "string" : + return "string"; + case "number" : + return "int"; + case "object" : + return "Object" + x.name; + + } +} + +var WithArray = { + classify: classify$5 +}; + +function classify$6(x) { + if (!(x instanceof Array) && typeof x !== "object" && typeof x !== "number" && typeof x !== "string") { + switch (x) { + case false : + return "JSONFalse"; + case true : + return "JSONTrue"; + case null : + return "JSONNull"; + + } + } else { + if (x instanceof Array) { + return { + TAG: "JSONArray", + _0: x + }; + } + switch (typeof x) { + case "string" : + return { + TAG: "JSONString", + _0: x + }; + case "number" : + return { + TAG: "JSONNumber", + _0: x + }; + case "object" : + return { + TAG: "JSONObject", + _0: x + }; + + } + } +} + +var Json = { + classify: classify$6 +}; + +function check(s, y) { + if (s === "B") { + return 42; + } + var x = s[0]; + if (x === "B") { + return 42; + } + var tmp = s[1]; + if (tmp === "B" && x !== y) { + return 41; + } else { + return 42; + } +} + +var TrickyNested = { + check: check +}; + +var i = 42; + +var i2 = 42.5; + +var s = "abc"; + +var s2 = "abc"; + +var w = { + x: 10, + y: "" +}; + +exports.i = i; +exports.i2 = i2; +exports.s = s; +exports.s2 = s2; +exports.classify = classify; +exports.classify2 = classify2; +exports.w = w; +exports.cls = cls; +exports.ListWithTuples = ListWithTuples; +exports.ListWithObjects = ListWithObjects; +exports.tuplesToObjects = tuplesToObjects; +exports.l1 = l1; +exports.l2 = l2; +exports.Truthy = Truthy; +exports.TwoObjects = TwoObjects; +exports.Unknown = Unknown; +exports.MultipleBlocks = MultipleBlocks; +exports.OnlyBlocks = OnlyBlocks; +exports.WithArray = WithArray; +exports.Json = Json; +exports.TrickyNested = TrickyNested; +/* l2 Not a pure module */ diff --git a/jscomp/test/UntaggedVariants.res b/jscomp/test/UntaggedVariants.res new file mode 100644 index 0000000000..4531fb2980 --- /dev/null +++ b/jscomp/test/UntaggedVariants.res @@ -0,0 +1,198 @@ +@unboxed +type t = A | I(int) | S(string) +@unboxed +type t2 = S2(string) | I2(float) + +let i = I(42) +let i2 = I2(42.5) +let s = S("abc") +let s2 = S2("abc") + +let classify = x => + switch x { + | I(_) => "An integer" + | S(s) => "A string" ++ s + | A => "A" + } + +let classify2 = x => + switch x { + | I2(_) => "A float" + | S2(s) => "A string" ++ s + } + +@unboxed +type tt = One | Two | Object({x: int, y: string}) + +let w = Object({x: 10, y: ""}) + +let cls = x => + switch x { + | One => "one" + | Two => "two" + | Object({y}) => "object" ++ y + } + +module ListWithTuples = { + @unboxed + type rec t<'a> = | @as(undefined) Empty | Cons(('a, t<'a>)) +} + +module ListWithObjects = { + @unboxed + type rec t<'a> = | @as(null) Empty | Cons({hd: 'a, tl: t<'a>}) +} + +let rec tuplesToObjects = (l: ListWithTuples.t<_>): ListWithObjects.t<_> => + switch l { + | Empty => Empty + | Cons((hd, tl)) => Cons({hd, tl: tuplesToObjects(tl)}) + } + +let l1 = ListWithTuples.Cons((1, Cons((2, Cons((3, Empty)))))) +let l2 = tuplesToObjects(l1) +Js.log2("l1", l1) +Js.log2("l2", l2) + +module Truthy = { + @unboxed + type t = | @as(true) True | Obj({flag: bool}) + + let isTrue = x => + switch x { + | True => true + | Obj({flag}) => flag + } +} + +module TwoObjects = { + @unboxed + type t = | @as(null) Null | Object({name: string}) | @as(undefined) Undefined + + let classify = x => + switch x { + | Null => "null" + | Object({name}) => "object" ++ name + | Undefined => "undefined" + } +} + +module Unknown = { + @unboxed + type t<'a> = A | B | Unknown('a) + + let classify = x => + switch x { + | A => "a" + | B => "b" + | Unknown(v) => { + Js.log(x) + "Unknown" + } + } +} + +module MultipleBlocks = { + @unboxed + type t<'a> = A | B | C | D | String(string) | Int(int) | Object({name: string}) + + let classify = x => + switch x { + | A => "a" + | B => "b" + | C => "c" + | D => "d" + | String(_) => "string" + | Int(_) => "int" + | Object({name}) => "Object" ++ name + } +} + +module OnlyBlocks = { + @unboxed + type t<'a> = String(string) | Int(int) | Object({name: string}) + + let classify = x => + switch x { + | String(_) => "string" + | Int(_) => "int" + | Object({name}) => "Object" ++ name + } +} + +module WithArray = { + @unboxed + type t<'a> = String(string) | Float(float) | Array(array) | Object({name: string}) + + let classify = x => + switch x { + | String(_) => "string" + | Float(_) => "int" + | Array(_) if true => "array" + | Array(_) => "array" + | Object({name}) => "Object" ++ name + } +} + +module Json = { + @unboxed + type rec t = + | @as(false) False + | @as(true) True + | @as(null) Null + | String(string) + | Number(float) + | Object(Js.Dict.t) + | Array(array) + + type tagged_t = + | JSONFalse + | JSONTrue + | JSONNull + | JSONString(string) + | JSONNumber(float) + | JSONObject(Js.Dict.t) + | JSONArray(array) + + let classify = (x: t) => + switch x { + | False => JSONFalse + | True => JSONTrue + | Null => JSONNull + | String(s) => JSONString(s) + | Number(n) => JSONNumber(n) + | Object(o) => JSONObject(o) + | Array(a) => JSONArray(a) + } + + /* from js_json.ml +let classify (x : t) : tagged_t = + let ty = Js.typeof x in + if ty = "string" then + JSONString (Obj.magic x) + else if ty = "number" then + JSONNumber (Obj.magic x ) + else if ty = "boolean" then + if (Obj.magic x) = true then JSONTrue + else JSONFalse + else if (Obj.magic x) == Js.null then + JSONNull + else if Js_array2.isArray x then + JSONArray (Obj.magic x) + else + JSONObject (Obj.magic x) + */ +} + +module TrickyNested = { + @unboxed + type rec t = + | A((t, t)) + | B + + let check = (s, y) => + switch s { + | A((A(x), B)) if x !== y => 41 + | _ => 42 + } +} diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index 81575a238e..5e2bceedd0 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -24,6 +24,7 @@ o test/SafePromises.cmi test/SafePromises.cmj : cc test/SafePromises.res | $bsc o test/UncurriedAlways.cmi test/UncurriedAlways.cmj : cc test/UncurriedAlways.res | $bsc $stdlib runtime o test/UncurriedExternals.cmi test/UncurriedExternals.cmj : cc test/UncurriedExternals.res | $bsc $stdlib runtime o test/UncurriedPervasives.cmi test/UncurriedPervasives.cmj : cc test/UncurriedPervasives.res | $bsc $stdlib runtime +o test/UntaggedVariants.cmi test/UntaggedVariants.cmj : cc test/UntaggedVariants.res | $bsc $stdlib runtime o test/a.cmi test/a.cmj : cc test/a.ml | test/test_order.cmj $bsc $stdlib runtime o test/a_filename_test.cmi test/a_filename_test.cmj : cc test/a_filename_test.ml | test/ext_filename_test.cmj test/mt.cmj $bsc $stdlib runtime o test/a_list_test.cmi test/a_list_test.cmj : cc test/a_list_test.ml | test/ext_list_test.cmj test/mt.cmj $bsc $stdlib runtime @@ -722,4 +723,4 @@ o test/variant.cmi test/variant.cmj : cc test/variant.ml | $bsc $stdlib runtime o test/variantsMatching.cmi test/variantsMatching.cmj : cc test/variantsMatching.res | $bsc $stdlib runtime o test/watch_test.cmi test/watch_test.cmj : cc test/watch_test.ml | $bsc $stdlib runtime o test/webpack_config.cmi test/webpack_config.cmj : cc test/webpack_config.ml | $bsc $stdlib runtime -o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/EmptyRecord.cmi test/EmptyRecord.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/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.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/app_root_finder.cmi test/app_root_finder.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.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/array_test.cmi test/array_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_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.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/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.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/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_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_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_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_node_string_buffer_test.cmi test/bs_node_string_buffer_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_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_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/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_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/caml_format_test.cmi test/caml_format_test.cmj test/caml_sys_poly_fill_test.cmi test/caml_sys_poly_fill_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_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_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_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_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_def.cmi test/exception_def.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebind_test.cmi test/exception_rebind_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/exn_error_pattern.cmi test/exn_error_pattern.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_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.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_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/flow_parser_reg_test.cmi test/flow_parser_reg_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/format_test.cmi test/format_test.cmj test/fs_test.cmi test/fs_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.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/genlex_test.cmi test/genlex_test.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_1154_test.cmi test/gpr_1154_test.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_1503_test.cmi test/gpr_1503_test.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_2652_test.cmi test/gpr_2652_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_405_test.cmi test/gpr_405_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_5312.cmi test/gpr_5312.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_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/hamming_test.cmi test/hamming_test.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/hashtbl_test.cmi test/hashtbl_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/imm_map_bench.cmi test/imm_map_bench.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_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/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_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/io_test.cmi test/io_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_list_test.cmi test/js_list_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_promise_basic_test.cmi test/js_promise_basic_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_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/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/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.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/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.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_fs_test.cmi test/node_fs_test.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.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/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_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/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/promise_catch_test.cmi test/promise_catch_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.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/rec_value_test.cmi test/rec_value_test.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_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/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simple_lexer_test.cmi test/simple_lexer_test.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.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/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_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_get_set_test.cmi test/string_get_set_test.cmj test/string_literal_print_test.cmi test/string_literal_print_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_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/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.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_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.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_filename.cmi test/test_filename.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_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.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_global_print.cmi test/test_global_print.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_internalOO.cmi test/test_internalOO.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_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.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_obj_simple_ffi.cmi test/test_obj_simple_ffi.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_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.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_require.cmi test/test_require.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_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.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_unsupported_primitive.cmi test/test_unsupported_primitive.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_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/ui_defs.cmi 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_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/unsafe_this.cmi test/unsafe_this.cmj test/update_record_test.cmi test/update_record_test.cmj test/utf8_decode_test.cmi test/utf8_decode_test.cmj test/variant.cmi test/variant.cmj test/variantsMatching.cmi test/variantsMatching.cmj test/watch_test.cmi test/watch_test.cmj test/webpack_config.cmi test/webpack_config.cmj +o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/EmptyRecord.cmi test/EmptyRecord.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/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.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/app_root_finder.cmi test/app_root_finder.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.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/array_test.cmi test/array_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_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.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/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.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/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_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_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_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_node_string_buffer_test.cmi test/bs_node_string_buffer_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_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_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/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_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/caml_format_test.cmi test/caml_format_test.cmj test/caml_sys_poly_fill_test.cmi test/caml_sys_poly_fill_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_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_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_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_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_def.cmi test/exception_def.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebind_test.cmi test/exception_rebind_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/exn_error_pattern.cmi test/exn_error_pattern.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_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.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_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/flow_parser_reg_test.cmi test/flow_parser_reg_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/format_test.cmi test/format_test.cmj test/fs_test.cmi test/fs_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.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/genlex_test.cmi test/genlex_test.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_1154_test.cmi test/gpr_1154_test.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_1503_test.cmi test/gpr_1503_test.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_2652_test.cmi test/gpr_2652_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_405_test.cmi test/gpr_405_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_5312.cmi test/gpr_5312.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_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/hamming_test.cmi test/hamming_test.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/hashtbl_test.cmi test/hashtbl_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/imm_map_bench.cmi test/imm_map_bench.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_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/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_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/io_test.cmi test/io_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_list_test.cmi test/js_list_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_promise_basic_test.cmi test/js_promise_basic_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_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/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/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.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/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.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_fs_test.cmi test/node_fs_test.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.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/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_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/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/promise_catch_test.cmi test/promise_catch_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.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/rec_value_test.cmi test/rec_value_test.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_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/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simple_lexer_test.cmi test/simple_lexer_test.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.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/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_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_get_set_test.cmi test/string_get_set_test.cmj test/string_literal_print_test.cmi test/string_literal_print_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_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/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.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_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.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_filename.cmi test/test_filename.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_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.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_global_print.cmi test/test_global_print.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_internalOO.cmi test/test_internalOO.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_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.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_obj_simple_ffi.cmi test/test_obj_simple_ffi.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_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.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_require.cmi test/test_require.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_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.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_unsupported_primitive.cmi test/test_unsupported_primitive.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_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/ui_defs.cmi 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_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/unsafe_this.cmi test/unsafe_this.cmj test/update_record_test.cmi test/update_record_test.cmj test/utf8_decode_test.cmi test/utf8_decode_test.cmj test/variant.cmi test/variant.cmj test/variantsMatching.cmi test/variantsMatching.cmj test/watch_test.cmi test/watch_test.cmj test/webpack_config.cmi test/webpack_config.cmj diff --git a/jscomp/test/variantsMatching.gen.tsx b/jscomp/test/variantsMatching.gen.tsx index 705fa23b40..8718551676 100644 --- a/jscomp/test/variantsMatching.gen.tsx +++ b/jscomp/test/variantsMatching.gen.tsx @@ -7,3 +7,15 @@ export type t = "thisIsA" | 42 | null | "D" | 3.14; // tslint:disable-next-line:interface-over-type-literal export type tNU = null | undefined; + +// tslint:disable-next-line:interface-over-type-literal +export type MyUndefined_t = undefined | a; + +// tslint:disable-next-line:interface-over-type-literal +export type MyNull_t = null | a; + +// tslint:disable-next-line:interface-over-type-literal +export type MyNullable_t = null | undefined | a; + +// tslint:disable-next-line:interface-over-type-literal +export type MyNullableExtended_t = null | undefined | "WhyNotAnotherOne" | a; diff --git a/jscomp/test/variantsMatching.js b/jscomp/test/variantsMatching.js index 4fd4b24d96..08883fc123 100644 --- a/jscomp/test/variantsMatching.js +++ b/jscomp/test/variantsMatching.js @@ -278,7 +278,7 @@ function isWhyNot(x) { } function plus$3(x, y) { - if (x === null || typeof x !== "object") { + if (x === undefined || x === null || x === "WhyNotAnotherOne") { switch (x) { case null : case undefined : @@ -287,13 +287,13 @@ function plus$3(x, y) { break; } - } else if (!(y === null || typeof y !== "object")) { + } else if (!(y === undefined || y === null || y === "WhyNotAnotherOne")) { return { x: x.x + y.x, y: x.y + y.y }; } - if (!(y === null || typeof y !== "object")) { + if (!(y === undefined || y === null || y === "WhyNotAnotherOne")) { return "WhyNotAnotherOne"; } switch (y) { @@ -307,7 +307,7 @@ function plus$3(x, y) { } function kind$1(x) { - if (!(x === null || typeof x !== "object")) { + if (!(x === undefined || x === null || x === "WhyNotAnotherOne")) { return "present"; } switch (x) { diff --git a/jscomp/test/variantsMatching.res b/jscomp/test/variantsMatching.res index 8aeb67961e..f8b3efd113 100644 --- a/jscomp/test/variantsMatching.res +++ b/jscomp/test/variantsMatching.res @@ -107,7 +107,8 @@ module CustomizeTags = { } module MyUndefined = { - type t<'a> = | @as(undefined) Undefined | @as(unboxed) Present('a) + @genType @unboxed + type t<'a> = | @as(undefined) Undefined | Present('a) // Note: 'a must not have undefined as value // There can be only one with payload, with 1 argument, to use unboxed @@ -124,7 +125,8 @@ module MyUndefined = { } module MyNull = { - type t<'a> = | @as(null) Null | @as(unboxed) Present('a) + @genType @unboxed + type t<'a> = | @as(null) Null | Present('a) // Note: 'a must not have null as value // There can be only one with payload, with 1 argument, to use unboxed @@ -141,10 +143,11 @@ module MyNull = { } module MyNullable = { + @genType @unboxed type t<'a> = | @as(null) Null | @as(undefined) Undefined - | @as(unboxed) Present('a) + | Present('a) // Note: 'a must not have null or undefined as value // There can be only one with payload, with 1 argument, to use unboxed @@ -173,10 +176,11 @@ module MyNullable = { } module MyNullableExtended = { + @genType @unboxed type t<'a> = | @as(null) Null | @as(undefined) Undefined - | @as(unboxed) Present('a) + | Present('a) | WhyNotAnotherOne // Note: 'a must be a not have null or something that's not an object as value // There can be only one with payload, with 1 argument, to use unboxed