Przeglądaj źródła

skip some AST nodes when checking for self-calling closures (closes #6283)

Simon Krajewski 8 lat temu
rodzic
commit
815260b044

+ 17 - 12
src/optimization/optimizer.ml

@@ -1106,18 +1106,23 @@ let reduce_control_flow ctx e = match e.eexpr with
 let rec reduce_loop ctx e =
 	let e = Type.map_expr (reduce_loop ctx) e in
 	sanitize_expr ctx.com (match e.eexpr with
-	| TCall ({ eexpr = TField ({ eexpr = TTypeExpr (TClassDecl c) },field) },params) ->
-		(match api_inline ctx c (field_name field) params e.epos with
-		| None -> reduce_expr ctx e
-		| Some e -> reduce_loop ctx e)
-	| TCall ({ eexpr = TFunction func } as ef,el) ->
-		let cf = mk_field "" ef.etype e.epos null_pos in
-		let ethis = mk (TConst TThis) t_dynamic e.epos in
-		let rt = (match follow ef.etype with TFun (_,rt) -> rt | _ -> assert false) in
-		let inl = (try type_inline ctx cf func ethis el rt None e.epos ~self_calling_closure:true false with Error (Custom _,_) -> None) in
-		(match inl with
-		| None -> reduce_expr ctx e
-		| Some e -> reduce_loop ctx e)
+	| TCall(e1,el) ->
+		begin match Texpr.skip e1 with
+			| { eexpr = TFunction func } as ef ->
+				let cf = mk_field "" ef.etype e.epos null_pos in
+				let ethis = mk (TConst TThis) t_dynamic e.epos in
+				let rt = (match follow ef.etype with TFun (_,rt) -> rt | _ -> assert false) in
+				let inl = (try type_inline ctx cf func ethis el rt None e.epos ~self_calling_closure:true false with Error (Custom _,_) -> None) in
+				(match inl with
+				| None -> reduce_expr ctx e
+				| Some e -> reduce_loop ctx e)
+			| { eexpr = TField ({ eexpr = TTypeExpr (TClassDecl c) },field) } ->
+				(match api_inline ctx c (field_name field) el e.epos with
+				| None -> reduce_expr ctx e
+				| Some e -> reduce_loop ctx e)
+			| _ ->
+				reduce_expr ctx e
+		end
 	| _ ->
 		reduce_expr ctx (reduce_control_flow ctx e))
 

+ 23 - 0
tests/optimization/src/issues/Issue6283.hx

@@ -0,0 +1,23 @@
+package issues;
+
+@:callable
+abstract From<T>(T) from T to T {
+	inline function new (t:T) return new From(t);
+	@:from macro public static function fromExpr (e:haxe.macro.Expr) {
+		return macro function (a, b) return a+b;
+	}
+}
+
+class Issue6283 {
+	@:js('console.log(3);')
+	@:analyzer(no_local_dce)
+	static function f(a, b) {
+		#if !macro
+		trace(foo({}));
+		#end
+	}
+
+	static inline function foo(f:From<Int->Int->Int>) {
+		return f(1,2);
+	}
+}