From a838d9df0a96258c1871cefdd0fa50dade7deff8 Mon Sep 17 00:00:00 2001 From: RblSb Date: Fri, 31 Jan 2025 16:12:08 +0300 Subject: [PATCH] Fix null coal assign --- src/typing/typer.ml | 14 ++++++++---- tests/optimization/src/issues/Issue11931.hx | 25 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 tests/optimization/src/issues/Issue11931.hx diff --git a/src/typing/typer.ml b/src/typing/typer.ml index af4a6cb994e..654780c1a82 100644 --- a/src/typing/typer.ml +++ b/src/typing/typer.ml @@ -1877,10 +1877,16 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = let e_cond = mk (TBinop(OpNotEq,e1,e_null)) ctx.t.tbool e1.epos in let e_if = mk (TIf(e_cond,cast e1,Some e2)) iftype p in vr#to_texpr e_if - | EBinop (OpAssignOp OpNullCoal,e1,e2) -> - let e_cond = EBinop(OpNotEq,e1,(EConst(Ident "null"), p)) in - let e_if = EIf ((e_cond, p),e1,Some e2) in - type_assign ctx e1 (e_if, p) with_type p + | EBinop (OpAssignOp OpNullCoal,e1_orig,e2) -> + let vr = new value_reference ctx in + let e1 = type_expr ctx (Expr.ensure_block e1_orig) with_type in + let e1_null_t = if is_nullable e1.etype then e1.etype else ctx.t.tnull e1.etype in + let e1_var = vr#as_var (Option.default "tmp" (WithType.get_expected_name with_type)) {e1 with etype = e1_null_t} in + let e_null = Builder.make_null e1_null_t e1.epos in + let e_cond = mk (TBinop(OpNotEq,e1_var,e_null)) ctx.t.tbool e1.epos in + let e_assign = type_assign ctx e1_orig (Expr.ensure_block e2) with_type p in + let e_if = mk (TIf(e_cond,e1_var,Some e_assign)) e1.etype p in + vr#to_texpr e_if | EBinop (op,e1,e2) -> type_binop ctx op e1 e2 false with_type p | EBlock [] when (match with_type with diff --git a/tests/optimization/src/issues/Issue11931.hx b/tests/optimization/src/issues/Issue11931.hx new file mode 100644 index 00000000000..4d3f81303b4 --- /dev/null +++ b/tests/optimization/src/issues/Issue11931.hx @@ -0,0 +1,25 @@ +package issues; + +class Issue11931 { + @:js(' + var arr = []; + var _g = 0; + var _g1 = issues_Issue11931.test_i; + while(_g < _g1) { + var x = _g++; + var e = arr[x]; + issues_Issue11931.use(e != null ? e : arr[x] = []); + } + ') + static function test() { + static var i = 0; + var arr:Array> = []; + for (x in 0...i) { + var e = arr[x] ??= []; + use(e); + } + } + + @:pure(false) + static function use(v:Array) {} +}