1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: fix sumtype with multi fntype (fix #15557) (#15583)

This commit is contained in:
yuyi 2022-08-30 17:48:25 +08:00 committed by GitHub
parent 5d4492ac6f
commit b154af032b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 7 deletions

View File

@ -526,7 +526,7 @@ pub fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_d
return p.parse_array_type(p.tok.kind)
}
else {
if p.tok.kind == .lpar && !p.inside_sum_type {
if p.tok.kind == .lpar {
// multiple return
if is_ptr {
p.unexpected(prepend_msg: 'parse_type:', got: '`&` before multiple returns')

View File

@ -486,6 +486,33 @@ fn (p &Parser) peek_token_after_var_list() token.Token {
return tok
}
// peek token `type Fn = fn () int`
fn (p &Parser) is_fn_type_decl() bool {
mut n := 1
mut tok := p.tok
mut prev_tok := p.tok
cur_ln := p.tok.line_nr
for {
tok = p.scanner.peek_token(n)
if tok.kind in [.lpar, .rpar] {
n++
prev_tok = tok
continue
}
if tok.kind == .pipe {
if tok.pos - prev_tok.pos > prev_tok.len {
return false
}
}
if tok.line_nr > cur_ln {
break
}
prev_tok = tok
n++
}
return true
}
fn (p &Parser) is_array_type() bool {
mut i := 1
mut tok := p.tok
@ -3742,7 +3769,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
p.check(.assign)
mut type_pos := p.tok.pos()
mut comments := []ast.Comment{}
if p.tok.kind == .key_fn {
if p.tok.kind == .key_fn && p.is_fn_type_decl() {
// function type: `type mycallback = fn(string, int)`
fn_name := p.prepend_mod(name)
fn_type := p.parse_fn_type(fn_name)
@ -3762,7 +3789,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
}
}
sum_variants << p.parse_sum_type_variants()
// type SumType = A | B | c
// type SumType = Aaa | Bbb | Ccc
if sum_variants.len > 1 {
for variant in sum_variants {
variant_sym := p.table.sym(variant.typ)

View File

@ -1 +1,2 @@
Fns
Fn
Fn

View File

@ -1,8 +1,13 @@
type Fns = bool | fn (int) int
type Fn = fn () int | fn (int) int
fn main() {
f := Fns(fn (a int) int {
f1 := Fn(fn (a int) int {
return a
})
println(typeof(f).name)
println(typeof(f1).name)
f2 := Fn(fn () int {
return 22
})
println(typeof(f2).name)
}