فهرست منبع

[typer] fix top-down inference when typing local functions against abtracts

closes #10336
Simon Krajewski 3 سال پیش
والد
کامیت
e134a970ff
2فایلهای تغییر یافته به همراه41 افزوده شده و 3 حذف شده
  1. 8 3
      src/typing/typer.ml
  2. 33 0
      tests/unit/src/unit/issues/Issue10336.hx

+ 8 - 3
src/typing/typer.ml

@@ -1199,7 +1199,7 @@ and type_local_function ctx kind f with_type p =
 	let targs = args#for_type in
 	(match with_type with
 	| WithType.WithType(t,_) ->
-		let rec loop t =
+		let rec loop stack t =
 			(match follow t with
 			| TFun (args2,tr) when List.length args2 = List.length targs ->
 				List.iter2 (fun (_,_,t1) (_,_,t2) ->
@@ -1215,10 +1215,15 @@ and type_local_function ctx kind f with_type p =
 					| _ -> ()
 				end
 			| TAbstract(a,tl) ->
-				loop (Abstract.get_underlying_type a tl)
+				begin match get_abstract_froms a tl with
+				| [t2] ->
+					if not (List.exists (shallow_eq t) stack) then loop (t :: stack) t2
+				| _ ->
+					()
+			end
 			| _ -> ())
 		in
-		loop t
+		loop [] t
 	| WithType.NoValue ->
 		if name = None then display_error ctx "Unnamed lvalue functions are not supported" p
 	| _ ->

+ 33 - 0
tests/unit/src/unit/issues/Issue10336.hx

@@ -0,0 +1,33 @@
+package unit.issues;
+
+private abstract JurajFunc<T>(T->Unit) {
+	@:from
+	public static function fromFuncReturningSameType<T>(f:T->T):JurajFunc<T> {
+		throw 'irrelevant';
+	}
+}
+
+private abstract KevinFunc<T>(T->Unit) from T->Unit to T->Unit {
+	@:from
+	public static function fromFuncReturningSameType<T>(f:T->T):KevinFunc<T> {
+		throw 'irrelevant';
+	}
+}
+
+private class Unit {}
+
+class Issue10336 extends Test {
+	function testJuraj() {
+		var value = 'foo';
+		exc(() -> {
+			var f:JurajFunc<String> = function(v:String) return value = v;
+		});
+	}
+
+	function testKevin() {
+		var value = 'foo';
+		exc(() -> {
+			var f:KevinFunc<String> = function(v:String) return value = v;
+		});
+	}
+}