Browse Source

support ...rest argument declaration without type hint (see #10019) (#10021)

* support ...rest argument declaration without type hint (closes #10019)

* "fix" c#

* use more ugly type path for "syntatic monomorph" so nobody is going to rely on it

Co-authored-by: Aleksandr Kuzmenko <[email protected]>
Dan Korostelev 4 years ago
parent
commit
eec1951c4a
5 changed files with 13 additions and 2 deletions
  1. 3 0
      src/core/ast.ml
  2. 2 1
      src/syntax/grammar.mly
  3. 1 0
      src/typing/typeload.ml
  4. 1 1
      std/cs/_std/haxe/Rest.hx
  5. 6 0
      tests/unit/src/unit/TestRest.hx

+ 3 - 0
src/core/ast.ml

@@ -319,6 +319,9 @@ and evar = {
 	ev_meta : metadata;
 }
 
+(* TODO: should we introduce CTMono instead? *)
+let ct_mono = CTPath { tpackage = ["$"]; tname = "_hx_mono"; tparams = []; tsub = None }
+
 type enum_flag =
 	| EPrivate
 	| EExtern

+ 2 - 1
src/syntax/grammar.mly

@@ -998,7 +998,8 @@ and parse_fun_param s =
 	match s with parser
 	| [< '(Question,_); name, pn = dollar_ident; t = popt parse_type_hint; c = parse_fun_param_value >] -> ((name,pn),true,meta,t,c)
 	| [< name, pn = dollar_ident; t = popt parse_type_hint; c = parse_fun_param_value >] -> ((name,pn),false,meta,t,c)
-	| [< '(Spread,_); name, pn = dollar_ident; t = parse_type_hint; c = parse_fun_param_value >] ->
+	| [< '(Spread,_); name, pn = dollar_ident; t = popt parse_type_hint; c = parse_fun_param_value >] ->
+		let t = match t with Some t -> t | None -> (ct_mono,null_pos) in
 		let t = CTPath (mk_type_path ~params:[TPType t] (["haxe"],"Rest")), snd t in
 		((name,pn),false,meta,Some t,c)
 

+ 1 - 0
src/typing/typeload.ml

@@ -442,6 +442,7 @@ and load_instance ctx ?(allow_display=false) ((_,pn) as tp) allow_no_params =
 and load_complex_type' ctx allow_display (t,p) =
 	match t with
 	| CTParent t -> load_complex_type ctx allow_display t
+	| CTPath { tpackage = ["$"]; tname = "_hx_mono" } -> spawn_monomorph ctx p
 	| CTPath t -> load_instance ~allow_display ctx (t,p) false
 	| CTOptional _ -> error "Optional type not allowed here" p
 	| CTNamed _ -> error "Named type not allowed here" p

+ 1 - 1
std/cs/_std/haxe/Rest.hx

@@ -20,7 +20,7 @@ abstract Rest<T>(NativeRest<T>) {
 		this = a;
 
 	@:arrayAccess inline function get(index:Int):T
-		return this[index];
+		return (this[index] : T); // typecheck, otherwise it will be inlined as Dynamic with `-D erase-generics`
 
 	@:to public function toArray():Array<T> {
 		var result = new NativeRest(this.Length);

+ 6 - 0
tests/unit/src/unit/TestRest.hx

@@ -132,6 +132,12 @@ class TestRest extends Test {
 		aeq([{f:2}, {f:1}], rest({f:2}, {f:1}));
 	}
 
+	function testInferred() {
+		function rest(...r) {
+			(r[0] : Int);
+		}
+		HelperMacros.typedAs(rest, (null : (r : Rest<Int>)->Void));
+
 	function testToString() {
 		function rest(...r:Int) {
 			return r.toString();