From b85782b7e7893480e3b193fe67e7404667394290 Mon Sep 17 00:00:00 2001 From: Krchi <997054144@qq.com> Date: Tue, 19 Aug 2025 19:34:50 +0800 Subject: [PATCH] checker: add error for struct not init (fix #24893) (#25134) --- vlib/v/checker/checker.v | 27 ++++++++++++-- .../checker/tests/globals/assign_no_value.out | 6 ++-- .../checker/tests/globals/assign_no_value.vv | 2 +- vlib/v/checker/tests/match_undefined_cond.out | 35 +++++++++---------- vlib/v/checker/tests/match_undefined_cond.vv | 4 +-- vlib/v/checker/tests/struct_not_init_err.out | 21 +++++++++++ vlib/v/checker/tests/struct_not_init_err.vv | 15 ++++++++ 7 files changed, 82 insertions(+), 28 deletions(-) create mode 100644 vlib/v/checker/tests/struct_not_init_err.out create mode 100644 vlib/v/checker/tests/struct_not_init_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 695cdf955..f32d4163e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4377,8 +4377,10 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { } } } - c.error(util.new_suggestion(node.name, const_names_in_mod).say('undefined ident: `${node.name}`'), - node.pos) + c.check_known_struct_name(node) or { + c.error(util.new_suggestion(node.name, const_names_in_mod).say('undefined ident: `${node.name}`'), + node.pos) + } } else { // If a variable is not found in the scope of an anonymous function // but is in an external scope, then we can suggest the user add it to the capturing list. @@ -4398,13 +4400,32 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { } } - c.error('undefined ident: `${node.name}`', node.pos) + c.check_known_struct_name(node) or { + c.error('undefined ident: `${node.name}`', node.pos) + } } } } return ast.void_type } +fn (mut c Checker) check_known_struct_name(ident ast.Ident) ? { + mut is_struct := false + if ident.mod == 'builtin' || ident.mod == 'main' { + is_struct = c.table.find_type(ident.name) != 0 + if !is_struct { + is_struct = c.table.find_type('main.${ident.name}') != 0 + } + } else { + is_struct = c.table.find_type('${ident.mod}.${ident.name}') != 0 + } + if is_struct { + c.error('`${ident.name}` must be initialized', ident.pos) + return + } + return none +} + fn (mut c Checker) concat_expr(mut node ast.ConcatExpr) ast.Type { mut mr_types := []ast.Type{} for mut expr in node.vals { diff --git a/vlib/v/checker/tests/globals/assign_no_value.out b/vlib/v/checker/tests/globals/assign_no_value.out index 48694794d..a092b0109 100644 --- a/vlib/v/checker/tests/globals/assign_no_value.out +++ b/vlib/v/checker/tests/globals/assign_no_value.out @@ -1,5 +1,5 @@ -vlib/v/checker/tests/globals/assign_no_value.vv:2:9: error: undefined ident: `int` +vlib/v/checker/tests/globals/assign_no_value.vv:2:9: error: undefined ident: `int_i` 1 | __global ( - 2 | test = int - | ~~~ + 2 | test = int_i + | ~~~~~ 3 | ) diff --git a/vlib/v/checker/tests/globals/assign_no_value.vv b/vlib/v/checker/tests/globals/assign_no_value.vv index a2271cc7f..129645025 100644 --- a/vlib/v/checker/tests/globals/assign_no_value.vv +++ b/vlib/v/checker/tests/globals/assign_no_value.vv @@ -1,3 +1,3 @@ __global ( - test = int + test = int_i ) diff --git a/vlib/v/checker/tests/match_undefined_cond.out b/vlib/v/checker/tests/match_undefined_cond.out index ddfed08da..0ffe6fc8a 100644 --- a/vlib/v/checker/tests/match_undefined_cond.out +++ b/vlib/v/checker/tests/match_undefined_cond.out @@ -1,21 +1,20 @@ -vlib/v/checker/tests/match_undefined_cond.vv:4:15: error: undefined ident: `Asd` - 2 | - 3 | fn main() { - 4 | res := match Asd { +vlib/v/checker/tests/match_undefined_cond.vv:2:15: error: undefined ident: `asd` + 1 | fn main() { + 2 | res := match asd { | ~~~ - 5 | 1 { 'foo' } - 6 | 2 { 'test' } -vlib/v/checker/tests/match_undefined_cond.vv:5:3: error: cannot match `void` with `int literal` - 3 | fn main() { - 4 | res := match Asd { - 5 | 1 { 'foo' } + 3 | 1 { 'foo' } + 4 | 2 { 'test' } +vlib/v/checker/tests/match_undefined_cond.vv:3:3: error: cannot match `void` with `int literal` + 1 | fn main() { + 2 | res := match asd { + 3 | 1 { 'foo' } | ^ - 6 | 2 { 'test' } - 7 | else { '' } -vlib/v/checker/tests/match_undefined_cond.vv:6:3: error: cannot match `void` with `int literal` - 4 | res := match Asd { - 5 | 1 { 'foo' } - 6 | 2 { 'test' } + 4 | 2 { 'test' } + 5 | else { '' } +vlib/v/checker/tests/match_undefined_cond.vv:4:3: error: cannot match `void` with `int literal` + 2 | res := match asd { + 3 | 1 { 'foo' } + 4 | 2 { 'test' } | ^ - 7 | else { '' } - 8 | } + 5 | else { '' } + 6 | } diff --git a/vlib/v/checker/tests/match_undefined_cond.vv b/vlib/v/checker/tests/match_undefined_cond.vv index 952e4b768..16321e220 100644 --- a/vlib/v/checker/tests/match_undefined_cond.vv +++ b/vlib/v/checker/tests/match_undefined_cond.vv @@ -1,7 +1,5 @@ -type Asd = int - fn main() { - res := match Asd { + res := match asd { 1 { 'foo' } 2 { 'test' } else { '' } diff --git a/vlib/v/checker/tests/struct_not_init_err.out b/vlib/v/checker/tests/struct_not_init_err.out new file mode 100644 index 000000000..402616db0 --- /dev/null +++ b/vlib/v/checker/tests/struct_not_init_err.out @@ -0,0 +1,21 @@ +vlib/v/checker/tests/struct_not_init_err.vv:11:7: error: `Data` must be initialized + 9 | + 10 | fn main() { + 11 | _ := Data + | ~~~~ + 12 | _ := DataCollection + 13 | _ := ast.Type +vlib/v/checker/tests/struct_not_init_err.vv:12:7: error: `DataCollection` must be initialized + 10 | fn main() { + 11 | _ := Data + 12 | _ := DataCollection + | ~~~~~~~~~~~~~~ + 13 | _ := ast.Type + 14 | // _ := gui.Animate // for vpm mod +vlib/v/checker/tests/struct_not_init_err.vv:13:11: error: `v.ast.Type` must be initialized + 11 | _ := Data + 12 | _ := DataCollection + 13 | _ := ast.Type + | ~~~~ + 14 | // _ := gui.Animate // for vpm mod + 15 | } diff --git a/vlib/v/checker/tests/struct_not_init_err.vv b/vlib/v/checker/tests/struct_not_init_err.vv new file mode 100644 index 000000000..fcf698fef --- /dev/null +++ b/vlib/v/checker/tests/struct_not_init_err.vv @@ -0,0 +1,15 @@ +module main + +import v.ast + +struct Data { +} + +type DataCollection = Data + +fn main() { + _ := Data + _ := DataCollection + _ := ast.Type + // _ := gui.Animate // for vpm mod +} -- 2.39.5