From 1ff9f045065ed03251dd38b4fbe7b32014d8c6a9 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 16 Dec 2024 14:26:52 +0800 Subject: [PATCH] all: check error of generic symbol and cleanup generic symbol (fix #23072) (#23178) --- vlib/v/fmt/tests/import_selective_input.vv | 2 +- vlib/v/parser/parse_type.v | 3 + vlib/v/parser/parser.v | 18 +- vlib/v/parser/struct.v | 2 +- .../v/parser/tests/duplicated_generic_err.out | 2 +- vlib/v/parser/tests/duplicated_generic_err.vv | 2 +- vlib/v/parser/tests/generic_lowercase_err.out | 2 +- vlib/v/parser/tests/generic_lowercase_err.vv | 2 +- .../tests/generic_struct_type_decl_err.out | 2 +- .../tests/generic_struct_type_decl_err.vv | 8 +- vlib/v/parser/tests/generic_symbol_err.out | 5 + vlib/v/parser/tests/generic_symbol_err.vv | 5 + vlib/v/parser/tests/long_generic_err.out | 2 +- vlib/v/parser/tests/long_generic_err.vv | 2 +- vlib/v/parser/tests/too_many_generics_err.out | 2 +- vlib/v/parser/tests/too_many_generics_err.vv | 2 +- ..._many_layers_embedded_generic_type_err.out | 13 +- ...o_many_layers_embedded_generic_type_err.vv | 190 +++++++++--------- 18 files changed, 141 insertions(+), 123 deletions(-) create mode 100644 vlib/v/parser/tests/generic_symbol_err.out create mode 100644 vlib/v/parser/tests/generic_symbol_err.vv diff --git a/vlib/v/fmt/tests/import_selective_input.vv b/vlib/v/fmt/tests/import_selective_input.vv index 2264c116e..d0dd68005 100644 --- a/vlib/v/fmt/tests/import_selective_input.vv +++ b/vlib/v/fmt/tests/import_selective_input.vv @@ -76,7 +76,7 @@ fn f(v FnArg, vv ...FnArgVariadic) FnRet { return FnRet{} } -fn f2(v Generic) Generic {} +fn f2(v Generic[FnArgTypeParam1, FnArgTypeParam2]) Generic[FnRetTypeParam1, FnRetTypeParam2] {} fn f_generic[T](v FnArgGeneric[T]) FnRetGeneric[T] { return FnRetGeneric[T]{} diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 2f2352168..83b42b621 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -873,6 +873,9 @@ fn (mut p Parser) parse_generic_inst_type(name string) ast.Type { p.error('too many levels of Parser.parse_generic_inst_type() calls: ${p.generic_type_level}, probably due to too many layers embedded generic type') return ast.void_type } + if p.tok.kind == .lt { + p.error('The generic symbol `<>` is obsolete, please replace it with `[]`') + } mut bs_name := name mut bs_cname := name start_pos := p.tok.pos() diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 4b309b53d..4b2416bf5 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -3442,10 +3442,13 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr { fn (mut p Parser) parse_generic_types() ([]ast.Type, []string) { mut types := []ast.Type{} mut param_names := []string{} - if p.tok.kind !in [.lt, .lsbr] { + if p.tok.kind == .lt { + p.error('The generic symbol `<>` is obsolete, please replace it with `[]`') + } + if p.tok.kind != .lsbr { return types, param_names } - end_kind := if p.tok.kind == .lt { token.Kind.gt } else { token.Kind.rsbr } + end_kind := token.Kind.rsbr p.next() mut first_done := false mut count := 0 @@ -3492,15 +3495,18 @@ fn (mut p Parser) parse_generic_types() ([]ast.Type, []string) { fn (mut p Parser) parse_concrete_types() []ast.Type { mut types := []ast.Type{} - if p.tok.kind !in [.lt, .lsbr] { + if p.tok.kind == .lt { + p.error('The generic symbol `<>` is obsolete, please replace it with `[]`') + } + if p.tok.kind != .lsbr { return types } p.inside_fn_concrete_type = true defer { p.inside_fn_concrete_type = false } - end_kind := if p.tok.kind == .lt { token.Kind.gt } else { token.Kind.rsbr } - p.next() // `<` + end_kind := token.Kind.rsbr + p.next() // `[` mut first_done := false for p.tok.kind !in [.eof, end_kind] { if first_done { @@ -3509,7 +3515,7 @@ fn (mut p Parser) parse_concrete_types() []ast.Type { types << p.parse_type() first_done = true } - p.check(end_kind) // `>` + p.check(end_kind) // `]` return types } diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 0d107f31a..b2d8a4017 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -668,7 +668,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { is_mut = true mut_pos = fields.len } - if p.peek_tok.kind in [.lt, .lsbr] && p.peek_tok.is_next_to(p.tok) { + if p.peek_tok.kind == .lsbr && p.peek_tok.is_next_to(p.tok) { if generic_types.len == 0 { p.error_with_pos('non-generic interface `${interface_name}` cannot define a generic method', p.peek_tok.pos()) diff --git a/vlib/v/parser/tests/duplicated_generic_err.out b/vlib/v/parser/tests/duplicated_generic_err.out index e1514077c..17bd7f66b 100644 --- a/vlib/v/parser/tests/duplicated_generic_err.out +++ b/vlib/v/parser/tests/duplicated_generic_err.out @@ -1,3 +1,3 @@ vlib/v/parser/tests/duplicated_generic_err.vv:1:12: error: duplicated generic parameter `A` - 1 | fn test() {} + 1 | fn test[A, A]() {} | ^ diff --git a/vlib/v/parser/tests/duplicated_generic_err.vv b/vlib/v/parser/tests/duplicated_generic_err.vv index 4b8e345db..91e7692ee 100644 --- a/vlib/v/parser/tests/duplicated_generic_err.vv +++ b/vlib/v/parser/tests/duplicated_generic_err.vv @@ -1 +1 @@ -fn test() {} +fn test[A, A]() {} diff --git a/vlib/v/parser/tests/generic_lowercase_err.out b/vlib/v/parser/tests/generic_lowercase_err.out index 3a02413fe..4ab260e56 100644 --- a/vlib/v/parser/tests/generic_lowercase_err.out +++ b/vlib/v/parser/tests/generic_lowercase_err.out @@ -1,3 +1,3 @@ vlib/v/parser/tests/generic_lowercase_err.vv:1:22: error: generic parameter needs to be uppercase - 1 | fn lowercase_generic() {} + 1 | fn lowercase_generic[a]() {} | ^ diff --git a/vlib/v/parser/tests/generic_lowercase_err.vv b/vlib/v/parser/tests/generic_lowercase_err.vv index 4d9bcadbb..50c741cdd 100644 --- a/vlib/v/parser/tests/generic_lowercase_err.vv +++ b/vlib/v/parser/tests/generic_lowercase_err.vv @@ -1 +1 @@ -fn lowercase_generic() {} +fn lowercase_generic[a]() {} diff --git a/vlib/v/parser/tests/generic_struct_type_decl_err.out b/vlib/v/parser/tests/generic_struct_type_decl_err.out index dd9f09c4a..8c801ed9d 100644 --- a/vlib/v/parser/tests/generic_struct_type_decl_err.out +++ b/vlib/v/parser/tests/generic_struct_type_decl_err.out @@ -1,5 +1,5 @@ vlib/v/parser/tests/generic_struct_type_decl_err.vv:1:13: error: generic parameter name needs to be exactly one char - 1 | struct GMap, V> { + 1 | struct GMap[Hashable[K], V] { | ~~~~~~~~ 2 | map_ map[int]V 3 | } diff --git a/vlib/v/parser/tests/generic_struct_type_decl_err.vv b/vlib/v/parser/tests/generic_struct_type_decl_err.vv index 79f5f92f4..2e68eccb2 100644 --- a/vlib/v/parser/tests/generic_struct_type_decl_err.vv +++ b/vlib/v/parser/tests/generic_struct_type_decl_err.vv @@ -1,17 +1,17 @@ -struct GMap, V> { +struct GMap[Hashable[K], V] { map_ map[int]V } -fn (t GMap, V>) contains(k K) bool { +fn (t GMap[Hashable[K], V]) contains(k K) bool { return true // TODO } -fn (t GMap, V>) set(k K, v V) { +fn (t GMap[Hashable[K], V]) set(k K, v V) { // TODO } fn main() { - x := GMap{} + x := GMap[string, string]{} x.set("hello", "world") println(x.contains("hello")) } diff --git a/vlib/v/parser/tests/generic_symbol_err.out b/vlib/v/parser/tests/generic_symbol_err.out new file mode 100644 index 000000000..d3cfa2e30 --- /dev/null +++ b/vlib/v/parser/tests/generic_symbol_err.out @@ -0,0 +1,5 @@ +vlib/v/parser/tests/generic_symbol_err.vv:1:13: error: The generic symbol `<>` is obsolete, please replace it with `[]` + 1 | pub fn what1(params ...A) { + | ^ + 2 | println(params) + 3 | } diff --git a/vlib/v/parser/tests/generic_symbol_err.vv b/vlib/v/parser/tests/generic_symbol_err.vv new file mode 100644 index 000000000..dc84d0e2e --- /dev/null +++ b/vlib/v/parser/tests/generic_symbol_err.vv @@ -0,0 +1,5 @@ +pub fn what1(params ...A) { + println(params) +} + +fn main() {} diff --git a/vlib/v/parser/tests/long_generic_err.out b/vlib/v/parser/tests/long_generic_err.out index d27f9f02f..51040c8a2 100644 --- a/vlib/v/parser/tests/long_generic_err.out +++ b/vlib/v/parser/tests/long_generic_err.out @@ -1,3 +1,3 @@ vlib/v/parser/tests/long_generic_err.vv:1:17: error: generic parameter name needs to be exactly one char - 1 | fn long_generic() {} + 1 | fn long_generic[Abc]() {} | ~~~ diff --git a/vlib/v/parser/tests/long_generic_err.vv b/vlib/v/parser/tests/long_generic_err.vv index ae3e538d5..2355c4959 100644 --- a/vlib/v/parser/tests/long_generic_err.vv +++ b/vlib/v/parser/tests/long_generic_err.vv @@ -1 +1 @@ -fn long_generic() {} +fn long_generic[Abc]() {} diff --git a/vlib/v/parser/tests/too_many_generics_err.out b/vlib/v/parser/tests/too_many_generics_err.out index 82cb5fb1d..34e14774a 100644 --- a/vlib/v/parser/tests/too_many_generics_err.out +++ b/vlib/v/parser/tests/too_many_generics_err.out @@ -1,3 +1,3 @@ vlib/v/parser/tests/too_many_generics_err.vv:1:40: error: cannot have more than 9 generic parameters - 1 | fn too_many() {} + 1 | fn too_many[A, B, D, E, F, G, H, I, J, K]() {} | ^ diff --git a/vlib/v/parser/tests/too_many_generics_err.vv b/vlib/v/parser/tests/too_many_generics_err.vv index a42f2c13c..412ea70e8 100644 --- a/vlib/v/parser/tests/too_many_generics_err.vv +++ b/vlib/v/parser/tests/too_many_generics_err.vv @@ -1 +1 @@ -fn too_many() {} +fn too_many[A, B, D, E, F, G, H, I, J, K]() {} diff --git a/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.out b/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.out index 403b384d3..f7e62bf0b 100644 --- a/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.out +++ b/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.out @@ -1,7 +1,6 @@ -vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.vv:11:9: error: too many levels of Parser.parse_generic_inst_type() calls: 11, probably due to too many layers embedded generic type - 9 | o, Wprld< - 10 | o, Wprld< - 11 | o, Wprld< - | ^ - 12 | o, Wprld< - 13 | o, Wprld< +vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.vv:2:2: error: unexpected token `,`, expecting `]` + 1 | Hello, Wprld[ + 2 | o, Wprld[ + | ^ + 3 | o, Wprld[ + 4 | o, Wprld[ diff --git a/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.vv b/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.vv index d6b530b95..9fdd824c7 100644 --- a/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.vv +++ b/vlib/v/parser/tests/too_many_layers_embedded_generic_type_err.vv @@ -1,95 +1,95 @@ -Hello, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< -o, Wprld< +Hello, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ +o, Wprld[ -- 2.39.5