2
0
Эх сурвалжийг харах

require extended generic class to have a constructor

Simon Krajewski 12 жил өмнө
parent
commit
ca6ca3168e
2 өөрчлөгдсөн 18 нэмэгдсэн , 3 устгасан
  1. 6 1
      codegen.ml
  2. 12 2
      tests/unit/TestGeneric.hx

+ 6 - 1
codegen.ml

@@ -371,7 +371,12 @@ let rec build_generic ctx c p tl =
 					try
 						if pl <> [] then raise Not_found;
 						let t = loop subst in
-						(match c.cl_constructor with None -> () | Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos);
+						(* extended type parameter: concrete type must have a constructor, but generic base class must not have one *)
+ 						begin match follow t,c.cl_constructor with
+							| TInst({cl_constructor = None} as cs,_),None -> error ("Cannot use " ^ (s_type_path cs.cl_path) ^ " as type parameter because it is extended and has no constructor") p
+							| _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
+							| _ -> ()
+						end;
 						t
 					with Not_found ->
 						apply_params c.cl_types tl (TInst(cs,pl))

+ 12 - 2
tests/unit/TestGeneric.hx

@@ -20,6 +20,10 @@ class MyRandomClass {
 	}
 }
 
+class MyRandomEmptyClass {
+	
+}
+
 class TestGeneric extends Test {
 	function testBasic() {
 		var mg = new MyGeneric<Int>(12);
@@ -32,8 +36,14 @@ class TestGeneric extends Test {
 	}
 	
 	function testExtends() {
-		t(unit.TestType.typeError(new MyGeneric2<String>()));
-		t(unit.TestType.typeError(new MyGeneric2<Int>()));
+		// basic class
+		//t(unit.TestType.typeError(new MyGeneric2<String>()));
+		
+		// not a class
+		//t(unit.TestType.typeError(new MyGeneric2<Int>()));
+		
+		// no constructor
+		//t(unit.TestType.typeError(new MyGeneric2<MyRandomEmptyClass>()));
 		
 		var mg = new MyGeneric2<MyRandomClass>("foo");
 		eq("foo", mg.s);