瀏覽代碼

fix for fix_override not fixing interfaces

Simon Krajewski 13 年之前
父節點
當前提交
912f55370a
共有 3 個文件被更改,包括 26 次插入5 次删除
  1. 9 4
      codegen.ml
  2. 10 0
      tests/unit/MyClass.hx
  3. 7 1
      tests/unit/TestType.hx

+ 9 - 4
codegen.ml

@@ -1211,9 +1211,9 @@ let fix_override com c f fd =
 			(match f.cf_kind with Var { v_read = AccRequire _ } -> raise Not_found | _ -> ());
 			interf, f
 	in
-	let f2 = (try Some (find_field c true) with Not_found -> None) in
-	let f = (match f2 with
-		| Some (interf,f2) ->
+	let f2 = (try Some (find_field c c.cl_interface) with Not_found -> None) in
+	let f = (match f2,fd with
+		| Some (interf,f2), Some(fd) ->
 			let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> assert false) in
 			let changed_args = ref [] in
 			let prefix = "_tmp_" in
@@ -1243,6 +1243,9 @@ let fix_override com c f fd =
 			} in
 			let fde = (match f.cf_expr with None -> assert false | Some e -> e) in
 			{ f with cf_expr = Some { fde with eexpr = TFunction fd2 }; cf_type = TFun(targs,tret) }
+		| Some(true,f2), None ->
+			let targs, tret = (match follow f2.cf_type with TFun (args,ret) -> args, ret | _ -> assert false) in
+			{ f with cf_type = TFun(targs,tret) }
 		| _ -> f
 	) in
 	c.cl_fields <- PMap.add f.cf_name f c.cl_fields;
@@ -1254,7 +1257,9 @@ let fix_overrides com t =
 		c.cl_ordered_fields <- List.map (fun f ->
 			match f.cf_expr, f.cf_kind with
 			| Some { eexpr = TFunction fd }, Method (MethNormal | MethInline) ->
-				fix_override com c f fd
+				fix_override com c f (Some fd)
+			| None, Method (MethNormal | MethInline) when c.cl_interface ->
+				fix_override com c f None
 			| _ ->
 				f
 		) c.cl_ordered_fields

+ 10 - 0
tests/unit/MyClass.hx

@@ -66,6 +66,10 @@ interface CovI {
 	public function covariant():Base;
 }
 
+interface CovI2 implements CovI {
+	public function covariant():Child2;
+}
+
 class Cov1 {
 	public function new() { }
 	public function covariant():Base { return new Base(); }
@@ -76,6 +80,12 @@ class Cov2 extends Cov1, implements CovI {
 	public override function covariant():Child1 { return new Child1(); }
 }
 
+class Cov3 implements CovI2
+{
+	public function new() { }
+	public function covariant():Child2_1 { return new Child2_1(); }
+}
+
 class Ctrv1 {
 	public function new() { }
 	public function contravariant(arg:Child1) { }

+ 7 - 1
tests/unit/TestType.hx

@@ -290,6 +290,7 @@ class TestType extends Test {
 		#if !macro
 		var b:Base = null;
 		var c1:Child1 = null;
+		var c2_1:Child2_1 = null;
 		
 		var c = new Cov2();
 		typedAs(c.covariant(), c1);
@@ -308,7 +309,12 @@ class TestType extends Test {
 		
 		// dynamic
 		var dr:Dynamic = c;
-		t(Std.is(dr.covariant(), Child1));		
+		t(Std.is(dr.covariant(), Child1));
+		
+		// interface covariance
+		var c3 = new Cov3();
+		typedAs(c3.covariant(), c2_1);
+		t(Std.is(c3.covariant(), Child2_1));
 		#end
 	}