Skip to content

Commit

Permalink
[typer] clean up with_type in operators.ml
Browse files Browse the repository at this point in the history
closes #11392
  • Loading branch information
Simn committed Nov 19, 2023
1 parent 5537809 commit 52bb475
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 16 deletions.
40 changes: 24 additions & 16 deletions src/typing/operators.ml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ let unify_int ctx e k =
unify ctx e.etype ctx.t.tint e.epos;
true

let make_binop ctx op e1 e2 is_assign_op with_type p =
let make_binop ctx op e1 e2 is_assign_op p =
let tint = ctx.t.tint in
let tfloat = ctx.t.tfloat in
let tstring = ctx.t.tstring in
Expand All @@ -204,7 +204,7 @@ let make_binop ctx op e1 e2 is_assign_op with_type p =
| KInt | KFloat | KString -> e
| KUnk | KDyn | KNumParam _ | KStrParam _ | KOther ->
let std = type_type ctx ([],"Std") e.epos in
let acc = acc_get ctx (type_field_default_cfg ctx std "string" e.epos (MCall []) with_type) in
let acc = acc_get ctx (type_field_default_cfg ctx std "string" e.epos (MCall []) WithType.value) in
ignore(follow acc.etype);
let acc = (match acc.eexpr with TField (e,FClosure (Some (c,tl),f)) -> { acc with eexpr = TField (e,FInstance (c,tl,f)) } | _ -> acc) in
make_call ctx acc [e] ctx.t.tstring e.epos
Expand Down Expand Up @@ -405,14 +405,14 @@ let make_binop ctx op e1 e2 is_assign_op with_type p =
| OpAssignOp _ ->
die "" __LOC__

let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op with_type p =
let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op p =
let map = apply_params a.a_params tl in
let make op_cf cf e1 e2 tret needs_assign swapped =
if cf.cf_expr = None && not (has_class_field_flag cf CfExtern) then begin
if not (Meta.has Meta.NoExpr cf.cf_meta) then Common.display_error ctx.com "Recursive operator method" p;
if not (Meta.has Meta.CoreType a.a_meta) then begin
(* for non core-types we require that the return type is compatible to the native result type *)
let result = make_binop ctx op {e1 with etype = Abstract.follow_with_abstracts e1.etype} {e1 with etype = Abstract.follow_with_abstracts e2.etype} is_assign_op with_type p in
let result = make_binop ctx op {e1 with etype = Abstract.follow_with_abstracts e1.etype} {e1 with etype = Abstract.follow_with_abstracts e2.etype} is_assign_op p in
let t_expected = BinopResult.get_type result in
begin try
unify_raise tret t_expected p
Expand Down Expand Up @@ -525,15 +525,15 @@ let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op with_type
else
find (loop op)

let try_abstract_binop_overloads ctx op e1 e2 is_assign_op with_type p =
let try_abstract_binop_overloads ctx op e1 e2 is_assign_op p =
try
begin match follow e1.etype with
| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl true is_assign_op with_type p
| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl true is_assign_op p
| _ -> raise Not_found
end
with Not_found ->
begin match follow e2.etype with
| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl false is_assign_op with_type p
| TAbstract({a_impl = Some c} as a,tl) -> find_abstract_binop_overload ctx op e1 e2 a c tl false is_assign_op p
| _ -> raise Not_found
end

Expand All @@ -542,17 +542,23 @@ let type_binop_rhs ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op wt p =
| OpEq | OpNotEq | OpLt | OpLte | OpGt | OpGte -> WithType.with_type e1.etype
| _ -> wt
in
type_expr ctx e2 with_type,with_type
type_expr ctx e2 with_type

let type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op with_type p =
let e2,with_type = type_binop_rhs ctx op e1 e2 is_assign_op with_type p in
let type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op with_type_rhs p =
let e2 = type_binop_rhs ctx op e1 e2 is_assign_op with_type_rhs p in
try
try_abstract_binop_overloads ctx op e1 e2 is_assign_op with_type p
try_abstract_binop_overloads ctx op e1 e2 is_assign_op p
with Not_found ->
make_binop ctx op e1 e2 is_assign_op with_type p
make_binop ctx op e1 e2 is_assign_op p

let with_type_or_value with_type = match with_type with
| WithType.NoValue ->
(* Even if we expect no value, we still want to type the lhs expression as a value. *)
WithType.value
| _ ->
with_type

