소스 검색

Fix structInit inheritance (#9263)

RblSb 5 년 전
부모
커밋
d9a5517567

+ 6 - 1
src/typing/typeloadFields.ml

@@ -139,7 +139,10 @@ let get_struct_init_super_info ctx c p =
 			let args = (try get_method_args ctor with Not_found -> []) in
 			let tl,el =
 				List.fold_left (fun (args,exprs) (v,value) ->
-					let opt = match value with Some _ -> true | None -> false in
+					let opt = match value with
+						| Some _ -> true
+						| None -> Meta.has Meta.Optional v.v_meta
+					in
 					let t = if opt then ctx.t.tnull v.v_type else v.v_type in
 					(v.v_name,opt,t) :: args,(mk (TLocal v) v.v_type p) :: exprs
 				) ([],[]) args
@@ -181,6 +184,8 @@ let ensure_struct_init_constructor ctx c ast_fields p =
 				let v = alloc_var VGenerated cf.cf_name t p in
 				let ef = mk (TField(ethis,FInstance(c,params,cf))) cf.cf_type p in
 				let ev = mk (TLocal v) v.v_type p in
+				if opt && not (Meta.has Meta.Optional v.v_meta) then
+					v.v_meta <- (Meta.Optional,[],null_pos) :: v.v_meta;
 				(* this.field = <constructor_argument> *)
 				let assign_expr = mk (TBinop(OpAssign,ef,ev)) cf.cf_type p in
 				let e =

+ 54 - 0
tests/misc/projects/Issue7559/Main.hx

@@ -0,0 +1,54 @@
+class Main {
+	static function main() {
+		final base:NullChild = {};
+		final base:BaseEmpty = {};
+		final base:ChildEmpty = {};
+		final base:Base = {};
+		final child:Child = {base: 200, child: 100};
+		final child:Child = {child: 100};
+		final child:OptionalChild = {};
+		final child:OptionalEmptyChild = {};
+		final child:FatChild = {};
+		final child:FatEmptyChild = {};
+	}
+}
+@:structInit
+class BaseNullEmpty {
+	final base:Null<Int>;
+}
+@:structInit
+class NullChild extends BaseNullEmpty {
+	@:optional final child: Int;
+}
+@:structInit
+class BaseEmpty {
+	final base:Int;
+}
+@:structInit
+class Base {
+	final base = 0;
+}
+@:structInit
+class OptionalChild extends Base {
+	@:optional final child: Int;
+}
+@:structInit
+class OptionalEmptyChild extends BaseEmpty {
+	@:optional final child: Int;
+}
+@:structInit
+class Child extends Base {
+	final child: Int;
+}
+@:structInit
+class ChildEmpty extends BaseEmpty {
+	final child: Int;
+}
+@:structInit
+class FatChild extends Child {
+	final fatChild: Int;
+}
+@:structInit
+class FatEmptyChild extends ChildEmpty {
+	final fatChild: Int;
+}

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

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

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

@@ -0,0 +1,6 @@
+Main.hx:3: characters 26-28 : Object requires field base
+Main.hx:4: characters 26-28 : Object requires field base
+Main.hx:5: characters 27-29 : Object requires fields: child, base
+Main.hx:10: characters 36-38 : Object requires field base
+Main.hx:11: characters 26-28 : Object requires fields: fatChild, child
+Main.hx:12: characters 31-33 : Object requires fields: fatChild, child, base