Skip to content

Commit b85782b

Browse files
authored
checker: add error for struct not init (fix #24893) (#25134)
1 parent c68e37e commit b85782b

7 files changed

Lines changed: 82 additions & 28 deletions

File tree

‎vlib/v/checker/checker.v‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4377,8 +4377,10 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
43774377
}
43784378
}
43794379
}
4380-
c.error(util.new_suggestion(node.name, const_names_in_mod).say('undefined ident: `${node.name}`'),
4381-
node.pos)
4380+
c.check_known_struct_name(node) or {
4381+
c.error(util.new_suggestion(node.name, const_names_in_mod).say('undefined ident: `${node.name}`'),
4382+
node.pos)
4383+
}
43824384
} else {
43834385
// If a variable is not found in the scope of an anonymous function
43844386
// 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 {
43984400
}
43994401
}
44004402

4401-
c.error('undefined ident: `${node.name}`', node.pos)
4403+
c.check_known_struct_name(node) or {
4404+
c.error('undefined ident: `${node.name}`', node.pos)
4405+
}
44024406
}
44034407
}
44044408
}
44054409
return ast.void_type
44064410
}
44074411

4412+
fn (mut c Checker) check_known_struct_name(ident ast.Ident) ? {
4413+
mut is_struct := false
4414+
if ident.mod == 'builtin' || ident.mod == 'main' {
4415+
is_struct = c.table.find_type(ident.name) != 0
4416+
if !is_struct {
4417+
is_struct = c.table.find_type('main.${ident.name}') != 0
4418+
}
4419+
} else {
4420+
is_struct = c.table.find_type('${ident.mod}.${ident.name}') != 0
4421+
}
4422+
if is_struct {
4423+
c.error('`${ident.name}` must be initialized', ident.pos)
4424+
return
4425+
}
4426+
return none
4427+
}
4428+
44084429
fn (mut c Checker) concat_expr(mut node ast.ConcatExpr) ast.Type {
44094430
mut mr_types := []ast.Type{}
44104431
for mut expr in node.vals {
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
vlib/v/checker/tests/globals/assign_no_value.vv:2:9: error: undefined ident: `int`
1+
vlib/v/checker/tests/globals/assign_no_value.vv:2:9: error: undefined ident: `int_i`
22
1 | __global (
3-
2 | test = int
4-
| ~~~
3+
2 | test = int_i
4+
| ~~~~~
55
3 | )
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__global (
2-
test = int
2+
test = int_i
33
)
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
vlib/v/checker/tests/match_undefined_cond.vv:4:15: error: undefined ident: `Asd`
2-
2 |
3-
3 | fn main() {
4-
4 | res := match Asd {
1+
vlib/v/checker/tests/match_undefined_cond.vv:2:15: error: undefined ident: `asd`
2+
1 | fn main() {
3+
2 | res := match asd {
54
| ~~~
6-
5 | 1 { 'foo' }
7-
6 | 2 { 'test' }
8-
vlib/v/checker/tests/match_undefined_cond.vv:5:3: error: cannot match `void` with `int literal`
9-
3 | fn main() {
10-
4 | res := match Asd {
11-
5 | 1 { 'foo' }
5+
3 | 1 { 'foo' }
6+
4 | 2 { 'test' }
7+
vlib/v/checker/tests/match_undefined_cond.vv:3:3: error: cannot match `void` with `int literal`
8+
1 | fn main() {
9+
2 | res := match asd {
10+
3 | 1 { 'foo' }
1211
| ^
13-
6 | 2 { 'test' }
14-
7 | else { '' }
15-
vlib/v/checker/tests/match_undefined_cond.vv:6:3: error: cannot match `void` with `int literal`
16-
4 | res := match Asd {
17-
5 | 1 { 'foo' }
18-
6 | 2 { 'test' }
12+
4 | 2 { 'test' }
13+
5 | else { '' }
14+
vlib/v/checker/tests/match_undefined_cond.vv:4:3: error: cannot match `void` with `int literal`
15+
2 | res := match asd {
16+
3 | 1 { 'foo' }
17+
4 | 2 { 'test' }
1918
| ^
20-
7 | else { '' }
21-
8 | }
19+
5 | else { '' }
20+
6 | }

‎vlib/v/checker/tests/match_undefined_cond.vv‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
type Asd = int
2-
31
fn main() {
4-
res := match Asd {
2+
res := match asd {
53
1 { 'foo' }
64
2 { 'test' }
75
else { '' }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
vlib/v/checker/tests/struct_not_init_err.vv:11:7: error: `Data` must be initialized
2+
9 |
3+
10 | fn main() {
4+
11 | _ := Data
5+
| ~~~~
6+
12 | _ := DataCollection
7+
13 | _ := ast.Type
8+
vlib/v/checker/tests/struct_not_init_err.vv:12:7: error: `DataCollection` must be initialized
9+
10 | fn main() {
10+
11 | _ := Data
11+
12 | _ := DataCollection
12+
| ~~~~~~~~~~~~~~
13+
13 | _ := ast.Type
14+
14 | // _ := gui.Animate // for vpm mod
15+
vlib/v/checker/tests/struct_not_init_err.vv:13:11: error: `v.ast.Type` must be initialized
16+
11 | _ := Data
17+
12 | _ := DataCollection
18+
13 | _ := ast.Type
19+
| ~~~~
20+
14 | // _ := gui.Animate // for vpm mod
21+
15 | }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module main
2+
3+
import v.ast
4+
5+
struct Data {
6+
}
7+
8+
type DataCollection = Data
9+
10+
fn main() {
11+
_ := Data
12+
_ := DataCollection
13+
_ := ast.Type
14+
// _ := gui.Animate // for vpm mod
15+
}

0 commit comments

Comments
 (0)