Browse Source

[generics] Ensure type substitution happens for closures too. (#12173)

* [generics] Ensure type substitution happens for closures too.

* Add tests for issue 12171 and PR 11784.
Zeta 5 tháng trước cách đây
mục cha
commit
82eb6e53d6

+ 7 - 1
src/typing/generic.ml

@@ -121,7 +121,8 @@ let generic_substitute_expr gctx e =
 	in
 	let rec build_expr e =
 		let e = match e.eexpr with
-		| TField(e1, FInstance({cl_kind = KGeneric} as c,tl,cf)) ->
+		| TField(e1, (FInstance({cl_kind = KGeneric} as c,tl,cf) as fa_orig)) 
+		| TField(e1, (FClosure(Some ({cl_kind = KGeneric} as c, tl), cf) as fa_orig)) ->
 			let info = gctx.ctx.g.get_build_info gctx.ctx (TClassDecl c) gctx.p in
 			let t = info.build_apply (List.map (generic_substitute_type' gctx true) tl) in
 			begin match follow t with
@@ -134,6 +135,11 @@ let generic_substitute_expr gctx e =
 				with Not_found ->
 					raise_typing_error (Printf.sprintf "Type %s has no field %s (possible typing order issue)" (s_type (print_context()) t) cf.cf_name) e.epos
 				in
+				(* preserve FClosure *)
+				let fa = match fa_orig, fa with
+					| FClosure _, FInstance(c,tl,cf) -> FClosure(Some(c,tl),cf)
+					| _ -> fa
+				in
 				build_expr {e with eexpr = TField(e1,fa)}
 			end;
 		| TTypeExpr (TClassDecl ({cl_kind = KTypeParameter _;} as c)) when Meta.has Meta.Const c.cl_meta ->

+ 13 - 0
tests/misc/projects/Issue12171/Main.hx

@@ -0,0 +1,13 @@
+function passMethod<T>(f:T->Void) {}
+@:generic
+class Generic<T> {
+	var foo:T;
+	public function new()
+	{
+		passMethod(method);
+	}
+
+	function method(value:T) {}
+}
+
+typedef Instance = Generic<Int>;

+ 3 - 0
tests/misc/projects/Issue12171/compile.hxml

@@ -0,0 +1,3 @@
+Main
+--interp
+--hxb bin/main.hxb

+ 0 - 0
tests/misc/projects/Issue12171/compile.hxml.stderr


+ 12 - 0
tests/misc/projects/Pull11784/Main.hx

@@ -0,0 +1,12 @@
+function main() {
+	foo(0);
+}
+
+@:generic function foo<T>(val:T):T {
+	return bar(val);
+}
+
+macro function bar(expr) {
+	var typedExpr = haxe.macro.Context.typeExpr(expr);
+	return haxe.macro.Context.storeTypedExpr(typedExpr);
+}

+ 3 - 0
tests/misc/projects/Pull11784/compile.hxml

@@ -0,0 +1,3 @@
+-m Main
+--interp
+--hxb bin/main.hxb

+ 0 - 0
tests/misc/projects/Pull11784/compile.hxml.stderr