Browse Source

Fix bad unification with static fields (#7527)

* check a_status in type_eq to fix static member unification issues (see #7526)

* [dce] revert adding MaybeUsed on statics which are no longer necessary (see #7526 and #4910)

* [test] add regression test for #7526

* type_eq TAnon comparison: check cf_public and cf_final

* remove cf_final check and report invalid_visibility for mismatching cf_public
George Corney 7 years ago
parent
commit
ae60db38d7

+ 8 - 1
src/core/type.ml

@@ -1862,12 +1862,19 @@ let rec type_eq param a b =
 		List.iter2 (type_eq param) tl1 tl2
 	| TAnon a1, TAnon a2 ->
 		(try
+			(match !(a2.a_status) with
+			| Statics c -> (match !(a1.a_status) with Statics c2 when c == c2 -> () | _ -> error [])
+			| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
+			| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
+			| _ -> ()
+			);
 			PMap.iter (fun n f1 ->
 				try
 					let f2 = PMap.find n a2.a_fields in
 					if f1.cf_kind <> f2.cf_kind && (param = EqStrict || param = EqCoreType || not (unify_kind f1.cf_kind f2.cf_kind)) then error [invalid_kind n f1.cf_kind f2.cf_kind];
 					let a = f1.cf_type and b = f2.cf_type in
-					(try type_eq param a b with Unify_error l -> error (invalid_field n :: l))
+					(try type_eq param a b with Unify_error l -> error (invalid_field n :: l));
+					if f1.cf_public != f2.cf_public then error [invalid_visibility n];
 				with
 					Not_found ->
 						if is_closed a2 then error [has_no_field b n];

+ 0 - 1
src/optimization/analyzerTexpr.ml

@@ -1119,7 +1119,6 @@ module Cleanup = struct
 			| TField({eexpr = TTypeExpr _},_) ->
 				e
 			| TTypeExpr (TClassDecl c) ->
-				List.iter (fun cf -> if not (Meta.has Meta.MaybeUsed cf.cf_meta) then cf.cf_meta <- (Meta.MaybeUsed,[],cf.cf_pos) :: cf.cf_meta;) c.cl_ordered_statics;
 				e
 			| TMeta((Meta.Ast,_,_),e1) when (match e1.eexpr with TSwitch _ -> false | _ -> true) ->
 				loop e1

+ 20 - 0
tests/misc/projects/Issue7526/Main.hx

@@ -0,0 +1,20 @@
+class C {
+
+    static private var member: Int = 42;
+
+}
+
+abstract A(Any) {
+
+	static private var member: Int = 42;
+
+}
+
+class Main {
+
+    static function main() {
+        (C: { member: Int }).member;
+        (A: { member: Int }).member;
+    }
+
+}

+ 2 - 0
tests/misc/projects/Issue7526/compile-fail.hxml

@@ -0,0 +1,2 @@
+-main Main
+--interp

+ 6 - 0
tests/misc/projects/Issue7526/compile-fail.hxml.stderr

@@ -0,0 +1,6 @@
+Main.hx:16: characters 9-29 : Class<C> should be { member : Int }
+Main.hx:16: characters 9-29 : { Statics C } should be { member : Int }
+Main.hx:16: characters 9-29 : The field member is not public
+Main.hx:17: characters 9-29 : Class<_Main.A_Impl_> should be { member : Int }
+Main.hx:17: characters 9-29 : { Statics _Main.A_Impl_ } should be { member : Int }
+Main.hx:17: characters 9-29 : The field member is not public