parser: proper error when declaring struct embedding at the wrong pos (#7920)

pull/7925/head
Daniel Däschle 2021-01-06 15:46:36 +01:00 committed by GitHub
parent f9a873736e
commit 8a0fc2e3c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 17 deletions

View File

@ -158,7 +158,8 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
field_start_pos := p.tok.position()
is_embed := ((p.tok.lit.len > 1 && p.tok.lit[0].is_capital()) ||
p.peek_tok.kind == .dot) &&
language == .v && ast_fields.len == 0 && !(is_field_mut || is_field_mut || is_field_global)
language == .v
is_on_top := ast_fields.len == 0 && !(is_field_mut || is_field_mut || is_field_global)
mut field_name := ''
mut typ := table.Type(0)
mut type_pos := token.Position{}
@ -174,6 +175,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
}
}
type_pos = type_pos.extend(p.prev_tok.position())
if !is_on_top {
p.error_with_pos('struct embedding must be declared at the beginning of the struct body',
type_pos)
return ast.StructDecl{}
}
sym := p.table.get_type_symbol(typ)
if typ in embed_types {
p.error_with_pos('cannot embed `$sym.name` more than once', type_pos)

View File

@ -1,7 +0,0 @@
vlib/v/parser/tests/embed_pub_mut_err.vv:6:1: error: expecting type declaration
4 | pub mut:
5 | Context
6 | }
| ^
7 |
8 | fn main() {

View File

@ -1,9 +0,0 @@
struct Context {}
struct App {
pub mut:
Context
}
fn main() {
}

View File

@ -0,0 +1,7 @@
vlib/v/parser/tests/struct_embed_wrong_pos_long_err.vv:4:2: error: struct embedding must be declared at the beginning of the struct body
2 | struct Foo2 {
3 | mut:
4 | cli.Command
| ~~~~~~~~~~~
5 | }
6 | fn main() {}

View File

@ -0,0 +1,6 @@
import cli
struct Foo2 {
mut:
cli.Command
}
fn main() {}

View File

@ -0,0 +1,7 @@
vlib/v/parser/tests/struct_embed_wrong_pos_short_err.vv:6:2: error: struct embedding must be declared at the beginning of the struct body
4 | struct Foo2 {
5 | mut:
6 | Foo
| ~~~
7 | }
8 | fn main() {}

View File

@ -0,0 +1,8 @@
struct Foo {
foo string
}
struct Foo2 {
mut:
Foo
}
fn main() {}