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

fixed typing of rest args against type parameters (closes #10124)

Aleksandr Kuzmenko 4 жил өмнө
parent
commit
6d5db24402

+ 1 - 0
extra/CHANGES.txt

@@ -11,6 +11,7 @@
 	all : fixed compiler compatibility with OS X 10.13 (#10110)
 	all : fixed compiler hanging on `switch` for abstracts with implicit casts involving type parameters and constraints (#10082)
 	all : fixed inlining of `haxe.DynamicAccess.keyValueIterator` (#10118)
+	all : fixed rest arguments typing against type parameters (#10124)
 	analyzer : fixed side effect handling for enums (#10032)
 	cpp : fixed handling of `cpp.ConstCharStar` with analyzer enabled (#9733)
 	php : fixed failure with trailing slash in output dir (#6212)

+ 18 - 6
src/typing/callUnification.ml

@@ -106,18 +106,30 @@ let rec unify_call_args ctx el args r callp inline force_inline in_overload =
 					in
 					(* these platforms deal with rest args on their own *)
 					if ctx.com.config.pf_supports_rest_args then
+						let type_rest t =
+							List.map (fun e ->
+								match e with
+								| (EUnop (Spread,Prefix,_),p) -> unexpected_spread p
+								| _ -> type_against name (t()) e
+							) el
+						in
 						match el with
 						| [(EUnop (Spread,Prefix,e),p)] ->
 							(try [mk (TUnop (Spread, Prefix, type_against name t e)) t p]
 							with WithTypeError(ul,p) -> arg_error ul name false p)
+						| _ when ExtType.is_mono (follow arg_t) ->
+							(try
+								let el = type_rest mk_mono in
+								try
+									Type.unify arg_t (unify_min ctx el);
+									el
+								with Unify_error _ ->
+									die ~p:callp "Unexpected unification error" __LOC__
+							with WithTypeError(ul,p) ->
+								arg_error ul name false p)
 						| _ ->
 							(try
-								List.map (fun e ->
-									match e with
-									| (EUnop (Spread,Prefix,_),p) ->
-										unexpected_spread p
-									| _ -> type_against name arg_t e
-								) el
+								type_rest (fun() -> arg_t)
 							with WithTypeError(ul,p) ->
 								arg_error ul name false p)
 					(* for other platforms make sure rest arguments are wrapped in an array *)

+ 9 - 0
tests/unit/src/unit/issues/Issue10124.hx

@@ -28,4 +28,13 @@ class Issue10124 extends Test {
 		arr.addFloat(5, 6, 7);
 		Assert.same([1, 3, 4, 5, 6, 7], arr);
 	}
+
+	function test3() {
+		function rest<T>(...values:T):Array<T> {
+			return values.toArray();
+		}
+		var a = rest(5, 6.2, 7);
+		aeq([5, 6.2, 7], a);
+		eq('Array<Float>', HelperMacros.typeString(a));
+	}
 }