let type_assign ctx e1 e2 with_type p =
let e1 = !type_access_ref ctx (fst e1) (snd e1) (MSet (Some e2)) with_type in
let type_rhs with_type = try
type_expr ctx e2 with_type
with Error e ->
Expand Down Expand Up @@ -604,6 +610,8 @@ let type_assign ctx e1 e2 with_type p =
let dispatcher = new call_dispatcher ctx (MCall [e2]) with_type p in
dispatcher#field_call fa_set [sea.se_this] [e2]
in
let with_type = with_type_or_value with_type in
let e1 = !type_access_ref ctx (fst e1) (snd e1) (MSet (Some e2)) with_type in
check_acc e1

let type_non_assign_op ctx op e1 e2 is_assign_op abstract_overload_only with_type p =
Expand All @@ -625,8 +633,8 @@ let type_non_assign_op ctx op e1 e2 is_assign_op abstract_overload_only with_typ
in
let e1 = type_expr ctx e1 wt in
let result = if abstract_overload_only then begin
let e2,with_type = type_binop_rhs ctx op e1 e2 is_assign_op with_type p in
try_abstract_binop_overloads ctx op e1 e2 is_assign_op with_type p
let e2 = type_binop_rhs ctx op e1 e2 is_assign_op with_type p in
try_abstract_binop_overloads ctx op e1 e2 is_assign_op p
end else
type_binop2 ctx op e1 e2 is_assign_op wt p
in
Expand Down Expand Up @@ -745,6 +753,7 @@ let type_assign_op ctx op e1 e2 with_type p =
let e = BinopResult.to_texpr vr r_rhs assign in
vr#to_texpr e
in
let with_type = with_type_or_value with_type in
loop (!type_access_ref ctx (fst e1) (snd e1) (MSet (Some e2)) with_type)


Expand All @@ -763,7 +772,6 @@ let type_binop ctx op e1 e2 is_assign_op with_type p =
let op = if is_assign_op then OpAssignOp op else op in
die ~p ("Failed to type binary operation " ^ (s_binop op)) __LOC__


let type_unop ctx op flag e with_type p =
let try_abstract_unop_overloads e = match follow e.etype with
| TAbstract ({a_impl = Some c} as a,tl) ->
Expand Down
5 changes: 5 additions & 0 deletions tests/misc/projects/Issue11392/Main.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function main() {
var a:Int;
var b:Int;
$type(a, _) = $type(b, _) = 0;
}
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue11392/compile.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--main Main
--interp
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue11392/compile.hxml.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Main.hx:4: characters 8-9 : Warning : Int (expected: Value)
Main.hx:4: characters 22-23 : Warning : Int (expected: WithType(Int, None))
1 change: 1 addition & 0 deletions tests/optimization/run.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
--macro Macro.register('TestJs')
--macro Macro.register('TestLocalDce')
--macro Macro.register('TestNadako')
--macro Macro.register('TestCompoundBlockElements')
--macro Macro.register('TestTreGeneration')
--macro Macro.register('TestInlineConstructors')
--macro Macro.register('issues')
Expand Down
70 changes: 70 additions & 0 deletions tests/optimization/src/TestCompoundBlockElements.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import TestJs.use;

class TestCompoundBlockElements {
@:js('
run(1);
run(1);
run(1);
')
static function testUnop() {
-run(1);
!run(1);
~run(1);
}

@:js('
run(1);
run(2);
run(3);
run(4);
run(5);
run(6);
run(7);
run(8);
run(9);
run(10);
')
static function testBinop() {
run(1) + run(2);
run(3) - run(4);
run(5) & run(6);
run(7) == run(8);
run(9) > run(10);
}

@:js('
run(1);
run(2);
')
static function testArrayAccess() {
run(1)[run(2)];
}

@:js('
run(1);
run(2);
run(3);
')
static function testArrayDeclaration() {
[run(1), run(2)];
run(3);
}

@:js('
run(1);
run(2);
run(3);
')
static function testObjectDeclaration() {
{
a: run(1),
b: run(2)
};
run(3);
}

@:pure(false)
static inline function run(i:Int):Dynamic {
return js.Syntax.code("run({0})", i);
}
}

0 comments on commit 52bb475

Please sign in to comment.