Pārlūkot izejas kodu

fix `@:generic` method type parameter application and check constraints early (closes #3639)

Simon Krajewski 10 gadi atpakaļ
vecāks
revīzija
d8c78065f2
3 mainītis faili ar 53 papildinājumiem un 3 dzēšanām
  1. 1 1
      tests/unit/src/unit/TestType.hx
  2. 44 0
      tests/unit/src/unit/issues/Issue3639.hx
  3. 8 2
      typer.ml

+ 1 - 1
tests/unit/src/unit/TestType.hx

@@ -599,7 +599,7 @@ class TestType extends Test {
 		var t = new haxe.Template("foo");
 		var ta = gf3(t, [])[0];
 		f(t == ta);
-		hsf(TestType, "gf3_haxe_Template_Array__");
+		hsf(TestType, "gf3_haxe_Template_Array_haxe_Template");
 		#end
 
 		eq(overloadFake(1), 1);

+ 44 - 0
tests/unit/src/unit/issues/Issue3639.hx

@@ -0,0 +1,44 @@
+package unit.issues;
+
+private class MyClass<T> {
+	public function new() { }
+
+	@:generic
+	static public function testStatic<K>(k:K) { return k; }
+
+	@:generic
+	static public function eachStatic<T, I:Iterator<T>>(itr:I, f:T -> T) {
+		for (x in itr) {
+			f(x);
+		}
+	}
+
+	@:generic
+	public function testMember<K>(t:T, k:K) { }
+
+	@:generic
+	public function eachMember<I:Iterator<T>>(itr : I, f : T -> T) {
+		for (x in itr) {
+			f(x);
+		}
+	}
+}
+
+class Issue3639 extends Test {
+	function test() {
+		MyClass.testStatic(1);
+		MyClass.eachStatic(0...5, function(x) return x);
+
+		hsf(MyClass, "testStatic_Int");
+		hsf(MyClass, "eachStatic_Int_IntIterator");
+
+		var t = new MyClass();
+		t.testMember(1, "12");
+
+		var t = new MyClass();
+		t.eachMember(0...5, function(x) return x);
+
+		hf(MyClass, "testMember_String");
+		hf(MyClass, "eachMember_IntIterator");
+	}
+}

+ 8 - 2
typer.ml

@@ -1749,8 +1749,9 @@ let unify_int ctx e k =
 	in
 	if cf.cf_params = [] then error "Function has no type parameters and cannot be generic" p;
 	let monos = List.map (fun _ -> mk_mono()) cf.cf_params in
-	let t = apply_params cf.cf_params monos cf.cf_type in
-	add_constraint_checks ctx c.cl_params [] cf monos p;
+	let map t = apply_params cf.cf_params monos t in
+	let map t = if stat then map t else apply_params c.cl_params tl (map t) in
+	let t = map cf.cf_type in
 	let args,ret = match t,using_param with
 		| TFun((_,_,ta) :: args,ret),Some e ->
 			let ta = if not (Meta.has Meta.Impl cf.cf_meta) then ta
@@ -1768,6 +1769,11 @@ let unify_int ctx e k =
 		| _ -> ()
 	end;
 	let el,_ = unify_call_args ctx el args ret p false false in
+	begin try
+		check_constraints ctx cf.cf_name cf.cf_params monos map false p
+	with Unify_error l ->
+		display_error ctx (error_msg (Unify l)) p
+	end;
 	let el = match using_param with None -> el | Some e -> e :: el in
 	(try
 		let gctx = Codegen.make_generic ctx cf.cf_params monos p in