From 658b116d07a94b14e0739a808baa6f094a3e01c5 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 16 Mar 2023 16:42:00 -0300 Subject: [PATCH] checker: fix wrong struct warn about inited fields (#17678) --- vlib/v/checker/checker.v | 3 ++- vlib/v/checker/struct.v | 8 +++---- .../tests/struct_embed_required_field_err.out | 12 +++++------ .../tests/struct_embed_required_field_err.vv | 1 + .../checker/tests/struct_init_wrong_warn.out | 0 .../v/checker/tests/struct_init_wrong_warn.vv | 21 +++++++++++++++++++ 6 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 vlib/v/checker/tests/struct_init_wrong_warn.out create mode 100644 vlib/v/checker/tests/struct_init_wrong_warn.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 96d2365eb..aca01a563 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2687,7 +2687,8 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type { if node.unresolved { return c.expr(c.table.resolve_init(node, c.unwrap_generic(node.typ))) } - return c.struct_init(mut node, false) + mut inited_fields := []string{} + return c.struct_init(mut node, false, mut inited_fields) } ast.TypeNode { if !c.inside_x_is_type && node.typ.has_flag(.generic) && unsafe { c.table.cur_fn != 0 } diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 42e4957bc..ad0620fac 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -269,7 +269,7 @@ fn minify_sort_fn(a &ast.StructField, b &ast.StructField) int { } } -fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_init bool) ast.Type { +fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_init bool, mut inited_fields []string) ast.Type { util.timing_start(@METHOD) defer { util.timing_measure_cumulative(@METHOD) @@ -450,7 +450,6 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini info_fields_sorted = info.fields.clone() info_fields_sorted.sort(a.i < b.i) } - mut inited_fields := []string{} for i, mut field in node.fields { mut field_info := ast.StructField{} mut field_name := '' @@ -567,6 +566,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini // need to modify here accordingly. fields := c.table.struct_fields(type_sym) mut checked_types := []ast.Type{} + for i, field in fields { if field.name in inited_fields { continue @@ -653,7 +653,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini pos: node.pos typ: field.typ } - c.struct_init(mut zero_struct_init, true) + c.struct_init(mut zero_struct_init, true, mut inited_fields) } } for embed in info.embeds { @@ -661,7 +661,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini pos: node.pos typ: embed } - c.struct_init(mut zero_struct_init, true) + c.struct_init(mut zero_struct_init, true, mut inited_fields) } // println('>> checked_types.len: $checked_types.len | checked_types: $checked_types | type_sym: $type_sym.name ') } diff --git a/vlib/v/checker/tests/struct_embed_required_field_err.out b/vlib/v/checker/tests/struct_embed_required_field_err.out index 9b4561fff..94ce63bcf 100644 --- a/vlib/v/checker/tests/struct_embed_required_field_err.out +++ b/vlib/v/checker/tests/struct_embed_required_field_err.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/struct_embed_required_field_err.vv:11:7: error: field `Foo.foo` must be initialized - 9 | - 10 | fn main() { - 11 | b := Bar { +vlib/v/checker/tests/struct_embed_required_field_err.vv:12:7: error: field `Bar.bar` must be initialized + 10 | + 11 | fn main() { + 12 | b := Bar { | ~~~~~ - 12 | foo: 1 - 13 | } + 13 | foo: 1 + 14 | } diff --git a/vlib/v/checker/tests/struct_embed_required_field_err.vv b/vlib/v/checker/tests/struct_embed_required_field_err.vv index d3a5964b6..51693c5ab 100644 --- a/vlib/v/checker/tests/struct_embed_required_field_err.vv +++ b/vlib/v/checker/tests/struct_embed_required_field_err.vv @@ -1,5 +1,6 @@ struct Foo { foo u8 [required] + bar u8 [required] } struct Bar { diff --git a/vlib/v/checker/tests/struct_init_wrong_warn.out b/vlib/v/checker/tests/struct_init_wrong_warn.out new file mode 100644 index 000000000..e69de29bb diff --git a/vlib/v/checker/tests/struct_init_wrong_warn.vv b/vlib/v/checker/tests/struct_init_wrong_warn.vv new file mode 100644 index 000000000..39ab8fa64 --- /dev/null +++ b/vlib/v/checker/tests/struct_init_wrong_warn.vv @@ -0,0 +1,21 @@ +struct Inner { + ptr &u8 +} + +struct Outter { + Inner +mut: + size int +} + +fn new_outter() &Outter { + return &Outter{ + ptr: vcalloc(0) + size: 1 + } +} + +fn main () { + outter := new_outter() + println(outter) +} \ No newline at end of file -- 2.39.5