Browse Source

allow duplicate fields when structurally extending if the types are equal (closes #3081)

Simon Krajewski 11 years ago
parent
commit
06fe066594
2 changed files with 50 additions and 5 deletions
  1. 34 0
      tests/unit/issues/Issue3081.hx
  2. 16 5
      typeload.ml

+ 34 - 0
tests/unit/issues/Issue3081.hx

@@ -0,0 +1,34 @@
+package unit.issues;
+
+private typedef T1<T> = {
+    function foo():T;
+}
+
+private typedef T2 = {
+    function foo():String;
+}
+
+private typedef T3 = {
+    > T1<String>,
+    > T2,
+    function bar():Int;
+	function foo():String;
+}
+
+private class C {
+	public function foo() {
+		return "foo";
+	}
+	public function bar() {
+		return 12;
+	}
+	public function new() { }
+}
+
+class Issue3081 extends Test {
+	function test() {
+		var c:T3 = new C();
+		eq("foo", c.foo());
+		eq(12, c.bar());
+	}
+}

+ 16 - 5
typeload.ml

@@ -429,6 +429,19 @@ and load_complex_type ctx p t =
 	| CTExtend (tl,l) ->
 		(match load_complex_type ctx p (CTAnonymous l) with
 		| TAnon a as ta ->
+			let is_redefined cf1 a2 =
+				try
+					let cf2 = PMap.find cf1.cf_name a2.a_fields in
+					let st = s_type (print_context()) in
+					if not (type_iseq cf1.cf_type cf2.cf_type) then begin
+						display_error ctx ("Cannot redefine field " ^ cf1.cf_name ^ " with different type") p;
+						display_error ctx ("First type was " ^ (st cf1.cf_type)) cf1.cf_pos;
+						error ("Second type was " ^ (st cf2.cf_type)) cf2.cf_pos
+					end else
+						true
+				with Not_found ->
+					false
+			in
 			let mk_extension t =
 				match follow t with
 				| TInst ({cl_kind = KTypeParameter _},_) ->
@@ -452,17 +465,15 @@ and load_complex_type ctx p t =
 				| TMono _ ->
 					error "Loop found in cascading signatures definitions. Please change order/import" p
 				| TAnon a2 ->
-					PMap.iter (fun f _ ->
-						if PMap.mem f a2.a_fields then error ("Cannot redefine field " ^ f) p;
-					) a.a_fields;
+					PMap.iter (fun _ cf -> ignore(is_redefined cf a2)) a.a_fields;
 					mk_anon (PMap.foldi PMap.add a.a_fields a2.a_fields)
 				| _ -> error "Can only extend classes and structures" p
 			in
 			let loop t = match follow t with
 				| TAnon a2 ->
 					PMap.iter (fun f cf ->
-						if PMap.mem f a.a_fields then error ("Cannot redefine field " ^ f) p;
-						a.a_fields <- PMap.add f cf a.a_fields
+						if not (is_redefined cf a) then
+							a.a_fields <- PMap.add f cf a.a_fields
 					) a2.a_fields
 				| _ ->
 					error "Multiple structural extension is only allowed for structures" p