parser: fix required function members in struct (#10299)
parent
89d2f508cc
commit
672bb6ca7f
|
@ -0,0 +1,7 @@
|
||||||
|
vlib/v/checker/tests/struct_required_fn_field.vv:12:6: error: field `Abc.f3` must be initialized
|
||||||
|
10 | f3: fn () {}
|
||||||
|
11 | }
|
||||||
|
12 | _ = Abc{
|
||||||
|
| ~~~~
|
||||||
|
13 | f1: 123
|
||||||
|
14 | f2: 789
|
|
@ -0,0 +1,16 @@
|
||||||
|
struct Abc {
|
||||||
|
f1 int [required]
|
||||||
|
f2 int
|
||||||
|
f3 fn () [attr1; required; attr2]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = Abc{
|
||||||
|
f1: 123
|
||||||
|
f3: fn () {}
|
||||||
|
}
|
||||||
|
_ = Abc{
|
||||||
|
f1: 123
|
||||||
|
f2: 789
|
||||||
|
}
|
||||||
|
}
|
|
@ -212,7 +212,7 @@ pub fn (mut p Parser) parse_fn_type(name string) ast.Type {
|
||||||
}
|
}
|
||||||
mut return_type := ast.void_type
|
mut return_type := ast.void_type
|
||||||
mut return_type_pos := token.Position{}
|
mut return_type_pos := token.Position{}
|
||||||
if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() {
|
if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() && !p.is_attributes() {
|
||||||
return_type_pos = p.tok.position()
|
return_type_pos = p.tok.position()
|
||||||
return_type = p.parse_type()
|
return_type = p.parse_type()
|
||||||
if return_type.has_flag(.generic) {
|
if return_type.has_flag(.generic) {
|
||||||
|
|
|
@ -1460,6 +1460,28 @@ fn (mut p Parser) expr_list() ([]ast.Expr, []ast.Comment) {
|
||||||
return exprs, comments
|
return exprs, comments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut p Parser) is_attributes() bool {
|
||||||
|
if p.tok.kind != .lsbr {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mut i := 0
|
||||||
|
for {
|
||||||
|
tok := p.peek_token(i)
|
||||||
|
if tok.kind == .eof || tok.line_nr != p.tok.line_nr {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if tok.kind == .rsbr {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
peek_rsbr_tok := p.peek_token(i + 1)
|
||||||
|
if peek_rsbr_tok.line_nr == p.tok.line_nr && peek_rsbr_tok.kind != .rcbr {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// when is_top_stmt is true attrs are added to p.attrs
|
// when is_top_stmt is true attrs are added to p.attrs
|
||||||
fn (mut p Parser) attributes() {
|
fn (mut p Parser) attributes() {
|
||||||
p.check(.lsbr)
|
p.check(.lsbr)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
struct Struct {
|
||||||
|
f1 fn () [required]
|
||||||
|
f2 fn () [attr1; required]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn func() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_struct_fields_storing_required_functions() {
|
||||||
|
s := Struct{
|
||||||
|
f1: func
|
||||||
|
f2: func
|
||||||
|
}
|
||||||
|
|
||||||
|
assert s.f1 == func
|
||||||
|
assert s.f2 == func
|
||||||
|
}
|
Loading…
Reference in New Issue