Skip to content

Commit

Permalink
Can i extract this TBinop?
Browse files Browse the repository at this point in the history
  • Loading branch information
RblSb committed Jan 31, 2025
1 parent a838d9d commit 8df3fcf
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
14 changes: 9 additions & 5 deletions src/typing/typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1877,14 +1877,18 @@ 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_orig,e2) ->
| EBinop (OpAssignOp OpNullCoal,e1,e2) ->
let vr = new value_reference ctx in
let e1 = type_expr ctx (Expr.ensure_block e1_orig) with_type in
let e_assign = type_assign ctx e1 (Expr.ensure_block e2) WithType.value p in
let e1 = match e_assign.eexpr with
| TBinop(OpAssign,e1_left,_) -> e1_left
| _ -> raise_typing_error "Invalid null coalescing assignment" p
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_null = Builder.make_null e1_null_t p in
let e_cond = mk (TBinop(OpNotEq,e1_var,e_null)) ctx.t.tbool 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) ->
Expand Down
18 changes: 5 additions & 13 deletions tests/optimization/src/issues/Issue11931.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,13 @@ 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] = []);
}
var e = arr[0];
issues_Issue11931.use(e != null ? e : arr[0] = []);
')
static function test() {
static var i = 0;
var arr:Array<Array<Int>> = [];
for (x in 0...i) {
var e = arr[x] ??= [];
use(e);
}
var arr = [];
var e = arr[0] ??= [];
use(e);
}

@:pure(false)
Expand Down
43 changes: 43 additions & 0 deletions tests/unit/src/unit/TestNullCoalescing.hx
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,48 @@ class TestNullCoalescing extends Test {
t(HelperMacros.isNullable(nullF2));
f(HelperMacros.isNullable(notNullF));
f(HelperMacros.isNullable(notNullF2));

// test typing
#if !macro
var a = mut() ?? mut();
eq(2, getMut());
resetMut();

var a = 0;
mutAssignLeft() ??= mut() ?? mut();
eq(3, getMut());
resetMut();

var a = 0;
final b = a ??= mut();
eq(1, getMut());
resetMut();

var a = 0;
mutAssignLeft() ??= 1;
eq(1, getMut());
resetMut();
#end
}

static var mutI = 0;

static macro function mut() {
mutI++;
return macro mutI;
}

static macro function getMut() {
return macro $v{mutI};
}

static macro function resetMut() {
mutI = 0;
return macro $v{mutI};
}

static macro function mutAssignLeft() {
mutI++;
return macro a;
}
}

0 comments on commit 8df3fcf

Please sign in to comment.