Browse Source

[typer] inherit some metadata to generic implementation class

closes #10557, closes #10550
Simon Krajewski 3 years ago
parent
commit
d1a2bd1dc2
2 changed files with 47 additions and 2 deletions
  1. 15 2
      src/typing/generic.ml
  2. 32 0
      tests/unit/src/unit/issues/Issue10550.hx

+ 15 - 2
src/typing/generic.ml

@@ -213,6 +213,21 @@ let rec build_generic ctx c p tl =
 		} in
 		gctx.mg <- Some mg;
 		let cg = mk_class mg (pack,name) c.cl_pos c.cl_name_pos in
+		cg.cl_meta <- List.filter (fun (m,_,_) -> match m with
+			| Meta.Access | Allow
+			| Final
+			| Hack
+			| Internal
+			| Keep
+			| NoClosure | NullSafety
+			| Pure
+			| Struct | StructInit
+			| Using ->
+				true
+			| _ ->
+				false
+		) c.cl_meta;
+		cg.cl_meta <- (Meta.NoDoc,[],null_pos) :: cg.cl_meta;
 		mg.m_types <- [TClassDecl cg];
 		Hashtbl.add ctx.g.modules mg.m_path mg;
 		add_dependency mg m;
@@ -314,8 +329,6 @@ let rec build_generic ctx c p tl =
 		);
 		TypeloadFunction.add_constructor ctx cg false p;
 		cg.cl_kind <- KGenericInstance (c,tl);
-		cg.cl_meta <- (Meta.NoDoc,[],null_pos) :: cg.cl_meta;
-		if has_meta Meta.Keep c.cl_meta then cg.cl_meta <- (Meta.Keep,[],null_pos) :: cg.cl_meta;
 		if (has_class_flag c CInterface) then add_class_flag cg CInterface;
 		cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
 			| _, Some cf, _ -> Some (build_field cf)

+ 32 - 0
tests/unit/src/unit/issues/Issue10550.hx

@@ -0,0 +1,32 @@
+package unit.issues;
+
+@:structInit @:publicFields
+private class Tuple2<T, U> {
+	final _1:T;
+	final _2:U;
+
+	inline function new(_1:T, _2:U) {
+		this._1 = _1;
+		this._2 = _2;
+	}
+}
+
+@:generic
+@:structInit @:publicFields
+private class Tuple2Generic<T, U> {
+	final _1:T;
+	final _2:U;
+
+	inline function new(_1:T, _2:U) {
+		this._1 = _1;
+		this._2 = _2;
+	}
+}
+
+class Issue10550 extends Test {
+	function test() {
+		final foo:Tuple2<Int, String> = {_1: 1, _2: "abc"}; // works
+		final bar:Tuple2Generic<Int, String> = {_1: 1, _2: "abc"}; // doesn't work
+		utest.Assert.pass();
+	}
+}