diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 5c28506207..f56955de7f 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -381,15 +381,23 @@ pub fn (mut p Parser) parse_type() ast.Type { p.next() is_result = true } - if (is_optional || is_result) && (p.tok.line_nr > line_nr || p.tok.kind in [.comma, .rpar]) { - mut typ := ast.void_type - if is_optional { - typ = typ.set_flag(.optional) - } else if is_result { - typ = typ.set_flag(.result) + + if is_optional || is_result { + // maybe the '[' is the start of the field attribute + is_required_field := p.inside_struct_field_decl && p.tok.kind == .lsbr + && p.peek_tok.kind == .name && p.peek_tok.lit == 'required' + + if p.tok.line_nr > line_nr || p.tok.kind in [.comma, .rpar] || is_required_field { + mut typ := ast.void_type + if is_optional { + typ = typ.set_flag(.optional) + } else if is_result { + typ = typ.set_flag(.result) + } + return typ } - return typ } + is_shared := p.tok.kind == .key_shared is_atomic := p.tok.kind == .key_atomic if is_shared { diff --git a/vlib/v/parser/tests/struct_field_required_fn_optional_type.out b/vlib/v/parser/tests/struct_field_required_fn_optional_type.out new file mode 100644 index 0000000000..c84b64b25d --- /dev/null +++ b/vlib/v/parser/tests/struct_field_required_fn_optional_type.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/struct_field_required_fn_optional_type.vv:6:7: error: field `Foo.foo` must be initialized + 4 | + 5 | fn main() { + 6 | f := Foo{} + | ~~~~~ + 7 | println(f) + 8 | } diff --git a/vlib/v/parser/tests/struct_field_required_fn_optional_type.vv b/vlib/v/parser/tests/struct_field_required_fn_optional_type.vv new file mode 100644 index 0000000000..0432b754de --- /dev/null +++ b/vlib/v/parser/tests/struct_field_required_fn_optional_type.vv @@ -0,0 +1,8 @@ +struct Foo { + foo fn() ? [required] +} + +fn main() { + f := Foo{} + println(f) +} diff --git a/vlib/v/parser/tests/struct_field_required_fn_result_type.out b/vlib/v/parser/tests/struct_field_required_fn_result_type.out new file mode 100644 index 0000000000..0f2886eb03 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_required_fn_result_type.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/struct_field_required_fn_result_type.vv:6:7: error: field `Foo.foo` must be initialized + 4 | + 5 | fn main() { + 6 | f := Foo{} + | ~~~~~ + 7 | println(f) + 8 | } diff --git a/vlib/v/parser/tests/struct_field_required_fn_result_type.vv b/vlib/v/parser/tests/struct_field_required_fn_result_type.vv new file mode 100644 index 0000000000..3892fb63bf --- /dev/null +++ b/vlib/v/parser/tests/struct_field_required_fn_result_type.vv @@ -0,0 +1,8 @@ +struct Foo { + foo fn() ! [required] +} + +fn main() { + f := Foo{} + println(f) +}