Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Early returns in NullCoal #10791

Merged
merged 7 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/typing/typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,28 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
let e1 = vr#as_var "tmp" {e1 with etype = ctx.t.tnull e1.etype} in
let e_null = Builder.make_null e1.etype e1.epos in
let e_cond = mk (TBinop(OpNotEq,e1,e_null)) ctx.t.tbool e1.epos in
let iftype = WithType.WithType(e2.etype,None) in
let rec is_dead_end e = match e.eexpr with
| TParenthesis e -> is_dead_end e
| TThrow _ -> true
| TReturn _ -> true
| TBreak -> true
| TContinue -> true
| TWhile (_, body, DoWhile) -> is_dead_end body
| TIf (_, if_body, Some else_body) -> is_dead_end if_body && is_dead_end else_body
| TBlock exprs -> List.exists is_dead_end exprs
| TMeta (_, e) -> is_dead_end e
| TCast (e, _) -> is_dead_end e
| _ -> false in
Simn marked this conversation as resolved.
Show resolved Hide resolved
let follow_null_once t =
match t with
| TAbstract({a_path = [],"Null"},[t]) -> t
| _ -> t
in
let iftype = if is_dead_end e2 then
WithType.with_type (follow_null_once e1.etype)
else
WithType.WithType(e2.etype,None)
in
let e_if = make_if_then_else ctx e_cond e1 e2 iftype p in
vr#to_texpr e_if
| EBinop (OpAssignOp OpNullCoal,e1,e2) ->
Expand Down
17 changes: 13 additions & 4 deletions tests/unit/src/unit/issues/Issue10744.hx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ import unit.HelperMacros.typeString;
class Issue10744 extends Test {
function test() {
var v:Null<Int> = 10;
eq("Null<Int>", typeString(v ?? return));
eq("Null<Int>", typeString(v ?? throw true));
eq("Int", typeString(v ?? return));
eq("Int", typeString(v ?? throw true));
for (i in 0...1) {
eq("Null<Int>", typeString(v ?? break));
eq("Null<Int>", typeString(v ?? continue));
eq("Int", typeString(v ?? break));
eq("Int", typeString(v ?? continue));
}
eq("Int", typeString(v ?? {
(throw "nope");
}));
eq("Null<Int>", typeString(v ?? {
if (Std.random(0) == 0)
return;
else
v;
}));
}
}