From b556f1302fa8a3d7bea68f74d5aff05e5aba4a6e Mon Sep 17 00:00:00 2001 From: shove Date: Thu, 3 Aug 2023 14:25:03 +0800 Subject: [PATCH] parser: fix parse error in the type of a ref array when the element type is a structure of another mod(fix #19033) (#19039) --- vlib/v/parser/expr.v | 34 ++++++++++++------- ..._type_of_ref_array_from_another_mod_test.v | 17 ++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 vlib/v/tests/parse_type_of_ref_array_from_another_mod_test.v diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index e019a3cb3d0766..091dc304dba925 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -182,18 +182,28 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { if p.expecting_type { // parse json.decode type (`json.decode([]User, s)`) node = p.name_expr() - } else if p.is_amp && p.peek_tok.kind == .rsbr && p.peek_token(3).kind != .lcbr { - pos := p.tok.pos() - typ := p.parse_type() - typname := p.table.sym(typ).name - p.check(.lpar) - expr := p.expr(0) - p.check(.rpar) - node = ast.CastExpr{ - typ: typ - typname: typname - expr: expr - pos: pos + } else if p.is_amp && p.peek_tok.kind == .rsbr { + mut n := 2 + mut peek_n_tok := p.peek_token(n) + for peek_n_tok.kind in [.name, .dot] { + n++ + peek_n_tok = p.peek_token(n) + } + if peek_n_tok.kind != .lcbr { + pos := p.tok.pos() + typ := p.parse_type() + typname := p.table.sym(typ).name + p.check(.lpar) + expr := p.expr(0) + p.check(.rpar) + node = ast.CastExpr{ + typ: typ + typname: typname + expr: expr + pos: pos + } + } else { + node = p.array_init(false) } } else { node = p.array_init(false) diff --git a/vlib/v/tests/parse_type_of_ref_array_from_another_mod_test.v b/vlib/v/tests/parse_type_of_ref_array_from_another_mod_test.v new file mode 100644 index 00000000000000..d4e4213f2b9c9f --- /dev/null +++ b/vlib/v/tests/parse_type_of_ref_array_from_another_mod_test.v @@ -0,0 +1,17 @@ +import another_module + +struct SomeStruct {} + +fn type_from_another_mod() { + _ = &[]another_module.SomeStruct{} +} + +fn type_from_current_mod() { + _ = &[]SomeStruct{} +} + +fn test_parse_type_of_ref_array() { + type_from_another_mod() + type_from_current_mod() + assert true +}