瀏覽代碼

re-build generic instance when checked as constraint (closes #1965)

Simon Krajewski 12 年之前
父節點
當前提交
2efa1520f2
共有 2 個文件被更改,包括 30 次插入3 次删除
  1. 24 2
      tests/unit/TestGeneric.hx
  2. 6 1
      typeload.ml

+ 24 - 2
tests/unit/TestGeneric.hx

@@ -20,8 +20,23 @@ class MyRandomClass {
 	}
 }
 
-class MyRandomEmptyClass {
-	
+class MyRandomEmptyClass { }
+
+@:generic class RBNode<T:RBNode<T>> {
+	public var rbLeft : T;
+	public var rbRight : T;
+}
+
+@:generic class RBTree<T:RBNode<T>> {
+	public var root : T;
+	public function new() {	}
+}
+
+class MyData extends RBNode<MyData> {
+	var id : Int;
+	public function new(id:Int) {
+		this.id = id;
+	}
 }
 
 class TestGeneric extends Test {
@@ -51,4 +66,11 @@ class TestGeneric extends Test {
 		var mg = new MyGeneric2<MyGeneric<MyRandomClass>>(new MyRandomClass("foo"));
 		eq("foo", mg.t.s);
 	}
+	
+	function testConstraints() {
+		var n = new RBTree<MyData>();
+		n.root = new MyData(1);
+		n.root.rbLeft = new MyData(2);
+		n.root.rbRight = new MyData(3);
+	}
 }

+ 6 - 1
typeload.ml

@@ -304,15 +304,20 @@ let rec load_type_def ctx p t =
 let check_param_constraints ctx types t pl c p =
 	match follow t with
 	| TMono _ -> ()
+	| TInst({cl_kind = KTypeParameter _},_) -> ()
 	| _ ->
 		let ctl = (match c.cl_kind with KTypeParameter l -> l | _ -> []) in
 		List.iter (fun ti ->
 			let ti = apply_params types pl ti in
 			let ti = (match follow ti with
-				| TInst ({ cl_kind = KGeneric }as c,pl) ->
+				| TInst ({ cl_kind = KGeneric } as c,pl) ->
 					(* if we solve a generic contraint, let's substitute with the actual generic instance before unifying *)
 					let _,_, f = ctx.g.do_build_instance ctx (TClassDecl c) p in
 					f pl
+				| TInst({cl_kind = KGenericInstance(c2,tl)},_) ->
+					(* build generic instance again with applied type parameters (issue 1965) *)
+					let _,_, f = ctx.g.do_build_instance ctx (TClassDecl c2) p in
+					f (List.map (fun t -> apply_params types pl t) tl)
 				| _ -> ti
 			) in
 			try