diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 695cdf9555..a473560cd8 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) + if !c.check_is_struct_name(node) { + 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) + if !c.check_is_struct_name(node) { + c.error('undefined ident: `${node.name}`', node.pos) + } } } } return ast.void_type } +fn (mut c Checker) check_is_struct_name(ident ast.Ident) bool { + 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 true + } + return false +} + 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 48694794dc..a092b01092 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 a2271cc7f1..1296450253 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 ddfed08da6..0ffe6fc8a8 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 952e4b768b..16321e220e 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 0000000000..402616db00 --- /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 0000000000..fcf698fef6 --- /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 +}