From 8ef3db5874a08165860bf8f2ec3ab2491d346fa5 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Mon, 10 Nov 2025 12:25:37 +0530 Subject: [PATCH] parser: disallow using generic functions as a field type name inside struct decl (fix #25452) (#25705) --- vlib/v/parser/parse_type.v | 13 ++++++++++--- .../tests/generic_imp_symbol_struct_field_err.out | 6 ++++++ .../tests/generic_imp_symbol_struct_field_err.vv | 5 +++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 vlib/v/parser/tests/generic_imp_symbol_struct_field_err.out create mode 100644 vlib/v/parser/tests/generic_imp_symbol_struct_field_err.vv diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 215df7219..d54f725dd 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -617,6 +617,7 @@ If you need to modify an array in a function, use a mutable argument instead: `f } fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_dot bool, is_option bool) ast.Type { + name_pos := p.tok.pos() mut name := p.tok.lit if language == .c { name = 'C.${name}' @@ -779,7 +780,7 @@ fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_dot b return p.parse_generic_type(name) } if p.tok.kind in [.lt, .lsbr] && p.tok.is_next_to(p.prev_tok) { - return p.parse_generic_inst_type(name) + return p.parse_generic_inst_type(name, name_pos) } return p.find_type_or_add_placeholder(name, language) } @@ -904,7 +905,7 @@ fn (mut p Parser) parse_generic_type(name string) ast.Type { return ast.new_type(idx).set_flag(.generic) } -fn (mut p Parser) parse_generic_inst_type(name string) ast.Type { +fn (mut p Parser) parse_generic_inst_type(name string, name_pos token.Pos) ast.Type { p.generic_type_level++ defer { p.generic_type_level-- @@ -999,7 +1000,13 @@ fn (mut p Parser) parse_generic_inst_type(name string) ast.Type { concrete_types_pos) } } - else {} + else { + // Disallow generic function as type inside struct decl + if parent_sym.kind == .placeholder && p.inside_struct_field_decl + && !parent_sym.name.all_after_last('.')[0].is_capital() { + p.error_with_pos('unknown type `${parent_sym.name}`', name_pos) + } + } } idx := p.table.register_sym(ast.TypeSymbol{ diff --git a/vlib/v/parser/tests/generic_imp_symbol_struct_field_err.out b/vlib/v/parser/tests/generic_imp_symbol_struct_field_err.out new file mode 100644 index 000000000..f956b9535 --- /dev/null +++ b/vlib/v/parser/tests/generic_imp_symbol_struct_field_err.out @@ -0,0 +1,6 @@ +vlib/v/parser/tests/generic_imp_symbol_struct_field_err.vv:4:8: error: unknown type `math.vec.vec3` + 2 | + 3 | struct Veca { + 4 | field vec3[f64] + | ~~~~ + 5 | } diff --git a/vlib/v/parser/tests/generic_imp_symbol_struct_field_err.vv b/vlib/v/parser/tests/generic_imp_symbol_struct_field_err.vv new file mode 100644 index 000000000..b8cd828f3 --- /dev/null +++ b/vlib/v/parser/tests/generic_imp_symbol_struct_field_err.vv @@ -0,0 +1,5 @@ +import math.vec { vec3 } + +struct Veca { + field vec3[f64] +} -- 2.39.5