mirror of
https://github.com/vlang/v.git
synced 2025-09-16 07:52:32 +03:00
checker: avoid nil assign to option var (#19746)
This commit is contained in:
parent
09f3e1e971
commit
e736ecaadd
5 changed files with 59 additions and 3 deletions
|
@ -386,6 +386,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
c.error('duplicate of an import symbol `${left.name}`', left.pos)
|
c.error('duplicate of an import symbol `${left.name}`', left.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if node.op == .assign && left_type.has_flag(.option) && right is ast.UnsafeExpr
|
||||||
|
&& right.expr.is_nil() {
|
||||||
|
c.error('cannot assign `nil` to option value', right.pos())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.PrefixExpr {
|
ast.PrefixExpr {
|
||||||
|
@ -424,6 +428,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if left_type.has_flag(.option) && right is ast.UnsafeExpr && right.expr.is_nil() {
|
||||||
|
c.error('cannot assign `nil` to option value', right.pos())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if mut left is ast.IndexExpr {
|
if mut left is ast.IndexExpr {
|
||||||
|
|
|
@ -205,6 +205,9 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
||||||
c.warn('unnecessary default value of `none`: struct fields are zeroed by default',
|
c.warn('unnecessary default value of `none`: struct fields are zeroed by default',
|
||||||
field.default_expr.pos)
|
field.default_expr.pos)
|
||||||
}
|
}
|
||||||
|
if field.typ.has_flag(.option) && field.default_expr.is_nil() {
|
||||||
|
c.error('cannot assign `nil` to option value', field.default_expr.pos())
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field.typ in ast.unsigned_integer_type_idxs {
|
if field.typ in ast.unsigned_integer_type_idxs {
|
||||||
|
|
34
vlib/v/checker/tests/nil_to_option_err.out
Normal file
34
vlib/v/checker/tests/nil_to_option_err.out
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
vlib/v/checker/tests/nil_to_option_err.vv:8:7: warning: cannot assign a reference to a value (this will be an error soon) left=int false right=nil true ptr=false
|
||||||
|
6 | fn main() {
|
||||||
|
7 | mut a := ?int(none)
|
||||||
|
8 | a = unsafe { nil }
|
||||||
|
| ^
|
||||||
|
9 |
|
||||||
|
10 | mut b := Test{}
|
||||||
|
vlib/v/checker/tests/nil_to_option_err.vv:7:9: warning: unused variable: `a`
|
||||||
|
5 |
|
||||||
|
6 | fn main() {
|
||||||
|
7 | mut a := ?int(none)
|
||||||
|
| ^
|
||||||
|
8 | a = unsafe { nil }
|
||||||
|
9 |
|
||||||
|
vlib/v/checker/tests/nil_to_option_err.vv:3:7: error: cannot assign `nil` to a non-pointer field
|
||||||
|
1 | struct Test {
|
||||||
|
2 | mut:
|
||||||
|
3 | a ?int = unsafe { nil }
|
||||||
|
| ~~~~
|
||||||
|
4 | }
|
||||||
|
5 |
|
||||||
|
vlib/v/checker/tests/nil_to_option_err.vv:8:9: error: cannot assign `nil` to option value
|
||||||
|
6 | fn main() {
|
||||||
|
7 | mut a := ?int(none)
|
||||||
|
8 | a = unsafe { nil }
|
||||||
|
| ~~~~~~
|
||||||
|
9 |
|
||||||
|
10 | mut b := Test{}
|
||||||
|
vlib/v/checker/tests/nil_to_option_err.vv:11:11: error: cannot assign `nil` to option value
|
||||||
|
9 |
|
||||||
|
10 | mut b := Test{}
|
||||||
|
11 | b.a = unsafe { nil }
|
||||||
|
| ~~~~~~
|
||||||
|
12 | }
|
12
vlib/v/checker/tests/nil_to_option_err.vv
Normal file
12
vlib/v/checker/tests/nil_to_option_err.vv
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
struct Test {
|
||||||
|
mut:
|
||||||
|
a ?int = unsafe { nil }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut a := ?int(none)
|
||||||
|
a = unsafe { nil }
|
||||||
|
|
||||||
|
mut b := Test{}
|
||||||
|
b.a = unsafe { nil }
|
||||||
|
}
|
|
@ -33,9 +33,9 @@ struct Complex {
|
||||||
o_ch_i ?chan int = chan int{cap: 10}
|
o_ch_i ?chan int = chan int{cap: 10}
|
||||||
o_my_alias ?MyInt = 123
|
o_my_alias ?MyInt = 123
|
||||||
// o_atomic_i ?atomic int // TODO: cgen error, but should be probably a checker one, since option atomics do not make sense
|
// o_atomic_i ?atomic int // TODO: cgen error, but should be probably a checker one, since option atomics do not make sense
|
||||||
o_pointer1_i ?&int = unsafe { nil }
|
o_pointer1_i ?&int
|
||||||
o_pointer2_i ?&&int = unsafe { nil }
|
o_pointer2_i ?&&int
|
||||||
o_pointer3_i ?&&&int = unsafe { nil }
|
o_pointer3_i ?&&&int
|
||||||
//
|
//
|
||||||
o_array_i ?[]int
|
o_array_i ?[]int
|
||||||
o_map_i ?map[int]int
|
o_map_i ?map[int]int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue