Procházet zdrojové kódy

[inliner] allow cast assignments, but take the cast off when inserting

closes #7286

I hope this makes sense....
Simon Krajewski před 7 roky
rodič
revize
67d2ab2df5

+ 12 - 6
src/optimization/inline.ml

@@ -316,9 +316,10 @@ class inline_state ctx ethis params cf f p = object(self)
 			in
 			try loop e; true with Exit -> false
 		in
-		let is_writable e =
+		let rec is_writable e =
 			match e.eexpr with
 			| TField _ | TEnumParameter _ | TLocal _ | TArray _ -> true
+			| TCast(e1,None) -> is_writable e1
 			| _  -> false
 		in
 		let vars = List.fold_left (fun acc (i,e) ->
@@ -417,7 +418,7 @@ class inline_state ctx ethis params cf f p = object(self)
 			if self#might_be_affected e then l.i_force_temp <- true;
 		) _inlined_vars;
 		let vars,subst = self#get_substitutions p in
-		let rec inline_params in_call e =
+		let rec inline_params in_call in_assignment e =
 			match e.eexpr with
 			| TLocal v ->
 				begin try
@@ -427,6 +428,7 @@ class inline_state ctx ethis params cf f p = object(self)
 							begin match e'.eexpr with
 								(* If we inline a function expression, we have to duplicate its locals. *)
 								| TFunction _ -> Texpr.duplicate_tvars e'
+								| TCast(e1,None) when in_assignment -> e1
 								| _ -> e'
 							end
 						| VIInlineIfCalled when in_call ->
@@ -439,12 +441,16 @@ class inline_state ctx ethis params cf f p = object(self)
 					e
 				end
 			| TCall(e1,el) ->
-				let e1 = inline_params true e1 in
-				let el = List.map (inline_params false) el in
+				let e1 = inline_params true false e1 in
+				let el = List.map (inline_params false false) el in
 				{e with eexpr = TCall(e1,el)}
-			| _ -> Type.map_expr (inline_params false) e
+			| TBinop((OpAssign | OpAssignOp _ as op),e1,e2) ->
+				let e1 = inline_params false true e1 in
+				let e2 = inline_params false false e2 in
+				{e with eexpr = TBinop(op,e1,e2)}
+			| _ -> Type.map_expr (inline_params false false) e
 		in
-		let e = (if PMap.is_empty subst then e else inline_params false e) in
+		let e = (if PMap.is_empty subst then e else inline_params false false e) in
 		let init = match vars with [] -> None | l -> Some l in
 		let md = ctx.curclass.cl_module.m_extra.m_display in
 		md.m_inline_calls <- (cf.cf_name_pos,{p with pmax = p.pmin + String.length cf.cf_name}) :: md.m_inline_calls;

+ 17 - 0
tests/unit/src/unit/issues/Issue7286.hx

@@ -0,0 +1,17 @@
+package unit.issues;
+
+class Issue7286 extends unit.Test {
+	function test() {
+		new TestMap();
+	}
+}
+
+private abstract TestMap(Dynamic) {
+	public function new() {
+		fromObj();
+	}
+
+	inline function fromObj() {
+		this = { };
+	}
+}