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

type return/break/continue expressions with monomorphs instead of Dynamic (see #10744) #10745

Merged
merged 5 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 17 additions & 10 deletions src/typing/typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ open Operators
(* ---------------------------------------------------------------------- *)
(* TOOLS *)

let mono_or_dynamic ctx with_type p = match with_type with
| WithType.NoValue ->
t_dynamic
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be Void maybe?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit worried about some crazy inline situation where we end up with Void in a value-place... With Dynamic we at least have the same behavior as before.

| Value _ | WithType _ ->
spawn_monomorph ctx p

let get_iterator_param t =
match follow t with
| TAnon a ->
Expand Down Expand Up @@ -1476,7 +1482,7 @@ and type_return ?(implicit=false) ctx e with_type p =
match e with
| None when is_abstract_ctor ->
let e_cast = mk (TCast(get_this ctx p,None)) ctx.ret p in
mk (TReturn (Some e_cast)) t_dynamic p
mk (TReturn (Some e_cast)) (mono_or_dynamic ctx with_type p) p
| None ->
let v = ctx.t.tvoid in
unify ctx v ctx.ret p;
Expand All @@ -1485,7 +1491,7 @@ and type_return ?(implicit=false) ctx e with_type p =
| WithType.Value (Some ImplicitReturn) -> true
| _ -> false
in
mk (TReturn None) (if expect_void then v else t_dynamic) p
mk (TReturn None) (if expect_void then v else (mono_or_dynamic ctx with_type p)) p
| Some e ->
if is_abstract_ctor then begin
match fst e with
Expand All @@ -1511,18 +1517,19 @@ and type_return ?(implicit=false) ctx e with_type p =
| _ -> ()
end;
(* if we get a Void expression (e.g. from inlining) we don't want to return it (issue #4323) *)
let t = mono_or_dynamic ctx with_type p in
mk (TBlock [
e;
mk (TReturn None) t_dynamic p
]) t_dynamic e.epos;
mk (TReturn None) t p
]) t e.epos;
| _ ->
mk (TReturn (Some e)) t_dynamic p
mk (TReturn (Some e)) (mono_or_dynamic ctx with_type p) p
with Error(err,p) ->
check_error ctx err p;
(* If we have a bad return, let's generate a return null expression at least. This surpresses various
follow-up errors that come from the fact that the function no longer has a return expression (issue #6445). *)
let e_null = mk (TConst TNull) (mk_mono()) p in
mk (TReturn (Some e_null)) t_dynamic p
mk (TReturn (Some e_null)) (mono_or_dynamic ctx with_type p) p

and type_cast ctx e t p =
let tpos = pos t in
Expand Down Expand Up @@ -1915,7 +1922,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
display_error ctx.com "Return outside function" p;
match e with
| None ->
Texpr.Builder.make_null t_dynamic p
Texpr.Builder.make_null (mono_or_dynamic ctx with_type p) p
| Some e ->
(* type the return expression to see if there are more errors
as well as use its type as if there was no `return`, since
Expand All @@ -1925,17 +1932,17 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
type_return ctx e with_type p
| EBreak ->
if not ctx.in_loop then display_error ctx.com "Break outside loop" p;
mk TBreak t_dynamic p
mk TBreak (mono_or_dynamic ctx with_type p) p
| EContinue ->
if not ctx.in_loop then display_error ctx.com "Continue outside loop" p;
mk TContinue t_dynamic p
mk TContinue (mono_or_dynamic ctx with_type p) p
| ETry (e1,[]) ->
type_expr ctx e1 with_type
| ETry (e1,catches) ->
type_try ctx e1 catches with_type p
| EThrow e ->
let e = type_expr ctx e WithType.value in
mk (TThrow e) (spawn_monomorph ctx p) p
mk (TThrow e) (mono_or_dynamic ctx with_type p) p
| ENew (t,el) ->
type_new ctx t el with_type false p
| EUnop (op,flag,e) ->
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/src/unit/issues/Issue10744.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package unit.issues;

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));
for (i in 0...1) {
eq("Null<Int>", typeString(v ?? break));
eq("Null<Int>", typeString(v ?? continue));
}
}
}