From 8466c6c03d77ae623ffc023272aacaa569c942ae Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Wed, 26 Jun 2024 04:05:55 +0530 Subject: [PATCH] parser: disallow self referencing function alias types like `type FnType = fn(string) FnType` and `type FnType = fn (FnType) string` (#21733) --- vlib/v/parser/parse_type.v | 9 +++++++++ vlib/v/parser/tests/fn_type_decl_same_return_type.out | 3 +++ vlib/v/parser/tests/fn_type_decl_same_return_type.vv | 1 + vlib/v/parser/tests/fn_type_del_same_param_type.out | 3 +++ vlib/v/parser/tests/fn_type_del_same_param_type.vv | 1 + 5 files changed, 17 insertions(+) create mode 100644 vlib/v/parser/tests/fn_type_decl_same_return_type.out create mode 100644 vlib/v/parser/tests/fn_type_decl_same_return_type.vv create mode 100644 vlib/v/parser/tests/fn_type_del_same_param_type.out create mode 100644 vlib/v/parser/tests/fn_type_del_same_param_type.vv diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index dfe432f08..1e324bb5c 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -315,6 +315,10 @@ fn (mut p Parser) parse_fn_type(name string, generic_types []ast.Type) ast.Type has_generic = true break } + if p.table.sym(param.typ).name == name { + p.error_with_pos('`${name}` cannot be a parameter as it references the fntype', + param.type_pos) + } } mut return_type := ast.void_type mut return_type_pos := token.Pos{} @@ -345,6 +349,11 @@ fn (mut p Parser) parse_fn_type(name string, generic_types []ast.Type) ast.Type p.error_with_pos('`${name}` type is generic fntype, must specify the generic type names, e.g. ${name}[T]', fn_type_pos) } + + if p.table.sym(return_type).name == name { + p.error_with_pos('`${name}` cannot be a return type as it references the fntype', + return_type_pos) + } // MapFooFn typedefs are manually added in cheaders.v // because typedefs get generated after the map struct is generated has_decl := p.builtin_mod && name.starts_with('Map') && name.ends_with('Fn') diff --git a/vlib/v/parser/tests/fn_type_decl_same_return_type.out b/vlib/v/parser/tests/fn_type_decl_same_return_type.out new file mode 100644 index 000000000..96bf1d6fe --- /dev/null +++ b/vlib/v/parser/tests/fn_type_decl_same_return_type.out @@ -0,0 +1,3 @@ +vlib/v/parser/tests/fn_type_decl_same_return_type.vv:1:27: error: `FnType` cannot be a return type as it references the fntype + 1 | type FnType = fn (string) FnType + | ~~~~~~ diff --git a/vlib/v/parser/tests/fn_type_decl_same_return_type.vv b/vlib/v/parser/tests/fn_type_decl_same_return_type.vv new file mode 100644 index 000000000..cc0966c81 --- /dev/null +++ b/vlib/v/parser/tests/fn_type_decl_same_return_type.vv @@ -0,0 +1 @@ +type FnType = fn (string) FnType diff --git a/vlib/v/parser/tests/fn_type_del_same_param_type.out b/vlib/v/parser/tests/fn_type_del_same_param_type.out new file mode 100644 index 000000000..f0e5c17aa --- /dev/null +++ b/vlib/v/parser/tests/fn_type_del_same_param_type.out @@ -0,0 +1,3 @@ +vlib/v/parser/tests/fn_type_del_same_param_type.vv:1:19: error: `FnType` cannot be a parameter as it references the fntype + 1 | type FnType = fn (FnType) string + | ~~~~~~ diff --git a/vlib/v/parser/tests/fn_type_del_same_param_type.vv b/vlib/v/parser/tests/fn_type_del_same_param_type.vv new file mode 100644 index 000000000..8244c0a73 --- /dev/null +++ b/vlib/v/parser/tests/fn_type_del_same_param_type.vv @@ -0,0 +1 @@ +type FnType = fn (FnType) string -- 2.39.5