From c9c49f04aebbc9740f77fa6d8cc97ab77980ed41 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 8 Nov 2024 13:34:29 +0100 Subject: [PATCH 01/10] Simplify conditionals. Fixes https://github.com/rescript-lang/rescript-compiler/issues/7142 - x ? y : false --> x && y - x ? false : y --> !x && y - push negation inside when it leads to simplification --- compiler/core/js_exp_make.ml | 29 ++++++++++++++----- lib/es6/Belt_List.js | 6 +--- lib/es6/Belt_Result.js | 10 ++----- lib/es6/List.js | 6 +--- lib/es6/Primitive_option.js | 2 +- lib/es6/Result.js | 10 ++----- lib/js/Belt_List.js | 6 +--- lib/js/Belt_Result.js | 10 ++----- lib/js/List.js | 6 +--- lib/js/Primitive_option.js | 2 +- lib/js/Result.js | 10 ++----- tests/tests/src/UntaggedVariants.mjs | 6 ++-- tests/tests/src/bdd.mjs | 4 +-- tests/tests/src/bs_poly_map_test.mjs | 6 ++-- tests/tests/src/complex_while_loop.mjs | 6 ++-- tests/tests/src/core/Core_NullableTests.mjs | 4 +-- tests/tests/src/demo_page.mjs | 6 ++-- .../tests/src/exception_rebound_err_test.mjs | 2 +- tests/tests/src/fib.mjs | 6 ++-- tests/tests/src/gpr_3877_test.mjs | 6 ++-- tests/tests/src/gpr_4900_test.mjs | 4 +-- tests/tests/src/gpr_4924_test.mjs | 8 ++--- tests/tests/src/int_overflow_test.mjs | 6 ++-- tests/tests/src/json_decorders.mjs | 4 +-- tests/tests/src/test_bool_equal.mjs | 4 +-- tests/tests/src/test_demo.mjs | 6 ++-- tests/tests/src/test_fib.mjs | 12 ++++---- tests/tests/src/test_while_side_effect.mjs | 6 ++-- tests/tests/src/topsort_test.mjs | 2 +- tests/tests/src/tramp_fib.mjs | 6 ++-- tests/tests/src/variantsMatching.mjs | 16 ++++++---- 31 files changed, 96 insertions(+), 121 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index cc8d357043..828d3f61dc 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -997,7 +997,7 @@ let rec simplify_and ~n (e1 : t) (e2 : t) : t option = _ ) as is_array) ) when Js_op_util.same_vident ia ib -> Some {expression_desc = is_array; comment = None} - | x, y when x = y -> Some e1 + | _ when Js_analyzer.eq_expression e1 e2 -> Some e1 | ( Bin ( EqEqEq, {expression_desc = Var ia}, @@ -1022,7 +1022,9 @@ let rec simplify_and ~n (e1 : t) (e2 : t) : t option = ({expression_desc = Bool _ | Null | Undefined _ | Number _ | Str _} as v2) ) ) when Js_op_util.same_vident ia ib && op1 != op2 -> - if v1 = v2 then Some false_ else if op1 = EqEqEq then Some e1 else Some e2 + if Js_analyzer.eq_expression v1 v2 then Some false_ + else if op1 = EqEqEq then Some e1 + else Some e2 | _ -> None in (if debug then @@ -1138,7 +1140,10 @@ let not (e : t) : t = | Bin (Ge, a, b) -> {e with expression_desc = Bin (Lt, a, b)} | Bin (Le, a, b) -> {e with expression_desc = Bin (Gt, a, b)} | Bin (Gt, a, b) -> {e with expression_desc = Bin (Le, a, b)} - | _ -> {expression_desc = Js_not e; comment = None} + | _ -> ( + match push_negation e with + | Some e_ -> e_ + | None -> {expression_desc = Js_not e; comment = None}) let not_empty_branch (x : t) = match x.expression_desc with @@ -1146,6 +1151,11 @@ let not_empty_branch (x : t) = | _ -> true let rec econd ?comment (pred : t) (ifso : t) (ifnot : t) : t = + let default () = + if Js_analyzer.eq_expression ifso ifnot then + if no_side_effect pred then ifso else seq ?comment pred ifso + else {expression_desc = Cond (pred, ifso, ifnot); comment} + in match (pred.expression_desc, ifso.expression_desc, ifnot.expression_desc) with | Bool false, _, _ -> ifnot | Number (Int {i = 0l; _}), _, _ -> ifnot @@ -1179,10 +1189,15 @@ let rec econd ?comment (pred : t) (ifso : t) (ifnot : t) : t = Seq (a, {expression_desc = Undefined _}), Seq (b, {expression_desc = Undefined _}) ) -> seq (econd ?comment pred a b) undefined - | _ -> - if Js_analyzer.eq_expression ifso ifnot then - if no_side_effect pred then ifso else seq ?comment pred ifso - else {expression_desc = Cond (pred, ifso, ifnot); comment} + | _, _, Bool false -> ( + match simplify_and ~n:0 pred ifso with + | Some e -> e + | None -> default ()) + | _, Bool false, _ -> ( + match simplify_and ~n:0 (not pred) ifnot with + | Some e -> e + | None -> default ()) + | _ -> default () let rec float_equal ?comment (e0 : t) (e1 : t) : t = match (e0.expression_desc, e1.expression_desc) with diff --git a/lib/es6/Belt_List.js b/lib/es6/Belt_List.js index 0991cb4e96..22455cc2e0 100644 --- a/lib/es6/Belt_List.js +++ b/lib/es6/Belt_List.js @@ -988,11 +988,7 @@ function eq(_l1, _l2, p) { let l2 = _l2; let l1 = _l1; if (!l1) { - if (l2) { - return false; - } else { - return true; - } + return !l2; } if (!l2) { return false; diff --git a/lib/es6/Belt_Result.js b/lib/es6/Belt_Result.js index b83195146a..e534ddd9fe 100644 --- a/lib/es6/Belt_Result.js +++ b/lib/es6/Belt_Result.js @@ -57,11 +57,7 @@ function isOk(x) { } function isError(x) { - if (x.TAG === "Ok") { - return false; - } else { - return true; - } + return x.TAG !== "Ok"; } function eq(a, b, f) { @@ -71,10 +67,8 @@ function eq(a, b, f) { } else { return false; } - } else if (b.TAG === "Ok") { - return false; } else { - return true; + return b.TAG !== "Ok"; } } diff --git a/lib/es6/List.js b/lib/es6/List.js index 89b2209010..06760467a5 100644 --- a/lib/es6/List.js +++ b/lib/es6/List.js @@ -1000,11 +1000,7 @@ function equal(_l1, _l2, p) { let l2 = _l2; let l1 = _l1; if (!l1) { - if (l2) { - return false; - } else { - return true; - } + return !l2; } if (!l2) { return false; diff --git a/lib/es6/Primitive_option.js b/lib/es6/Primitive_option.js index 2bdb0ccca9..7d3ab0014e 100644 --- a/lib/es6/Primitive_option.js +++ b/lib/es6/Primitive_option.js @@ -44,7 +44,7 @@ function fromNull(x) { } function valFromOption(x) { - if (!(x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== undefined)) { + if (x === null || x.BS_PRIVATE_NESTED_SOME_NONE === undefined) { return x; } let depth = x.BS_PRIVATE_NESTED_SOME_NONE; diff --git a/lib/es6/Result.js b/lib/es6/Result.js index 5b5023054f..9fc4536c9e 100644 --- a/lib/es6/Result.js +++ b/lib/es6/Result.js @@ -51,11 +51,7 @@ function isOk(x) { } function isError(x) { - if (x.TAG === "Ok") { - return false; - } else { - return true; - } + return x.TAG !== "Ok"; } function equal(a, b, f) { @@ -65,10 +61,8 @@ function equal(a, b, f) { } else { return false; } - } else if (b.TAG === "Ok") { - return false; } else { - return true; + return b.TAG !== "Ok"; } } diff --git a/lib/js/Belt_List.js b/lib/js/Belt_List.js index f5bf603c2b..2d9f0e17ec 100644 --- a/lib/js/Belt_List.js +++ b/lib/js/Belt_List.js @@ -988,11 +988,7 @@ function eq(_l1, _l2, p) { let l2 = _l2; let l1 = _l1; if (!l1) { - if (l2) { - return false; - } else { - return true; - } + return !l2; } if (!l2) { return false; diff --git a/lib/js/Belt_Result.js b/lib/js/Belt_Result.js index 0aba2f6f5c..fb2585738a 100644 --- a/lib/js/Belt_Result.js +++ b/lib/js/Belt_Result.js @@ -57,11 +57,7 @@ function isOk(x) { } function isError(x) { - if (x.TAG === "Ok") { - return false; - } else { - return true; - } + return x.TAG !== "Ok"; } function eq(a, b, f) { @@ -71,10 +67,8 @@ function eq(a, b, f) { } else { return false; } - } else if (b.TAG === "Ok") { - return false; } else { - return true; + return b.TAG !== "Ok"; } } diff --git a/lib/js/List.js b/lib/js/List.js index 129fb6f5cf..8e8cd35fbc 100644 --- a/lib/js/List.js +++ b/lib/js/List.js @@ -1000,11 +1000,7 @@ function equal(_l1, _l2, p) { let l2 = _l2; let l1 = _l1; if (!l1) { - if (l2) { - return false; - } else { - return true; - } + return !l2; } if (!l2) { return false; diff --git a/lib/js/Primitive_option.js b/lib/js/Primitive_option.js index 53c29aae13..d6d8a9f45b 100644 --- a/lib/js/Primitive_option.js +++ b/lib/js/Primitive_option.js @@ -44,7 +44,7 @@ function fromNull(x) { } function valFromOption(x) { - if (!(x !== null && x.BS_PRIVATE_NESTED_SOME_NONE !== undefined)) { + if (x === null || x.BS_PRIVATE_NESTED_SOME_NONE === undefined) { return x; } let depth = x.BS_PRIVATE_NESTED_SOME_NONE; diff --git a/lib/js/Result.js b/lib/js/Result.js index b0c9638920..bee54d5b2f 100644 --- a/lib/js/Result.js +++ b/lib/js/Result.js @@ -51,11 +51,7 @@ function isOk(x) { } function isError(x) { - if (x.TAG === "Ok") { - return false; - } else { - return true; - } + return x.TAG !== "Ok"; } function equal(a, b, f) { @@ -65,10 +61,8 @@ function equal(a, b, f) { } else { return false; } - } else if (b.TAG === "Ok") { - return false; } else { - return true; + return b.TAG !== "Ok"; } } diff --git a/tests/tests/src/UntaggedVariants.mjs b/tests/tests/src/UntaggedVariants.mjs index 95d20f5767..4a2a4c5fc8 100644 --- a/tests/tests/src/UntaggedVariants.mjs +++ b/tests/tests/src/UntaggedVariants.mjs @@ -234,7 +234,7 @@ let TrickyNested = { }; function checkEnum(e) { - if (!(e === "One" || e === "Three" || e === "Two")) { + if (e !== "One" && e !== "Three" && e !== "Two") { return "Something else..." + e; } switch (e) { @@ -252,7 +252,7 @@ let OverlapString = { }; function checkEnum$1(e) { - if (!(e === 1.0 || e === "Three" || e === "Two")) { + if (e !== 1.0 && e !== "Three" && e !== "Two") { return "Something else..."; } switch (e) { @@ -270,7 +270,7 @@ let OverlapNumber = { }; function checkEnum$2(e) { - if (!(e === null || typeof e !== "object")) { + if (e !== null && typeof e === "object") { return "Object..."; } switch (e) { diff --git a/tests/tests/src/bdd.mjs b/tests/tests/src/bdd.mjs index dd2b767d28..ea08036d64 100644 --- a/tests/tests/src/bdd.mjs +++ b/tests/tests/src/bdd.mjs @@ -363,10 +363,8 @@ function random_vars(n) { function bool_equal(a, b) { if (a) { return b; - } else if (b) { - return false; } else { - return true; + return !b; } } diff --git a/tests/tests/src/bs_poly_map_test.mjs b/tests/tests/src/bs_poly_map_test.mjs index 5015db4a04..548269bfd8 100644 --- a/tests/tests/src/bs_poly_map_test.mjs +++ b/tests/tests/src/bs_poly_map_test.mjs @@ -210,7 +210,7 @@ let match$1 = match[0]; let match$2 = Belt_Map.get(v3, 10); -b("File \"bs_poly_map_test.res\", line 155, characters 4-11", match$2 !== undefined ? match$2 === 11 : false); +b("File \"bs_poly_map_test.res\", line 155, characters 4-11", match$2 === 11); let match$3 = Belt_Map.get(v3, -10); @@ -218,13 +218,13 @@ b("File \"bs_poly_map_test.res\", line 162, characters 4-11", match$3 === undefi let match$4 = Belt_Map.get(v4, -10); -b("File \"bs_poly_map_test.res\", line 169, characters 4-11", match$4 !== undefined ? match$4 === 0 : false); +b("File \"bs_poly_map_test.res\", line 169, characters 4-11", match$4 === 0); b("File \"bs_poly_map_test.res\", line 175, characters 4-11", Belt_Map.isEmpty(Belt_Map.remove(Belt_Map.make(Icmp), 0))); b("File \"bs_poly_map_test.res\", line 176, characters 4-11", Belt_Map.isEmpty(Belt_Map.removeMany(Belt_Map.make(Icmp), [0]))); -b("File \"bs_poly_map_test.res\", line 178, characters 4-11", pres !== undefined ? pres === 5000 : false); +b("File \"bs_poly_map_test.res\", line 178, characters 4-11", pres === 5000); b("File \"bs_poly_map_test.res\", line 184, characters 4-11", Belt_Array.eq(Belt_Map.keysToArray(match$1[0]), Belt_Array.makeBy(5000, i => i), (prim0, prim1) => prim0 === prim1)); diff --git a/tests/tests/src/complex_while_loop.mjs b/tests/tests/src/complex_while_loop.mjs index 5fd9b2aa27..ad885374a3 100644 --- a/tests/tests/src/complex_while_loop.mjs +++ b/tests/tests/src/complex_while_loop.mjs @@ -5,10 +5,10 @@ function f() { let n = 0; while ((() => { let fib = x => { - if (x === 0 || x === 1) { - return 1; - } else { + if (x !== 0 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } }; return fib(n) > 10; diff --git a/tests/tests/src/core/Core_NullableTests.mjs b/tests/tests/src/core/Core_NullableTests.mjs index 7228bd972c..f781a4e6cc 100644 --- a/tests/tests/src/core/Core_NullableTests.mjs +++ b/tests/tests/src/core/Core_NullableTests.mjs @@ -7,7 +7,7 @@ function shouldHandleNullableValues() { let tUndefined = undefined; let tValue = "hello"; let tmp; - tmp = (tNull == null) ? tNull === null : false; + tmp = tNull === null; Test.run([ [ "Core_NullableTests.res", @@ -29,7 +29,7 @@ function shouldHandleNullableValues() { "Should handle undefined" ], tmp$1, (prim0, prim1) => prim0 === prim1, true); let tmp$2; - tmp$2 = (tValue == null) ? false : tValue === "hello"; + tmp$2 = tValue === "hello"; Test.run([ [ "Core_NullableTests.res", diff --git a/tests/tests/src/demo_page.mjs b/tests/tests/src/demo_page.mjs index ee3b1665a5..cacf467d0b 100644 --- a/tests/tests/src/demo_page.mjs +++ b/tests/tests/src/demo_page.mjs @@ -4,10 +4,10 @@ import * as React from "react"; import * as ReactDom from "react-dom"; function fib(x) { - if (x === 2 || x === 1) { - return 1; - } else { + if (x !== 2 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } } diff --git a/tests/tests/src/exception_rebound_err_test.mjs b/tests/tests/src/exception_rebound_err_test.mjs index a43cea2ec0..fcb0d2812e 100644 --- a/tests/tests/src/exception_rebound_err_test.mjs +++ b/tests/tests/src/exception_rebound_err_test.mjs @@ -52,7 +52,7 @@ function test_js_error4() { } } else if (e.RE_EXN_ID === B) { return 5; - } else if (e.RE_EXN_ID === C && !(e._1 !== 1 || e._2 !== 2)) { + } else if (e.RE_EXN_ID === C && e._1 === 1 && e._2 === 2) { return 6; } else { return 7; diff --git a/tests/tests/src/fib.mjs b/tests/tests/src/fib.mjs index 40a3b661f3..9c974944f1 100644 --- a/tests/tests/src/fib.mjs +++ b/tests/tests/src/fib.mjs @@ -2,10 +2,10 @@ function fib(x) { - if (x === 0 || x === 1) { - return 1; - } else { + if (x !== 0 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } } diff --git a/tests/tests/src/gpr_3877_test.mjs b/tests/tests/src/gpr_3877_test.mjs index 66f0c8d4ff..2c16b2d958 100644 --- a/tests/tests/src/gpr_3877_test.mjs +++ b/tests/tests/src/gpr_3877_test.mjs @@ -3,10 +3,10 @@ function test(code) { if (code > 599 || code < 500) { - if (code === 201 || code === 200) { - return "good response"; - } else { + if (code !== 201 && code !== 200) { return "the catch all"; + } else { + return "good response"; } } else if (code > 597 || code < 512) { return "bad response"; diff --git a/tests/tests/src/gpr_4900_test.mjs b/tests/tests/src/gpr_4900_test.mjs index 5d3ef07f54..1113493aeb 100644 --- a/tests/tests/src/gpr_4900_test.mjs +++ b/tests/tests/src/gpr_4900_test.mjs @@ -11,8 +11,8 @@ let test_id = { }; function showToJs(x) { - if (typeof x !== "object" && x === "No") { - return false; + if (typeof x !== "object") { + return x !== "No"; } else { return true; } diff --git a/tests/tests/src/gpr_4924_test.mjs b/tests/tests/src/gpr_4924_test.mjs index fc3b42303d..03278edbad 100644 --- a/tests/tests/src/gpr_4924_test.mjs +++ b/tests/tests/src/gpr_4924_test.mjs @@ -27,8 +27,8 @@ function u1(b) { } function u2(b) { - if (typeof b !== "object" && b === "A") { - return false; + if (typeof b !== "object") { + return b !== "A"; } else { return true; } @@ -57,8 +57,8 @@ function u4(b) { } function u5(b) { - if (typeof b !== "object" && b === "A") { - return false; + if (typeof b !== "object") { + return b !== "A"; } else { return true; } diff --git a/tests/tests/src/int_overflow_test.mjs b/tests/tests/src/int_overflow_test.mjs index 8f44d3aae1..192ca3ca25 100644 --- a/tests/tests/src/int_overflow_test.mjs +++ b/tests/tests/src/int_overflow_test.mjs @@ -28,10 +28,10 @@ function hash_variant2(s) { } function fib(x) { - if (x === 0 || x === 1) { - return 1; - } else { + if (x !== 0 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } } diff --git a/tests/tests/src/json_decorders.mjs b/tests/tests/src/json_decorders.mjs index cac0277cc7..781dfca57d 100644 --- a/tests/tests/src/json_decorders.mjs +++ b/tests/tests/src/json_decorders.mjs @@ -3,7 +3,7 @@ import * as $$Array from "rescript/lib/es6/Array.js"; function decodeUser(json) { - if (!(typeof json === "object" && !Array.isArray(json))) { + if (typeof json !== "object" || Array.isArray(json)) { return; } let id = json.id; @@ -30,7 +30,7 @@ function decodeUser(json) { } function decodeGroup(json) { - if (!(typeof json === "object" && !Array.isArray(json))) { + if (typeof json !== "object" || Array.isArray(json)) { return; } let id = json.id; diff --git a/tests/tests/src/test_bool_equal.mjs b/tests/tests/src/test_bool_equal.mjs index 6d0bc4e9d6..d7e5c90a32 100644 --- a/tests/tests/src/test_bool_equal.mjs +++ b/tests/tests/src/test_bool_equal.mjs @@ -4,10 +4,8 @@ function bool_equal(x, y) { if (x) { return y; - } else if (y) { - return false; } else { - return true; + return !y; } } diff --git a/tests/tests/src/test_demo.mjs b/tests/tests/src/test_demo.mjs index 048494ef32..44e19f2540 100644 --- a/tests/tests/src/test_demo.mjs +++ b/tests/tests/src/test_demo.mjs @@ -3,10 +3,10 @@ import * as Belt_List from "rescript/lib/es6/Belt_List.js"; function fib(x) { - if (x === 2 || x === 1) { - return 1; - } else { + if (x !== 2 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } } diff --git a/tests/tests/src/test_fib.mjs b/tests/tests/src/test_fib.mjs index 982775b5a6..4e488a8269 100644 --- a/tests/tests/src/test_fib.mjs +++ b/tests/tests/src/test_fib.mjs @@ -2,18 +2,18 @@ function fib(x) { - if (x === 0 || x === 1) { - return 1; - } else { + if (x !== 0 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } } function fib2(x) { - if (x === 2 || x === 1) { - return 1; - } else { + if (x !== 2 && x !== 1) { return fib2(x - 1 | 0) + fib2(x - 2 | 0) | 0; + } else { + return 1; } } diff --git a/tests/tests/src/test_while_side_effect.mjs b/tests/tests/src/test_while_side_effect.mjs index 2cbc733d44..315cd3bc1f 100644 --- a/tests/tests/src/test_while_side_effect.mjs +++ b/tests/tests/src/test_while_side_effect.mjs @@ -10,10 +10,10 @@ while (console.log(v.contents.toString()), v.contents = v.contents + 1 | 0, v.co }; function fib(x) { - if (x === 0 || x === 1) { - return 1; - } else { + if (x !== 0 && x !== 1) { return fib(x - 1 | 0) + fib(x - 2 | 0) | 0; + } else { + return 1; } } diff --git a/tests/tests/src/topsort_test.mjs b/tests/tests/src/topsort_test.mjs index 90fdebb6c5..2dc512b66a 100644 --- a/tests/tests/src/topsort_test.mjs +++ b/tests/tests/src/topsort_test.mjs @@ -545,7 +545,7 @@ try { let match$2 = match$1.tl; if (match$2 && match$2.hd === "eat") { let match$3 = match$2.tl; - if (!(match$3 && match$3.hd === "go" && !match$3.tl)) { + if (!(match$3 && !(match$3.hd !== "go" || match$3.tl))) { exit = 1; } diff --git a/tests/tests/src/tramp_fib.mjs b/tests/tests/src/tramp_fib.mjs index 69ceed051f..2d440bb5a3 100644 --- a/tests/tests/src/tramp_fib.mjs +++ b/tests/tests/src/tramp_fib.mjs @@ -15,13 +15,13 @@ function eq(loc, x, y) { } function fib(n, k) { - if (n === 0 || n === 1) { - return k(1); - } else { + if (n !== 0 && n !== 1) { return { TAG: "Suspend", _0: () => fib(n - 1 | 0, v0 => fib(n - 2 | 0, v1 => k(v0 + v1 | 0))) }; + } else { + return k(1); } } diff --git a/tests/tests/src/variantsMatching.mjs b/tests/tests/src/variantsMatching.mjs index e4b281726f..4e367a3740 100644 --- a/tests/tests/src/variantsMatching.mjs +++ b/tests/tests/src/variantsMatching.mjs @@ -74,8 +74,8 @@ function st(state) { } function showToJs(x) { - if (typeof x !== "object" && x === "No") { - return false; + if (typeof x !== "object") { + return x !== "No"; } else { return true; } @@ -96,7 +96,11 @@ function third(l) { return false; } let match$1 = match.tl; - return match$1 && !(match$1.hd !== 3 || match$1.tl); + if (match$1 && match$1.hd === 3) { + return !match$1.tl; + } else { + return false; + } } function third2(l) { @@ -274,13 +278,13 @@ function plus$3(x, y) { case "WhyNotAnotherOne" : break; } - } else if (!(y === null || y === "WhyNotAnotherOne" || y === undefined)) { + } else if (y !== null && y !== "WhyNotAnotherOne" && y !== undefined) { return { x: x.x + y.x, y: x.y + y.y }; } - if (!(y === null || y === "WhyNotAnotherOne" || y === undefined)) { + if (y !== null && y !== "WhyNotAnotherOne" && y !== undefined) { return "WhyNotAnotherOne"; } switch (y) { @@ -293,7 +297,7 @@ function plus$3(x, y) { } function kind$1(x) { - if (!(x === null || x === "WhyNotAnotherOne" || x === undefined)) { + if (x !== null && x !== "WhyNotAnotherOne" && x !== undefined) { return "present"; } switch (x) { From 2dad0322838230710998514e59773f240eb22164 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 8 Nov 2024 13:35:35 +0100 Subject: [PATCH 02/10] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba3fd69f59..6c5ad614c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ - Improve pattern matching on optional fields. https://github.com/rescript-lang/rescript-compiler/pull/7143 https://github.com/rescript-lang/rescript-compiler/pull/7144 - Optimize compilation of switch statements for untagged variants when there are no literal cases. https://github.com/rescript-lang/rescript-compiler/pull/7135 - Further improve boolean optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7149 +- Simplify code generated forconditionals. https://github.com/rescript-lang/rescript-compiler/pull/7151 #### :house: Internal From 0d49895dc9f272fdb16ebb704b7a75deec4772d6 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 8 Nov 2024 13:42:08 +0100 Subject: [PATCH 03/10] Squeeze in side effects check From https://github.com/rescript-lang/rescript-compiler/pull/7149/files#r1834278587 --- compiler/core/js_exp_make.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 828d3f61dc..65bea5242b 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -743,7 +743,7 @@ let rec simplify_and ~n (e1 : t) (e2 : t) : t option = let res = match (e1.expression_desc, e2.expression_desc) with | Bool false, _ -> Some false_ - | _, Bool false -> Some false_ + | _, Bool false when no_side_effect e1 -> Some false_ | Bool true, _ -> Some e2 | _, Bool true -> Some e1 | Bin (And, a, b), _ -> ( From 8bb34736e19171caf3ea13c0e911b6bcf39a5d44 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 8 Nov 2024 13:58:25 +0100 Subject: [PATCH 04/10] comment --- compiler/core/js_exp_make.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 65bea5242b..0dfc0166d9 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -702,7 +702,7 @@ let rec push_negation (e : t) : t option = Basic simplification rules: - [false && e] -> [false] - [true && e] -> [e] - - [e && false] -> [false] + - [e && false] -> [false] If [e] has no side effects - [e && true] -> [e] - [(a && b) && e] -> If either [a && e] or [b && e] can be simplified, creates new AND expression with simplified parts: [(a' && b')] From 30a6b2d0b77ae1c376177a897cd54f8eb356b0c7 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sat, 9 Nov 2024 08:37:25 +0100 Subject: [PATCH 05/10] Only apply optimisations when there are no side effects. --- compiler/core/js_analyzer.ml | 8 +++-- compiler/core/js_exp_make.ml | 48 ++++++++++++++++------------ tests/tests/src/option_repr_test.mjs | 4 +-- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/compiler/core/js_analyzer.ml b/compiler/core/js_analyzer.ml index 2b660a025a..7411de8bcf 100644 --- a/compiler/core/js_analyzer.ml +++ b/compiler/core/js_analyzer.ml @@ -109,9 +109,11 @@ let rec no_side_effect_expression_desc (x : J.expression_desc) = no_side_effect call_expr && Ext_list.for_all strings no_side_effect && Ext_list.for_all values no_side_effect - | Js_not _ | Cond _ | FlatCall _ | Call _ | New _ | Raw_js_code _ - (* actually true? *) -> - false + | Js_not e -> no_side_effect e + | Cond (a, b, c) -> no_side_effect a && no_side_effect b && no_side_effect c + | Call ({expression_desc = Str {txt = "Array.isArray"}}, [e], _) -> + no_side_effect e + | FlatCall _ | Call _ | New _ | Raw_js_code _ (* actually true? *) -> false | Await _ -> false | Spread _ -> false diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 0dfc0166d9..1310675f56 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -696,13 +696,13 @@ let rec push_negation (e : t) : t option = | _ -> None (** - [simplify_and e1 e2] attempts to simplify the boolean AND expression [e1 && e2]. + [simplify_and_ e1 e2] attempts to simplify the boolean AND expression [e1 && e2]. Returns [Some simplified] if simplification is possible, [None] otherwise. Basic simplification rules: - [false && e] -> [false] - [true && e] -> [e] - - [e && false] -> [false] If [e] has no side effects + - [e && false] -> [false] - [e && true] -> [e] - [(a && b) && e] -> If either [a && e] or [b && e] can be simplified, creates new AND expression with simplified parts: [(a' && b')] @@ -735,7 +735,7 @@ let rec push_negation (e : t) : t option = attempting to reduce it to a simpler form. If no simplification is possible, returns [None]. *) -let rec simplify_and ~n (e1 : t) (e2 : t) : t option = +let rec simplify_and_ ~n (e1 : t) (e2 : t) : t option = if debug then Printf.eprintf "%s simplify_and %s %s\n" (String.make (n * 2) ' ') @@ -743,34 +743,34 @@ let rec simplify_and ~n (e1 : t) (e2 : t) : t option = let res = match (e1.expression_desc, e2.expression_desc) with | Bool false, _ -> Some false_ - | _, Bool false when no_side_effect e1 -> Some false_ + | _, Bool false -> Some false_ | Bool true, _ -> Some e2 | _, Bool true -> Some e1 | Bin (And, a, b), _ -> ( - let ao = simplify_and ~n:(n + 1) a e2 in - let bo = simplify_and ~n:(n + 1) b e2 in + let ao = simplify_and_ ~n:(n + 1) a e2 in + let bo = simplify_and_ ~n:(n + 1) b e2 in match (ao, bo) with | None, None -> ( - match simplify_and ~n:(n + 1) a b with + match simplify_and_ ~n:(n + 1) a b with | None -> None | Some e -> simplify_and_force ~n:(n + 1) e e2) | Some a_, None -> simplify_and_force ~n:(n + 1) a_ b | None, Some b_ -> simplify_and_force ~n:(n + 1) a b_ | Some a_, Some b_ -> simplify_and_force ~n:(n + 1) a_ b_) | _, Bin (And, a, b) -> - simplify_and ~n:(n + 1) + simplify_and_ ~n:(n + 1) {expression_desc = Bin (And, e1, a); comment = None} b | Bin (Or, a, b), _ -> ( - let ao = simplify_and ~n:(n + 1) a e2 in - let bo = simplify_and ~n:(n + 1) b e2 in + let ao = simplify_and_ ~n:(n + 1) a e2 in + let bo = simplify_and_ ~n:(n + 1) b e2 in match (ao, bo) with | Some {expression_desc = Bool false}, None -> Some {expression_desc = Bin (And, b, e2); comment = None} | None, Some {expression_desc = Bool false} -> Some {expression_desc = Bin (And, a, e2); comment = None} | None, _ | _, None -> ( - match simplify_or ~n:(n + 1) a b with + match simplify_or_ ~n:(n + 1) a b with | None -> None | Some e -> simplify_and_force ~n:(n + 1) e e2) | Some a_, Some b_ -> simplify_or_force ~n:(n + 1) a_ b_) @@ -1037,12 +1037,12 @@ let rec simplify_and ~n (e1 : t) (e2 : t) : t option = res and simplify_and_force ~n (e1 : t) (e2 : t) : t option = - match simplify_and ~n e1 e2 with + match simplify_and_ ~n e1 e2 with | None -> Some {expression_desc = Bin (And, e1, e2); comment = None} | x -> x (** - [simplify_or e1 e2] attempts to simplify the boolean OR expression [e1 || e2]. + [simplify_or_ e1 e2] attempts to simplify the boolean OR expression [e1 || e2]. Returns [Some simplified] if simplification is possible, [None] otherwise. Basic simplification rules: @@ -1061,7 +1061,7 @@ and simplify_and_force ~n (e1 : t) (e2 : t) : t option = This transformation allows reuse of [simplify_and]'s more extensive optimizations in the context of OR expressions. *) -and simplify_or ~n (e1 : t) (e2 : t) : t option = +and simplify_or_ ~n (e1 : t) (e2 : t) : t option = if debug then Printf.eprintf "%ssimplify_or %s %s\n" (String.make (n * 2) ' ') @@ -1076,7 +1076,7 @@ and simplify_or ~n (e1 : t) (e2 : t) : t option = | _ -> ( match (push_negation e1, push_negation e2) with | Some e1_, Some e2_ -> ( - match simplify_and ~n:(n + 1) e1_ e2_ with + match simplify_and_ ~n:(n + 1) e1_ e2_ with | Some e -> push_negation e | None -> None) | _ -> None) @@ -1091,10 +1091,18 @@ and simplify_or ~n (e1 : t) (e2 : t) : t option = res and simplify_or_force ~n (e1 : t) (e2 : t) : t option = - match simplify_or ~n e1 e2 with + match simplify_or_ ~n e1 e2 with | None -> Some {expression_desc = Bin (Or, e1, e2); comment = None} | x -> x +let simplify_and (e1 : t) (e2 : t) : t option = + if no_side_effect e1 && no_side_effect e2 then simplify_and_ ~n:0 e1 e2 + else None + +let simplify_or (e1 : t) (e2 : t) : t option = + if no_side_effect e1 && no_side_effect e2 then simplify_or_ ~n:0 e1 e2 + else None + let and_ ?comment (e1 : t) (e2 : t) : t = match (e1.expression_desc, e2.expression_desc) with | Var i, Var j when Js_op_util.same_vident i j -> e1 @@ -1111,7 +1119,7 @@ let and_ ?comment (e1 : t) (e2 : t) : t = when Js_op_util.same_vident i j -> e2 | _, _ -> ( - match simplify_and ~n:0 e1 e2 with + match simplify_and e1 e2 with | Some e -> e | None -> {expression_desc = Bin (And, e1, e2); comment}) @@ -1125,7 +1133,7 @@ let or_ ?comment (e1 : t) (e2 : t) = when Js_op_util.same_vident i j -> {e2 with expression_desc = Bin (Or, r, l)} | _, _ -> ( - match simplify_or ~n:0 e1 e2 with + match simplify_or e1 e2 with | Some e -> e | None -> {expression_desc = Bin (Or, e1, e2); comment}) @@ -1190,11 +1198,11 @@ let rec econd ?comment (pred : t) (ifso : t) (ifnot : t) : t = Seq (b, {expression_desc = Undefined _}) ) -> seq (econd ?comment pred a b) undefined | _, _, Bool false -> ( - match simplify_and ~n:0 pred ifso with + match simplify_and pred ifso with | Some e -> e | None -> default ()) | _, Bool false, _ -> ( - match simplify_and ~n:0 (not pred) ifnot with + match simplify_and (not pred) ifnot with | Some e -> e | None -> default ()) | _ -> default () diff --git a/tests/tests/src/option_repr_test.mjs b/tests/tests/src/option_repr_test.mjs index 9f4d0e742b..d67be245ef 100644 --- a/tests/tests/src/option_repr_test.mjs +++ b/tests/tests/src/option_repr_test.mjs @@ -221,9 +221,9 @@ b("File \"option_repr_test.res\", line 127, characters 3-10", Belt_List.every(xs let xs_1$1 = { hd: neqx(undefined, null), tl: { - hd: Primitive_object.equal(Primitive_option.some(undefined), Primitive_option.some(undefined)), + hd: Primitive_object.equal(Primitive_option.some(undefined), Primitive_option.some(undefined)) && Primitive_object.equal(Primitive_option.some(undefined), Primitive_option.some(undefined)), tl: { - hd: Primitive_object.equal(Primitive_option.some(Primitive_option.some(undefined)), Primitive_option.some(Primitive_option.some(undefined))), + hd: Primitive_object.equal(Primitive_option.some(Primitive_option.some(undefined)), Primitive_option.some(Primitive_option.some(undefined))) && Primitive_object.equal(Primitive_option.some(Primitive_option.some(undefined)), Primitive_option.some(Primitive_option.some(undefined))), tl: { hd: Primitive_object.notequal(Primitive_option.some(Primitive_option.some(Primitive_option.some(undefined))), Primitive_option.some(Primitive_option.some(undefined))) && Primitive_object.notequal(Primitive_option.some(Primitive_option.some(undefined)), Primitive_option.some(Primitive_option.some(Primitive_option.some(undefined)))), tl: /* [] */0 From c0e5b7843b5ece3d3cf39a7e577b5e99c0deb544 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sun, 10 Nov 2024 08:57:41 +0100 Subject: [PATCH 06/10] More side effects. --- compiler/core/js_exp_make.ml | 26 ++++++++++++++++++-------- compiler/core/js_exp_make.mli | 2 +- compiler/core/lam_compile_primitive.ml | 8 ++++---- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 1310675f56..893753b761 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -1394,13 +1394,15 @@ let rec int_comp (cmp : Lam_compat.comparison) ?comment (e0 : t) (e1 : t) = _ ), Number (Int {i = 0l}) ) -> int_comp cmp l r (* = 0 > 0 < 0 *) - | Ceq, Optional_block _, Undefined _ | Ceq, Undefined _, Optional_block _ -> + | (Ceq, Optional_block _, Undefined _ | Ceq, Undefined _, Optional_block _) + when no_side_effect e0 && no_side_effect e1 -> false_ | Ceq, _, _ -> int_equal e0 e1 | Cneq, Optional_block _, Undefined _ | Cneq, Undefined _, Optional_block _ | Cneq, Caml_block _, Number _ - | Cneq, Number _, Caml_block _ -> + | Cneq, Number _, Caml_block _ + when no_side_effect e0 && no_side_effect e1 -> true_ | _ -> bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 @@ -1718,7 +1720,7 @@ let of_block ?comment ?e block : t = let is_null ?comment (x : t) = triple_equal ?comment x nil let is_undef ?comment x = triple_equal ?comment x undefined -let for_sure_js_null_undefined (x : t) = +let is_null_undefined_constant (x : t) = match x.expression_desc with | Null | Undefined _ -> true | _ -> false @@ -1730,28 +1732,36 @@ let is_null_undefined ?comment (x : t) : t = | _ -> {comment; expression_desc = Is_null_or_undefined x} let eq_null_undefined_boolean ?comment (a : t) (b : t) = + (* [a == b] when either a or b is null or undefined *) match (a.expression_desc, b.expression_desc) with | ( (Null | Undefined _), - (Bool _ | Number _ | Typeof _ | Fun _ | Array _ | Caml_block _) ) -> + (Bool _ | Number _ | Typeof _ | Fun _ | Array _ | Caml_block _) ) + when no_side_effect b -> false_ | ( (Bool _ | Number _ | Typeof _ | Fun _ | Array _ | Caml_block _), - (Null | Undefined _) ) -> + (Null | Undefined _) ) + when no_side_effect a -> false_ | Null, Undefined _ | Undefined _, Null -> false_ | Null, Null | Undefined _, Undefined _ -> true_ | _ -> {expression_desc = Bin (EqEqEq, a, b); comment} let neq_null_undefined_boolean ?comment (a : t) (b : t) = + (* [a != b] when either a or b is null or undefined *) match (a.expression_desc, b.expression_desc) with | ( (Null | Undefined _), - (Bool _ | Number _ | Typeof _ | Fun _ | Array _ | Caml_block _) ) -> + (Bool _ | Number _ | Typeof _ | Fun _ | Array _ | Caml_block _) ) + when no_side_effect b -> true_ | ( (Bool _ | Number _ | Typeof _ | Fun _ | Array _ | Caml_block _), - (Null | Undefined _) ) -> + (Null | Undefined _) ) + when no_side_effect a -> true_ | Null, Null | Undefined _, Undefined _ -> false_ | Null, Undefined _ | Undefined _, Null -> true_ - | _ -> {expression_desc = Bin (NotEqEq, a, b); comment} + | _ -> + let _ = assert false in + {expression_desc = Bin (NotEqEq, a, b); comment} let make_exception (s : string) = pure_runtime_call Primitive_modules.exceptions Literals.create [str s] diff --git a/compiler/core/js_exp_make.mli b/compiler/core/js_exp_make.mli index e890e4c6aa..20022f942c 100644 --- a/compiler/core/js_exp_make.mli +++ b/compiler/core/js_exp_make.mli @@ -365,7 +365,7 @@ val is_null : ?comment:string -> t -> t val is_undef : ?comment:string -> t -> t -val for_sure_js_null_undefined : J.expression -> bool +val is_null_undefined_constant : J.expression -> bool val is_null_undefined : ?comment:string -> t -> t diff --git a/compiler/core/lam_compile_primitive.ml b/compiler/core/lam_compile_primitive.ml index efea6c977b..47c255afb2 100644 --- a/compiler/core/lam_compile_primitive.ml +++ b/compiler/core/lam_compile_primitive.ml @@ -373,13 +373,13 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) match args with | [e1; e2] when cmp = Ceq - && (E.for_sure_js_null_undefined e1 - || E.for_sure_js_null_undefined e2) -> + && (E.is_null_undefined_constant e1 + || E.is_null_undefined_constant e2) -> E.eq_null_undefined_boolean e1 e2 | [e1; e2] when cmp = Cneq - && (E.for_sure_js_null_undefined e1 - || E.for_sure_js_null_undefined e2) -> + && (E.is_null_undefined_constant e1 + || E.is_null_undefined_constant e2) -> E.neq_null_undefined_boolean e1 e2 | [e1; e2] -> Location.prerr_warning loc Warnings.Bs_polymorphic_comparison; From 00b9b92cb9df0642d3371f754fe2dbcd3478360f Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sun, 10 Nov 2024 09:38:24 +0100 Subject: [PATCH 07/10] More side effect cases. --- compiler/core/js_exp_make.ml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 893753b761..e894d761dd 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -559,7 +559,8 @@ let string_length ?comment (e : t) : t = (* TODO: use [Buffer] instead? *) let bytes_length ?comment (e : t) : t = match e.expression_desc with - | Array (l, _) -> int ?comment (Int32.of_int (List.length l)) + | Array (l, _) when no_side_effect e -> + int ?comment (Int32.of_int (List.length l)) | _ -> {expression_desc = Length (e, Bytes); comment} let function_length ?comment (e : t) : t = @@ -624,7 +625,8 @@ let rec triple_equal ?comment (e0 : t) (e1 : t) : t = | Undefined _, Optional_block _ | Optional_block _, Undefined _ | Null, Undefined _ - | Undefined _, Null -> + | Undefined _, Null + when no_side_effect e0 && no_side_effect e1 -> false_ | Null, Null | Undefined _, Undefined _ -> true_ | _ -> {expression_desc = Bin (EqEqEq, e0, e1); comment} @@ -1604,11 +1606,9 @@ let is_pos_pow n = let int32_mul ?comment (e1 : J.expression) (e2 : J.expression) : J.expression = match (e1, e2) with - | {expression_desc = Number (Int {i = 0l}); _}, x - when Js_analyzer.no_side_effect_expression x -> + | {expression_desc = Number (Int {i = 0l}); _}, x when no_side_effect x -> zero_int_literal - | x, {expression_desc = Number (Int {i = 0l}); _} - when Js_analyzer.no_side_effect_expression x -> + | x, {expression_desc = Number (Int {i = 0l}); _} when no_side_effect x -> zero_int_literal | ( {expression_desc = Number (Int {i = i0}); _}, {expression_desc = Number (Int {i = i1}); _} ) -> From 90f7e9bb7bbf4b958c3726a6003aa28ca3c8d524 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sun, 10 Nov 2024 09:45:44 +0100 Subject: [PATCH 08/10] dead code --- compiler/core/js_exp_make.ml | 7 ------- compiler/core/js_exp_make.mli | 2 -- 2 files changed, 9 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index e894d761dd..652f1d844d 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -556,13 +556,6 @@ let string_length ?comment (e : t) : t = (* No optimization for {j||j}*) | _ -> {expression_desc = Length (e, String); comment} -(* TODO: use [Buffer] instead? *) -let bytes_length ?comment (e : t) : t = - match e.expression_desc with - | Array (l, _) when no_side_effect e -> - int ?comment (Int32.of_int (List.length l)) - | _ -> {expression_desc = Length (e, Bytes); comment} - let function_length ?comment (e : t) : t = match e.expression_desc with | Fun {is_method; params} -> diff --git a/compiler/core/js_exp_make.mli b/compiler/core/js_exp_make.mli index 20022f942c..f8216e1acb 100644 --- a/compiler/core/js_exp_make.mli +++ b/compiler/core/js_exp_make.mli @@ -143,8 +143,6 @@ val array_length : ?comment:string -> t -> t val string_length : ?comment:string -> t -> t -val bytes_length : ?comment:string -> t -> t - val function_length : ?comment:string -> t -> t val string_append : ?comment:string -> t -> t -> t From 1a5f2865feaff297d1c6eca4acfca8c2d75d8894 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sun, 10 Nov 2024 09:51:10 +0100 Subject: [PATCH 09/10] Add example of what was previously over-optimized. --- tests/tests/src/Equality_over_optimization.mjs | 9 +++++++++ tests/tests/src/Equality_over_optimization.res | 1 + 2 files changed, 10 insertions(+) create mode 100644 tests/tests/src/Equality_over_optimization.mjs create mode 100644 tests/tests/src/Equality_over_optimization.res diff --git a/tests/tests/src/Equality_over_optimization.mjs b/tests/tests/src/Equality_over_optimization.mjs new file mode 100644 index 0000000000..a9b38bff6e --- /dev/null +++ b/tests/tests/src/Equality_over_optimization.mjs @@ -0,0 +1,9 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +let z = undefined === [(console.log("hello"), undefined)]; + +export { + z, +} +/* z Not a pure module */ diff --git a/tests/tests/src/Equality_over_optimization.res b/tests/tests/src/Equality_over_optimization.res new file mode 100644 index 0000000000..a6bc04a918 --- /dev/null +++ b/tests/tests/src/Equality_over_optimization.res @@ -0,0 +1 @@ +let z = None == Some([Console.log("hello")]) From 6d4c212ab0900d8705a6f9c0ae6274d77de88ca3 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sun, 10 Nov 2024 09:58:05 +0100 Subject: [PATCH 10/10] Update CHANGELOG.md --- CHANGELOG.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c5ad614c5..45e8ef2753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,20 @@ - Introduce "Unified operators" for arithmetic operators (`+`, `-`, `*`, `/`, `mod`). See https://github.com/rescript-lang/rescript-compiler/pull/7057 + +#### :bug: Bug fix +- Fix and clean up boolean and/or optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7134 https://github.com/rescript-lang/rescript-compiler/pull/7151 + +#### :nail_care: Polish +- Improve code generation for pattern matching of untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/7128 +- Improve negation handling in combination with and/or to simplify generated code (especially coming out of pattern matching). https://github.com/rescript-lang/rescript-compiler/pull/7138 +- optimize JavaScript code generation by using x == null checks and improving type-based optimizations for string/number literals. https://github.com/rescript-lang/rescript-compiler/pull/7141 +- Improve pattern matching on optional fields. https://github.com/rescript-lang/rescript-compiler/pull/7143 https://github.com/rescript-lang/rescript-compiler/pull/7144 +- Optimize compilation of switch statements for untagged variants when there are no literal cases. https://github.com/rescript-lang/rescript-compiler/pull/7135 +- Further improve boolean optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7149 +- Simplify code generated for conditionals. https://github.com/rescript-lang/rescript-compiler/pull/7151 + + # 12.0.0-alpha.4 #### :boom: Breaking Change @@ -44,10 +58,8 @@ - Fix variant cast to int. https://github.com/rescript-lang/rescript-compiler/pull/7058 - Fix comments formatted away in function without arguments. https://github.com/rescript-lang/rescript-compiler/pull/7095 - Fix genType JSX component compilation. https://github.com/rescript-lang/rescript-compiler/pull/7107 -- Fix and clean up boolean and/or optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7134 #### :nail_care: Polish - - Add some context to error message for unused variables. https://github.com/rescript-lang/rescript-compiler/pull/7050 - Improve error message when passing `children` prop to a component that doesn't accept it. https://github.com/rescript-lang/rescript-compiler/pull/7044 - Improve error messages for pattern matching on option vs non-option, and vice versa. https://github.com/rescript-lang/rescript-compiler/pull/7035 @@ -57,13 +69,6 @@ - Improve output of record copying. https://github.com/rescript-lang/rescript-compiler/pull/7043 - Provide additional context in error message when `unit` is expected. https://github.com/rescript-lang/rescript-compiler/pull/7045 - Improve error message when passing an object where a record is expected. https://github.com/rescript-lang/rescript-compiler/pull/7101 -- Improve code generation or pattern matching of untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/7128 -- Improve negation handling in combination with and/or to simplify generated code (especially coming out of pattern matching). https://github.com/rescript-lang/rescript-compiler/pull/7138 -- optimize JavaScript code generation by using x == null checks and improving type-based optimizations for string/number literals. https://github.com/rescript-lang/rescript-compiler/pull/7141 -- Improve pattern matching on optional fields. https://github.com/rescript-lang/rescript-compiler/pull/7143 https://github.com/rescript-lang/rescript-compiler/pull/7144 -- Optimize compilation of switch statements for untagged variants when there are no literal cases. https://github.com/rescript-lang/rescript-compiler/pull/7135 -- Further improve boolean optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7149 -- Simplify code generated forconditionals. https://github.com/rescript-lang/rescript-compiler/pull/7151 #### :house: Internal