Parcourir la source

Final vs never vs null. Again. (#8096)

* Revert "Final vs. never vs. null (#8011)"

This reverts commit 309672728fdcd6503b0d93d6fff36c8518077a01.

* test for #8079, #8081, #8093

* fix test for #8079
Alexander Kuzmenko il y a 6 ans
Parent
commit
c5bb23663f

+ 2 - 11
src/core/type.ml

@@ -1905,7 +1905,6 @@ let rec type_eq param a b =
 				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];
-					if has_class_field_flag f1 CfFinal <> has_class_field_flag f2 CfFinal then raise (Unify_error [FinalInvariance]);
 					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));
 					if (has_class_field_flag f1 CfPublic) != (has_class_field_flag f2 CfPublic) then error [invalid_visibility n];
@@ -2246,7 +2245,7 @@ and unify_anons a b a1 a2 =
 			let f1 = PMap.find n a1.a_fields in
 			if not (unify_kind f1.cf_kind f2.cf_kind) then
 				(match !(a1.a_status), f1.cf_kind, f2.cf_kind with
-				| Opened, Var { v_read = AccNormal; v_write = AccNever }, Var { v_read = AccNormal; v_write = AccNormal } ->
+				| Opened, Var { v_read = AccNormal; v_write = AccNo }, Var { v_read = AccNormal; v_write = AccNormal } ->
 					f1.cf_kind <- f2.cf_kind;
 				| _ -> error [invalid_kind n f1.cf_kind f2.cf_kind]);
 			if (has_class_field_flag f2 CfPublic) && not (has_class_field_flag f1 CfPublic) then error [invalid_visibility n];
@@ -2398,15 +2397,7 @@ and unify_with_access f1 t1 f2 =
 	| Var { v_read = AccNo } | Var { v_read = AccNever } -> unify f2.cf_type t1
 	(* read only *)
 	| Method MethNormal | Method MethInline | Var { v_write = AccNo } | Var { v_write = AccNever } ->
-		begin match (has_class_field_flag f1 CfFinal),(has_class_field_flag f2 CfFinal) with
-		| true,true
-		| false,false ->
-			()
-		| true,false ->
-			()
-		| false,true ->
-			raise (Unify_error [FinalInvariance]);
-		end;
+		if (has_class_field_flag f1 CfFinal) <> (has_class_field_flag f2 CfFinal) then raise (Unify_error [FinalInvariance]);
 		unify t1 f2.cf_type
 	(* read/write *)
 	| _ -> with_variance (type_eq EqBothDynamic) t1 f2.cf_type

+ 1 - 1
src/optimization/optimizerTexpr.ml

@@ -31,7 +31,7 @@ let is_read_only_field_access e fa = match fa with
 		true
 	| FDynamic _ ->
 		false
-	| FAnon {cf_kind = Var {v_write = AccNo | AccNever}} when (match e.eexpr with TIdent _ -> true | _ -> false) -> true
+	| FAnon {cf_kind = Var {v_write = AccNo}} when (match e.eexpr with TIdent _ -> true | _ -> false) -> true
 	| FInstance (c,_,cf) | FStatic (c,cf) | FClosure (Some(c,_),cf) ->
 		begin match cf.cf_kind with
 			| Method MethDynamic -> false

+ 1 - 1
src/typing/fields.ml

@@ -461,7 +461,7 @@ let rec type_field ?(resume=false) ctx e i p mode =
 	| TMono r ->
 		let f = {
 			(mk_field i (mk_mono()) p null_pos) with
-			cf_kind = Var { v_read = AccNormal; v_write = (match mode with MSet -> AccNormal | MGet | MCall -> AccNever) };
+			cf_kind = Var { v_read = AccNormal; v_write = (match mode with MSet -> AccNormal | MGet | MCall -> AccNo) };
 		} in
 		let x = ref Opened in
 		let t = TAnon { a_fields = PMap.add i f PMap.empty; a_status = x } in

+ 4 - 4
tests/unit/src/unit/TestFieldVariance.hx

@@ -85,7 +85,7 @@ class TestFieldVariance extends Test {
 		// anon to final anon
 
 		t(typeError(finalField = publicField));
-		t(typeError(finalField = neverField));
+		finalField = neverField;
 		t(typeError(finalField = nullField));
 
 		// anon to never anon
@@ -97,7 +97,7 @@ class TestFieldVariance extends Test {
 		// anon to null anon
 
 		nullField = publicField;
-		nullField = finalField;
+		t(typeError(nullField = finalField));
 		nullField = neverField;
 
 		// class to final anon
@@ -110,14 +110,14 @@ class TestFieldVariance extends Test {
 		// class to never anon
 
 		neverField = publicFieldClass;
-		neverField = finalFieldClass;
+		t(typeError(neverField = finalFieldClass));
 		neverField = neverFieldClass;
 		neverField = nullFieldClass;
 
 		// class to null anon
 
 		nullField = publicFieldClass;
-		nullField = finalFieldClass;
+		t(typeError(nullField = finalFieldClass));
 		nullField = neverFieldClass;
 		nullField = nullFieldClass;
 	}

+ 11 - 0
tests/unit/src/unit/issues/Issue8079.hx

@@ -0,0 +1,11 @@
+package unit.issues;
+
+class Issue8079 extends unit.Test {
+	function test() {
+		var instance = ({}:Dynamic);
+		if(instance.timeout != null) {
+			instance.timeout = null;
+		}
+		utest.Assert.pass();
+	}
+}