From 2106be4578ee4899cdf7600ca8ede88823fbd979 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 12 Jun 2024 12:06:42 +0200 Subject: [PATCH] add missing recursion when checking abstract casts closes #11676 --- src/context/abstractCast.ml | 11 ++-- tests/misc/projects/Issue11676/Main.hx | 55 +++++++++++++++++++ tests/misc/projects/Issue11676/compile.hxml | 2 + .../projects/Issue11676/compile.hxml.stdout | 1 + 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 tests/misc/projects/Issue11676/Main.hx create mode 100644 tests/misc/projects/Issue11676/compile.hxml create mode 100644 tests/misc/projects/Issue11676/compile.hxml.stdout diff --git a/src/context/abstractCast.ml b/src/context/abstractCast.ml index 6e5f864629b..50d6ac45ba5 100644 --- a/src/context/abstractCast.ml +++ b/src/context/abstractCast.ml @@ -244,7 +244,7 @@ let find_multitype_specialization com a pl p = cf, follow m let handle_abstract_casts ctx e = - let rec loop ctx e = match e.eexpr with + let rec loop e = match e.eexpr with | TNew({cl_kind = KAbstractImpl a} as c,pl,el) -> if not (Meta.has Meta.MultiType a.a_meta) then begin (* This must have been a @:generic expansion with a { new } constraint (issue #4364). In this case @@ -296,10 +296,11 @@ let handle_abstract_casts ctx e = | TCast(e2,None) -> {e1 with eexpr = TCast(find_field e2,None)} | TField(e2,fa) -> + let e2 = loop e2 in let a,pl,e2 = find_abstract e2 e2.etype in let m = Abstract.get_underlying_type a pl in let fname = field_name fa in - let el = List.map (loop ctx) el in + let el = List.map loop el in begin try let fa = quick_field m fname in let get_fun_type t = match follow t with @@ -353,11 +354,11 @@ let handle_abstract_casts ctx e = in find_field e1 with Not_found -> - Type.map_expr (loop ctx) e + Type.map_expr loop e end | _ -> - Type.map_expr (loop ctx) e + Type.map_expr loop e in - loop ctx e + loop e ;; Typecore.cast_or_unify_raise_ref := cast_or_unify_raise diff --git a/tests/misc/projects/Issue11676/Main.hx b/tests/misc/projects/Issue11676/Main.hx new file mode 100644 index 00000000000..d4563220bb2 --- /dev/null +++ b/tests/misc/projects/Issue11676/Main.hx @@ -0,0 +1,55 @@ +class Main { + static function main() { + var comp = new AComponent([1, 2, 3]); + trace(comp.doSomething()); + } +} + +interface Component { + function doSomething():T; +} + +@:forward +@:multiType +abstract AComponent(Component) { + public function new(value:T); + + @:to public static inline function toInt(t:Component, value:Int):IntComponent { + return new IntComponent(value); + } + + @:to public static inline function toIntArray(t:Component>, value:Array):ArrayComponent { + return new ArrayComponent(value); + } +} + +@:generic +@:remove +class ArrayComponent implements Component> { + final value:Array; + + public function new(value:Array) { + this.value = value; + var x = []; + for (i in 0...value.length) { + var y = new AComponent(this.value[i]).doSomething(); + x.push(y); + } + } + + public function doSomething():Array { + return this.value; + } +} + +class IntComponent implements Component { + final value:Int; + + public function new(value:Int) { + this.value = value; + } + + public function doSomething():Int { + return value; + } +} diff --git a/tests/misc/projects/Issue11676/compile.hxml b/tests/misc/projects/Issue11676/compile.hxml new file mode 100644 index 00000000000..5f82c470c12 --- /dev/null +++ b/tests/misc/projects/Issue11676/compile.hxml @@ -0,0 +1,2 @@ +-m Main +--interp \ No newline at end of file diff --git a/tests/misc/projects/Issue11676/compile.hxml.stdout b/tests/misc/projects/Issue11676/compile.hxml.stdout new file mode 100644 index 00000000000..6f559e06558 --- /dev/null +++ b/tests/misc/projects/Issue11676/compile.hxml.stdout @@ -0,0 +1 @@ +Main.hx:4: [1,2,3] \ No newline at end of file