Prechádzať zdrojové kódy

disallow `@:callable` on `@:coreType` abstracts and fix call completion (see #3830)

Simon Krajewski 10 rokov pred
rodič
commit
d367e7b8db

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

@@ -0,0 +1,12 @@
+@:callable
+@:noFollow
+abstract FunctionPointer<T:haxe.Constraints.Function>(T) from T {}
+
+class Main {
+	static function main() {
+		var f:FunctionPointer<String->Void> = test;
+		f(|
+	}
+
+	static function test(s:String) { }
+}

+ 12 - 0
tests/misc/projects/Issue3830/MainFail.hx

@@ -0,0 +1,12 @@
+@:callable
+@:coreType
+abstract FunctionPointer<T:haxe.Constraints.Function> from T {}
+
+class Main {
+	static function main() {
+		var f:FunctionPointer<String->Void> = test;
+		f("foo");
+	}
+
+	static function test(s:String) { }
+}

+ 2 - 0
tests/misc/projects/Issue3830/compile-fail.hxml

@@ -0,0 +1,2 @@
+-main MainFail
+--no-output

+ 1 - 0
tests/misc/projects/Issue3830/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+MainFail.hx:3: characters 0-63 : @:coreType abstracts cannot be @:callable

+ 2 - 0
tests/misc/projects/Issue3830/compile.hxml

@@ -0,0 +1,2 @@
+-main Main
+--display Main.hx@0

+ 3 - 0
tests/misc/projects/Issue3830/compile.hxml.stderr

@@ -0,0 +1,3 @@
+<type>
+String -&gt; Void
+</type>

+ 5 - 1
typeload.ml

@@ -2737,7 +2737,11 @@ let rec init_module_type ctx context_init do_init (decl,p) =
 					TLazy r
 				end else
 					error "Missing underlying type declaration or @:coreType declaration" p;
-			end else t in
+			end else begin
+				if Meta.has Meta.Callable a.a_meta then
+					error "@:coreType abstracts cannot be @:callable" p;
+				t
+			end in
 			t
 		in
 		List.iter (function

+ 6 - 3
typer.ml

@@ -3716,9 +3716,12 @@ and handle_display ctx e_ast iscall p =
 		let fields = PMap.fold (fun f acc -> PMap.add f.cf_name f acc) fields use_methods in
 		let fields = PMap.fold (fun f acc -> if Meta.has Meta.NoCompletion f.cf_meta then acc else f :: acc) fields [] in
 		let t = if iscall then
-			match follow e.etype with
-			| TFun _ -> e.etype
-			| _ -> t_dynamic
+			let rec loop t = match follow t with
+				| TFun _ -> t
+				| TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta -> loop (Abstract.get_underlying_type a tl)
+				| _ -> t_dynamic
+			in
+			loop e.etype
 		else
 			let get_field acc f =
 				List.fold_left (fun acc f ->