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

check casts for property initializations (closes #3244)

Simon Krajewski 11 жил өмнө
parent
commit
025cc144ec

+ 20 - 0
tests/unit/issues/Issue3244.hx

@@ -0,0 +1,20 @@
+package unit.issues;
+
+private abstract A(String) from String {
+    @:from static function fromInt(v:Int):A return "abc";
+}
+
+private class TestClass {
+    static public var a:A = 1;
+	public var b:A = 1;
+
+	public function new() { }
+}
+
+class Issue3244 extends Test {
+	function test() {
+		// treat as Dynamic so we can be sure the cast isn't generated here
+		eq("abc", (TestClass.a : Dynamic));
+		eq("abc", (new TestClass().b : Dynamic));
+	}
+}

+ 15 - 7
typeload.ml

@@ -188,7 +188,7 @@ let make_module ctx mpath file tdecls loadp =
 				(match !decls with
 				(match !decls with
 				| (TClassDecl c,_) :: _ ->
 				| (TClassDecl c,_) :: _ ->
 					List.iter (fun m -> match m with
 					List.iter (fun m -> match m with
-						| ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum),_,_) ->
+						| ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce),_,_) ->
 							c.cl_meta <- m :: c.cl_meta;
 							c.cl_meta <- m :: c.cl_meta;
 						| _ ->
 						| _ ->
 							()
 							()
@@ -1715,14 +1715,21 @@ let init_class ctx c p context_init herits fields =
 		| Some e ->
 		| Some e ->
 			let check_cast e =
 			let check_cast e =
 				(* insert cast to keep explicit field type (issue #1901) *)
 				(* insert cast to keep explicit field type (issue #1901) *)
-				if not (type_iseq e.etype cf.cf_type)
-				then begin match e.eexpr,follow cf.cf_type with
+				let st = s_type (print_context()) in
+				if e.epos.pfile = "src/Main.hx" then Printf.printf "%s %s\n" (st e.etype) (st cf.cf_type);
+				if type_iseq e.etype cf.cf_type then
+					e
+				else begin match e.eexpr,follow cf.cf_type with
 					| TConst (TInt i),TAbstract({a_path=[],"Float"},_) ->
 					| TConst (TInt i),TAbstract({a_path=[],"Float"},_) ->
 						(* turn int constant to float constant if expected type is float *)
 						(* turn int constant to float constant if expected type is float *)
 						{e with eexpr = TConst (TFloat (Int32.to_string i))}
 						{e with eexpr = TConst (TFloat (Int32.to_string i))}
 					| _ ->
 					| _ ->
-						mk (TCast(e,None)) cf.cf_type e.epos
-				end else e
+						let e' = (!check_abstract_cast_ref) ctx cf.cf_type e e.epos in
+						if e' == e then
+							mk (TCast(e,None)) cf.cf_type e.epos
+						else
+							e'
+				end
 			in
 			in
 			let r = exc_protect ctx (fun r ->
 			let r = exc_protect ctx (fun r ->
 				(* type constant init fields (issue #1956) *)
 				(* type constant init fields (issue #1956) *)
@@ -1760,7 +1767,7 @@ let init_class ctx c p context_init herits fields =
 								has_this e;
 								has_this e;
 								e
 								e
 						in
 						in
-						check_cast e
+						e
 					| Var v when v.v_read = AccInline ->
 					| Var v when v.v_read = AccInline ->
 						let e = require_constant_expression e "Inline variable initialization must be a constant value" in
 						let e = require_constant_expression e "Inline variable initialization must be a constant value" in
 						begin match c.cl_kind with
 						begin match c.cl_kind with
@@ -1773,10 +1780,11 @@ let init_class ctx c p context_init herits fields =
 							| _ ->
 							| _ ->
 								()
 								()
 						end;
 						end;
-						check_cast e
+						e
 					| _ ->
 					| _ ->
 						e
 						e
 					) in
 					) in
+					let e = check_cast e in
 					cf.cf_expr <- Some e;
 					cf.cf_expr <- Some e;
 					cf.cf_type <- t;
 					cf.cf_type <- t;
 				end;
 				end;