parser: fixed parsing prototype function with recursive type (#13922)

pull/13953/head
Vincenzo Palazzo 2022-04-05 17:39:49 +02:00 committed by GitHub
parent 0cba579a7b
commit 359f16fdfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 2 deletions

View File

@ -11,6 +11,8 @@ import v.util
[heap]
pub struct Table {
mut:
parsing_type string // name of the type to enable recursive type parsing
pub mut:
type_symbols []&TypeSymbol
type_idxs map[string]int
@ -830,7 +832,17 @@ pub fn (mut t Table) register_enum_decl(enum_decl EnumDecl) {
}
pub fn (t &Table) known_type(name string) bool {
return t.find_type_idx(name) != 0
return t.find_type_idx(name) != 0 || t.parsing_type == name
}
// start_parsing_type open the scope during the parsing of a type
// where the type name must include the module prefix
pub fn (mut t Table) start_parsing_type(type_name string) {
t.parsing_type = type_name
}
pub fn (mut t Table) reset_parsing_type() {
t.parsing_type = ''
}
pub fn (t &Table) known_type_idx(typ Type) bool {

View File

@ -738,13 +738,14 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
} else {
p.tok.lit
}
types_only := p.tok.kind in [.amp, .ellipsis, .key_fn, .lsbr]
|| (p.peek_tok.kind == .comma && p.table.known_type(argname))
|| p.peek_tok.kind == .dot || p.peek_tok.kind == .rpar
|| (p.tok.kind == .key_mut && (p.peek_token(2).kind == .comma
|| p.peek_token(2).kind == .rpar || (p.peek_tok.kind == .name
&& p.peek_token(2).kind == .dot)))
// TODO copy pasta, merge 2 branches
// TODO copy paste, merge 2 branches
if types_only {
mut arg_no := 1
for p.tok.kind != .rpar {
@ -800,6 +801,7 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
p.error_with_pos('expecting `)`', p.prev_tok.pos())
return []ast.Param{}, false, false
}
if p.tok.kind == .comma {
if is_variadic {
p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no',

View File

@ -51,6 +51,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
p.error_with_pos('cannot register struct `IError`, it is builtin interface type',
name_pos)
}
// append module name before any type of parsing to enable recursion parsing
p.table.start_parsing_type(p.prepend_mod(name))
defer {
p.table.reset_parsing_type()
}
generic_types, _ := p.parse_generic_types()
no_body := p.tok.kind != .lcbr
if language == .v && no_body {

View File

@ -0,0 +1,9 @@
module main
struct Ok {
alibaba fn (Ok, )
}
struct OkInt {
a fn (int, )
}