parser: add errors for invalid anonymous function (#7786)

pull/7877/head
Nick Treleaven 2021-01-05 00:32:24 +00:00 committed by GitHub
parent 9f74be4cf6
commit c0e56d10c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 3 deletions

View File

@ -443,12 +443,24 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
is_arg: true is_arg: true
}) })
} }
mut same_line := p.tok.line_nr == p.prev_tok.line_nr
mut return_type := table.void_type mut return_type := table.void_type
if p.tok.kind.is_start_of_type() { // lpar: multiple return types
return_type = p.parse_type() if same_line {
if p.tok.kind.is_start_of_type() {
return_type = p.parse_type()
} else if p.tok.kind != .lcbr {
p.error_with_pos('expected return type, not $p.tok for anonymous function',
p.tok.position())
}
} }
mut stmts := []ast.Stmt{} mut stmts := []ast.Stmt{}
no_body := p.tok.kind != .lcbr no_body := p.tok.kind != .lcbr
same_line = p.tok.line_nr == p.prev_tok.line_nr
if no_body && same_line {
p.error_with_pos('unexpected `$p.tok.kind` after anonymous function signature, expecting `{`',
p.tok.position())
}
if p.tok.kind == .lcbr { if p.tok.kind == .lcbr {
stmts = p.parse_block_no_scope(false) stmts = p.parse_block_no_scope(false)
} }

View File

@ -0,0 +1,6 @@
vlib/v/parser/tests/anon_fn_return_type.vv:7:22: error: expected return type, not string "hi" for anonymous function
5 | _ = fn (name string) flag.Flag
6 | _ = fn (name string) flag.Flag {return {}}
7 | _ = fn (name string) "hi" + name
| ~~~~
8 |

View File

@ -0,0 +1,8 @@
import flag
_ = fn (name string)
_ = fn (name string) {}
_ = fn (name string) flag.Flag
_ = fn (name string) flag.Flag {return {}}
_ = fn (name string) "hi" + name

View File

@ -437,7 +437,8 @@ pub fn (kind Kind) is_infix() bool {
pub fn (tok &Token) can_start_type(builtin_type_names []string) bool { pub fn (tok &Token) can_start_type(builtin_type_names []string) bool {
match tok.kind { match tok.kind {
.name { return tok.lit[0].is_capital() || tok.lit in builtin_type_names } .name { return tok.lit[0].is_capital() || tok.lit in builtin_type_names }
.amp, .lsbr, .question { return true } // Note: return type (T1, T2) should be handled elsewhere
.amp, .key_fn, .lsbr, .question { return true }
else {} else {}
} }
return false return false