Pārlūkot izejas kodu

Fix for inline constructors bug #12149 (#12169)

* Fix #12149

* Add unit test
Mario Carbajal 3 mēneši atpakaļ
vecāks
revīzija
ad680dfea1

+ 20 - 17
src/optimization/inlineConstructors.ml

@@ -223,23 +223,26 @@ let inline_constructors ctx original_e =
 		The id is incremented each time and is used later in the final_map phase to identify the correct inline_object.
 	*)
 	let rec mark_ctors ?(force_inline=false) e : texpr =
-		let is_meta_inline = match e.eexpr with (TMeta((Meta.Inline,_,_),e)) -> true | _ -> false in
-		let e = Type.map_expr (mark_ctors ~force_inline:is_meta_inline) e in
-		let mark() =
-			incr curr_io_id;
-			let id_expr = (EConst(Int (string_of_int !curr_io_id, None)), e.epos) in
-			let meta = (Meta.InlineObject, [id_expr], e.epos) in
-			mk (TMeta(meta, e)) e.etype e.epos
-		in
-		match e.eexpr, force_inline with
-			| TObjectDecl _, _
-			| TArrayDecl _, _
-			| TNew _, true ->
-				mark()
-			| TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_), _ ->
-				if needs_inline ctx (Some c) cf then mark()
-				else e
-			| _ -> e
+		match e.eexpr with
+			| TMeta((Meta.InlineConstructorArgument _,_,_),_) -> e
+			| _ ->
+				let is_meta_inline = match e.eexpr with (TMeta((Meta.Inline,_,_),e)) -> true | _ -> false in
+				let e = Type.map_expr (mark_ctors ~force_inline:is_meta_inline) e in
+				let mark() =
+					incr curr_io_id;
+					let id_expr = (EConst(Int (string_of_int !curr_io_id, None)), e.epos) in
+					let meta = (Meta.InlineObject, [id_expr], e.epos) in
+					mk (TMeta(meta, e)) e.etype e.epos
+				in
+				match e.eexpr, force_inline with
+					| TObjectDecl _, _
+					| TArrayDecl _, _
+					| TNew _, true ->
+						mark()
+					| TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_), _ ->
+						if needs_inline ctx (Some c) cf then mark()
+						else e
+					| _ -> e
 	in
 
 	(*

+ 48 - 0
tests/unit/src/unit/issues/Issue12149.hx

@@ -0,0 +1,48 @@
+package unit.issues;
+
+final class Vec {
+	public var x:Float;
+
+	public inline function new(x:Float)
+		this.x = x;
+}
+
+final class Rect {
+	public var top_left:Vec;
+
+	public inline function new(top_left:Vec)
+		this.top_left = top_left;
+}
+
+enum Shape {
+	Vec(v:Vec);
+}
+
+interface BodyInt {
+	function shape():Shape;
+}
+
+
+class Body implements BodyInt {
+	public inline function shape():Shape {
+		throw new Rect(new Vec(1)).top_left;
+	}
+}
+
+class Issue12149 extends Test {
+	function test() {
+		noAssert();
+	}
+
+	static inline function update_entity<T:BodyInt>(body:T) {
+		switch body.shape() {
+			case Vec(v):
+				throw new Vec(new Vec(new Vec(v.x).x).x);
+			default:
+				throw "";
+		}
+	}
+	
+	static function set_pos(body:Body)
+		update_entity(body);
+}