Skip to content

Commit b344639

Browse files
[hl] don't use unsafe cast for method with type param ret type (#12367)
1 parent cfc1ced commit b344639

File tree

2 files changed

+44
-19
lines changed

2 files changed

+44
-19
lines changed

src/generators/genhl.ml

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,25 +2327,9 @@ and eval_expr ctx e =
23272327
(match !def_ret with
23282328
| None ->
23292329
let rt = to_type ctx e.etype in
2330-
let is_valid_method t =
2331-
match follow t with
2332-
| TFun (_,rt) ->
2333-
(match follow rt with
2334-
| TInst({ cl_kind = KTypeParameter ttp },_) ->
2335-
(* don't allow if we have a constraint virtual, see hxbit.Serializer.getRef *)
2336-
not (List.exists (fun t -> match to_type ctx t with HVirtual _ -> true | _ -> false) (get_constraints ttp))
2337-
| _ -> false)
2338-
| _ ->
2339-
false
2340-
in
2341-
(match ec.eexpr with
2342-
| TField (_, FInstance(_,_,{ cf_kind = Method (MethNormal|MethInline); cf_type = t })) when is_valid_method t ->
2343-
(* let's trust the compiler when it comes to casting the return value from a type parameter *)
2344-
unsafe_cast_to ctx ret rt e.epos
2345-
| _ ->
2346-
cast_to ~force:true ctx ret rt e.epos)
2347-
| Some r ->
2348-
r)
2330+
cast_to ~force:true ctx ret rt e.epos
2331+
| Some r -> r
2332+
)
23492333
| TField (ec,FInstance({ cl_path = [],"Array" },[t],{ cf_name = "length" })) when to_type ctx t = HDyn ->
23502334
let r = alloc_tmp ctx HI32 in
23512335
op ctx (OCall1 (r,alloc_fun_path ctx (["hl";"types"],"ArrayDyn") "get_length", eval_null_check ctx ec));

tests/unit/src/unit/TestHL.hx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
package unit;
22

3+
class Box {
4+
var value:Dynamic;
5+
6+
public function new(value:Dynamic) {
7+
this.value = value;
8+
}
9+
10+
public function get<T>():T {
11+
return value;
12+
}
13+
}
14+
15+
interface IFoo {}
16+
17+
class Foo implements IFoo {
18+
public function new() {}
19+
}
20+
21+
class Bar {
22+
public var val:Int;
23+
}
24+
325
class TestHL extends Test {
26+
function testRetTypeTP() {
27+
var box = new Box(new Foo());
28+
try {
29+
var bar:Bar = box.get();
30+
trace(bar.val);
31+
assert("Expected cast failure");
32+
} catch(e: haxe.Exception) {
33+
eq(e.message, "Can't cast unit.Foo to unit.Bar");
34+
}
35+
}
36+
37+
function testRetTypeTPIFace() {
38+
var foo = new Foo();
39+
var ifoo: IFoo = foo;
40+
var box = new Box(ifoo);
41+
var bar:Foo = box.get();
42+
// important: eq must not be used as casting the values to dynamic papers over some issues
43+
t(foo == bar);
44+
}
445

546
//private function refTest(i:hl.types.Ref<Int>):Void
647
//{

0 commit comments

Comments
 (0)