浏览代码

do not recurse after inlining when finding abstract casts (fixed issue #1842)

Simon Krajewski 12 年之前
父节点
当前提交
6f1a78d0a2
共有 3 个文件被更改,包括 30 次插入8 次删除
  1. 3 8
      codegen.ml
  2. 22 0
      tests/unit/MyAbstract.hx
  3. 5 0
      tests/unit/TestBasetypes.hx

+ 3 - 8
codegen.ml

@@ -1340,7 +1340,6 @@ module Abstract = struct
 		let ethis = mk (TTypeExpr (TClassDecl c)) ta p in
 		let monos = List.map (fun _ -> mk_mono()) cf.cf_params in
 		let map t = apply_params a.a_types pl (apply_params cf.cf_params monos t) in
-		(* TODO: temp RC fix for from-functions to infer type parameters *)
 		let tcf = match follow (map cf.cf_type),args with
 			| TFun((_,_,ta) :: args,r) as tf,e :: el when Meta.has Meta.From cf.cf_meta ->
 				unify ctx e.etype ta p;
@@ -1349,20 +1348,16 @@ module Abstract = struct
 		in
 		let def () =
 			let e = mk (TField (ethis,(FStatic (c,cf)))) tcf p in
-			mk (TCall(e,args)) (map t) p
+			loop ctx (mk (TCall(e,args)) (map t) p)
 		in
-		let e = match cf.cf_expr with
+		match cf.cf_expr with
 		| Some { eexpr = TFunction fd } when cf.cf_kind = Method MethInline ->
 			let config = if Meta.has Meta.Impl cf.cf_meta then (Some (a.a_types <> [] || cf.cf_params <> [], map)) else None in
 			(match Optimizer.type_inline ctx cf fd ethis args t config p true with
 				| Some e -> (match e.eexpr with TCast(e,None) -> e | _ -> e)
-				| None ->
-					def())
+				| None -> def())
 		| _ ->
 			def()
-		in
-		(* TODO: can this cause loops? *)
-		loop ctx e
 
 	and check_cast ctx tleft eright p =
 		let tright = follow eright.etype in

+ 22 - 0
tests/unit/MyAbstract.hx

@@ -284,4 +284,26 @@ abstract MyAbstractThatCallsAMember(Int) to Int {
 	}
 
 	inline function bar() this++;
+}
+
+abstract MyDebugString(String) to String {
+	public inline function new(s:String) {
+		this = s;
+	}
+	
+	public inline function substr(i:Int, ?len:Null<Int>) {
+		return this.substr(i);
+	}
+}
+
+@:multiType abstract MySpecialString(String) {
+	public function new(value:String);	
+
+	public inline function substr(i:Int, ?len:Int) {
+		return len == null ? this.substr(i) : this.substr(i, len);
+	}
+	
+	@:to static inline public function toNormal(t:String, value:String) {
+		return new MyDebugString(value);
+	}	
 }

+ 5 - 0
tests/unit/TestBasetypes.hx

@@ -482,4 +482,9 @@ class TestBasetypes extends Test {
 		var as = new MyAbstract.MyAbstractThatCallsAMember(2);
 		eq(3, as);
 	}
+	
+	function testAbstractMultitypeInline() {
+		var a = new unit.MyAbstract.MySpecialString("My debugging abstract");
+		eq("debugging abstract", a.substr(3));
+	}
 }