Browse Source

make sure extended generic type parameters are built before checking if they have a constructor (closes #3557)

Simon Krajewski 10 years ago
parent
commit
594e08b158
2 changed files with 32 additions and 1 deletions
  1. 6 1
      codegen.ml
  2. 26 0
      tests/unit/src/unit/issues/Issue3557.hx

+ 6 - 1
codegen.ml

@@ -407,7 +407,12 @@ let rec build_generic ctx c p tl =
 						let t = loop subst in
 						let t = loop subst in
 						(* extended type parameter: concrete type must have a constructor, but generic base class must not have one *)
 						(* 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
 						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
+							| TInst(cs,_),None ->
+								cs.cl_build();
+								begin match cs.cl_constructor with
+									| None -> error ("Cannot use " ^ (s_type_path cs.cl_path) ^ " as type parameter because it is extended and has no constructor") p
+									| _ -> ()
+								end;
 							| _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
 							| _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
 							| _ -> ()
 							| _ -> ()
 						end;
 						end;

+ 26 - 0
tests/unit/src/unit/issues/Issue3557.hx

@@ -0,0 +1,26 @@
+package unit.issues;
+
+private class MyBaseClass {
+	public function new():Void {}
+}
+
+private class MyClass extends Generic<MyBaseClass> {
+	public function new():Void {
+		super();
+	}
+}
+
+private interface Interface {}
+
+@:generic
+private class Generic<Default:{ public function new():Void; }>
+	extends Default
+	implements Interface {}
+
+class Issue3557 extends Test {
+	function test() {
+		new MyBaseClass();
+		new Generic<MyBaseClass>();
+		new MyClass();
+	}
+}