diff --git a/CHANGELOG.md b/CHANGELOG.md index bb20b8affc..c53d07088c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ # 12.0.0-alpha.6 (Unreleased) +#### :bug: Bug fix +- Fix bug where a ref assignment is moved ouside a conditional. https://github.com/rescript-lang/rescript/pull/7176 + # 12.0.0-alpha.5 #### :rocket: New Feature diff --git a/compiler/core/js_analyzer.mli b/compiler/core/js_analyzer.mli index 7a1f281663..786c29fece 100644 --- a/compiler/core/js_analyzer.mli +++ b/compiler/core/js_analyzer.mli @@ -29,7 +29,7 @@ val free_variables_of_statement : J.statement -> Set_ident.t -val free_variables_of_expression : J.finish_ident_expression -> Set_ident.t +val free_variables_of_expression : J.expression -> Set_ident.t (* val no_side_effect_expression_desc : J.expression_desc -> bool *) diff --git a/compiler/core/js_stmt_make.ml b/compiler/core/js_stmt_make.ml index 0067e89ccc..e4d87302e9 100644 --- a/compiler/core/js_stmt_make.ml +++ b/compiler/core/js_stmt_make.ml @@ -232,8 +232,6 @@ let rec block_last_is_return_throw_or_continue (x : J.block) = *) let if_ ?comment ?declaration ?else_ (e : J.expression) (then_ : J.block) : t = let declared = ref false in - let common_prefix_blocks = ref [] in - let add_prefix b = common_prefix_blocks := b :: !common_prefix_blocks in let rec aux ?comment (e : J.expression) (ifso : J.block) (ifnot : J.block) : t = match (e.expression_desc, ifnot) with @@ -301,14 +299,6 @@ let if_ ?comment ?declaration ?else_ (e : J.expression) (then_ : J.block) : t = | _, [{statement_desc = If (pred1, ifso1, ifnot1)}] when Js_analyzer.eq_block ifso ifnot1 -> aux ?comment (E.or_ e (E.not pred1)) ifso ifso1 - | ifso1 :: ifso_rest, ifnot1 :: ifnot_rest - when Js_analyzer.eq_statement ifnot1 ifso1 - && Js_analyzer.no_side_effect_expression e -> - (* here we do agressive optimization, because it can help optimization later, - move code outside of branch is generally helpful later - *) - add_prefix ifso1; - aux ?comment e ifso_rest ifnot_rest | _ -> {statement_desc = If (e, ifso, ifnot); comment}) in let if_block = @@ -317,12 +307,9 @@ let if_ ?comment ?declaration ?else_ (e : J.expression) (then_ : J.block) : t = | None -> [] | Some v -> v) in - let prefix = !common_prefix_blocks in match (!declared, declaration) with - | true, _ | _, None -> - if prefix = [] then if_block else block (List.rev_append prefix [if_block]) - | false, Some (kind, id) -> - block (declare_variable ~kind id :: List.rev_append prefix [if_block]) + | true, _ | _, None -> if_block + | false, Some (kind, id) -> block (declare_variable ~kind id :: [if_block]) let assign ?comment id e : t = {statement_desc = J.Exp (E.assign (E.var id) e); comment} diff --git a/tests/tests/src/move_ref_assignment.mjs b/tests/tests/src/move_ref_assignment.mjs new file mode 100644 index 0000000000..acd9050656 --- /dev/null +++ b/tests/tests/src/move_ref_assignment.mjs @@ -0,0 +1,33 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +let j = 1; + +let k = { + c: 1 +}; + +function upd() { + k.c = 3; +} + +if (k.c === 1) { + upd(); + j = j + 2 | 0; + console.log("correct"); +} else { + upd(); + j = j + 2 | 0; + console.log("incorrect"); +} + +let j$1 = 0; + +let k$1 = 0; + +export { + upd, + j$1 as j, + k$1 as k, +} +/* Not a pure module */ diff --git a/tests/tests/src/move_ref_assignment.res b/tests/tests/src/move_ref_assignment.res new file mode 100644 index 0000000000..3e6af9b5ca --- /dev/null +++ b/tests/tests/src/move_ref_assignment.res @@ -0,0 +1,19 @@ +type t = {mutable c: int} + +let j = {c: 1} +let k = {c: 1} + +let upd = () => k.c = 3 + +if k.c == 1 { + upd() + j.c = j.c + 2 + Console.log("correct") +} else { + upd() + j.c = j.c + 2 + Console.log("incorrect") +} + +let j = 0 +let k = 0 diff --git a/tests/tests/src/test_ramification.mjs b/tests/tests/src/test_ramification.mjs index 18fb48f4f4..bcde916376 100644 --- a/tests/tests/src/test_ramification.mjs +++ b/tests/tests/src/test_ramification.mjs @@ -33,11 +33,12 @@ function f(x) { function f2(x) { let v = 0; let y; - v = 1; if (x.TAG === "A") { + v = 1; let z = 33; y = z + 3 | 0; } else { + v = 1; let z$1 = 33; y = z$1 + 4 | 0; } @@ -47,8 +48,13 @@ function f2(x) { function f3(x) { let v = 0; let y; - v = 1; - y = x.TAG === "A" ? 3 : 4; + if (x.TAG === "A") { + v = 1; + y = 3; + } else { + v = 1; + y = 4; + } return y + 32 | 0; }