From 721dbec2e4991a4b47d4e24e86996d7da8a39274 Mon Sep 17 00:00:00 2001 From: shove Date: Sun, 23 Oct 2022 01:02:11 +0800 Subject: [PATCH] checker: fix missed check on the initialization of result struct fields (fix #16152) (#16153) --- vlib/v/checker/struct.v | 8 ++++++-- .../tests/struct_field_optional_init_err.out | 14 ++++++++++++++ .../tests/struct_field_optional_init_err.vv | 11 +++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/struct_field_optional_init_err.out create mode 100644 vlib/v/checker/tests/struct_field_optional_init_err.vv diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index e16686e297..394d055f7c 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -87,7 +87,7 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) { if field.has_default_expr { c.expected_type = field.typ default_expr_type := c.expr(field.default_expr) - if !field.typ.has_flag(.optional) { + if !field.typ.has_flag(.optional) && !field.typ.has_flag(.result) { c.check_expr_opt_call(field.default_expr, default_expr_type) } struct_sym.info.fields[i].default_expr_typ = default_expr_type @@ -420,7 +420,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { if expr_type == ast.void_type { c.error('`$field.expr` (no value) used as value', field.pos) } - if !field_info.typ.has_flag(.optional) { + if !field_info.typ.has_flag(.optional) && !field.typ.has_flag(.result) { expr_type = c.check_expr_opt_call(field.expr, expr_type) } expr_type_sym := c.table.sym(expr_type) @@ -465,6 +465,10 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { c.error('field `$field_info.name` is optional, but initialization of optional fields currently unsupported', field.pos) } + if field_info.typ.has_flag(.result) { + c.error('field `$field_info.name` is result, but initialization of result fields currently unsupported', + field.pos) + } if expr_type.is_ptr() && expected_type.is_ptr() { if mut field.expr is ast.Ident { if mut field.expr.obj is ast.Var { diff --git a/vlib/v/checker/tests/struct_field_optional_init_err.out b/vlib/v/checker/tests/struct_field_optional_init_err.out new file mode 100644 index 0000000000..88a9c125d2 --- /dev/null +++ b/vlib/v/checker/tests/struct_field_optional_init_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/struct_field_optional_init_err.vv:8:3: error: field `bar` is result, but initialization of result fields currently unsupported + 6 | fn main() { + 7 | _ := Foo{ + 8 | bar: 1 + | ~~~~~~ + 9 | baz: 1 + 10 | } +vlib/v/checker/tests/struct_field_optional_init_err.vv:9:3: error: field `baz` is optional, but initialization of optional fields currently unsupported + 7 | _ := Foo{ + 8 | bar: 1 + 9 | baz: 1 + | ~~~~~~ + 10 | } + 11 | } diff --git a/vlib/v/checker/tests/struct_field_optional_init_err.vv b/vlib/v/checker/tests/struct_field_optional_init_err.vv new file mode 100644 index 0000000000..b04071e8e0 --- /dev/null +++ b/vlib/v/checker/tests/struct_field_optional_init_err.vv @@ -0,0 +1,11 @@ +struct Foo { + bar !int + baz ?int +} + +fn main() { + _ := Foo{ + bar: 1 + baz: 1 + } +}