all: make 0 => unsafe { nil } an error, not a notice

This commit is contained in:
Alexander Medvednikov 2024-10-07 01:54:19 +03:00
parent a2d385aee3
commit 2b52153c14
15 changed files with 26 additions and 33 deletions

View File

@ -6707,16 +6707,16 @@ struct Node {
}
// Reference fields must be initialized unless an initial value is declared.
// Zero (0) is OK but use with caution, it's a nil pointer.
// Nil is OK but use with caution, it's a nil pointer.
foo := Node{
a: 0
a: unsafe { nil }
}
bar := Node{
a: &foo
}
baz := Node{
a: 0
b: 0
a: unsafe { nil }
b: unsafe { nil }
}
qux := Node{
a: &foo

View File

@ -51,7 +51,7 @@ and a new scope is created:
import v.ast
scope := ast.Scope{
parent: 0
parent: unsafe { nil }
}
```
after that, you can parse your files.

View File

@ -760,7 +760,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
&& !got_type.is_any_kind_of_pointer() && !exp_type.has_flag(.option)
&& !(init_field.expr is ast.UnsafeExpr && init_field.expr.expr.str() == '0') {
if init_field.expr.str() == '0' {
c.note('assigning `0` to a reference field is only allowed in `unsafe` blocks',
c.error('assigning `0` to a reference field is only allowed in `unsafe` blocks',
init_field.pos)
} else {
c.error('reference field must be initialized with reference',

View File

@ -1,11 +1,11 @@
vlib/v/checker/tests/struct_ref_fields_init_0_err.vv:6:10: notice: assigning `0` to a reference field is only allowed in `unsafe` blocks
vlib/v/checker/tests/struct_ref_fields_init_0_err.vv:6:10: error: assigning `0` to a reference field is only allowed in `unsafe` blocks
4 |
5 | fn main() {
6 | _ = Foo{0}
| ^
7 | _ = Foo{
8 | foo: 0
vlib/v/checker/tests/struct_ref_fields_init_0_err.vv:8:3: notice: assigning `0` to a reference field is only allowed in `unsafe` blocks
vlib/v/checker/tests/struct_ref_fields_init_0_err.vv:8:3: error: assigning `0` to a reference field is only allowed in `unsafe` blocks
6 | _ = Foo{0}
7 | _ = Foo{
8 | foo: 0

View File

@ -3,10 +3,10 @@ vlib/v/parser/tests/invalid_struct_decl_script_err.vv:1:1: notice: script mode s
| ~~~~~
2 |
3 | struct Abc {
vlib/v/parser/tests/invalid_struct_decl_script_err.vv:3:1: error: all definitions must occur before code in script mode
vlib/v/parser/tests/invalid_struct_decl_script_err.vv:3:8: error: all definitions must occur before code in script mode
1 | mynum := 10
2 |
3 | struct Abc {
| ~~~~~~
| ~~~
4 | x int
5 | }

View File

@ -41,7 +41,7 @@ fn test_eval() {
vpref := &pref.Preferences{}
mut scope := &ast.Scope{
start_pos: 0
parent: 0
parent: unsafe { nil }
}
mut stmts := []ast.Stmt{}
for input in inputs {

View File

@ -209,7 +209,7 @@ fn test_struct_with_struct_pointer() {
}
fn test_struct_with_nil() {
w := Wrapper4{0}
w := Wrapper4{unsafe { nil }}
assert '${w}' == 'Wrapper4{\n foo: &nil\n}'
assert w.str() == 'Wrapper4{\n foo: &nil\n}'
}

View File

@ -60,14 +60,14 @@ mut:
}
fn test_stack_circular_elem_auto_str() {
mut elem := Circular{0}
mut elem := Circular{unsafe { nil }}
elem.next = &elem
s := '${elem}'.replace('\n', '|')
assert s == 'Circular{| next: &<circular>|}'
}
fn test_heap_circular_elem_auto_str() {
mut elem := &Circular{0}
mut elem := &Circular{unsafe { nil }}
elem.next = elem
s := '${elem}'.replace('\n', '|')
assert s == '&Circular{| next: &<circular>|}'

View File

@ -1,13 +1,7 @@
struct Node {
val int
left &Node
right &Node
}
fn test_string_ref_struct() {
n := Node{123, 0, 0}
println(n.left)
assert '${n.left}' == '&nil'
left &Node = unsafe { nil }
right &Node = unsafe { nil }
}
fn test_string_ref_struct_with_nil_instead_of_0() {

View File

@ -38,7 +38,7 @@ fn new[T]() &Node[T] {
}
fn (mut n Node[T]) add(val T) {
node := &Node[T]{val, 0}
node := &Node[T]{val, unsafe { nil }}
n.next = node
}

View File

@ -14,8 +14,8 @@ pub fn list_new[T]() List[T] {
}
pub fn (mut l List[T]) add(value T) {
mut node := &ListNode[T]{value, 0}
if unsafe { l.head == 0 } {
mut node := &ListNode[T]{value, unsafe { nil }}
if unsafe { l.head == nil } {
l.head = node
} else {
node.next = l.head

View File

@ -136,8 +136,8 @@ fn (mut node ListNode[T]) test() &ListNode[T] {
}
fn test_generics_return_generic_struct_field() {
mut node1 := &ListNode[int]{100, 0}
mut node2 := &ListNode[int]{200, 0}
mut node1 := &ListNode[int]{100, unsafe { nil }}
mut node2 := &ListNode[int]{200, unsafe { nil }}
node1.next = node2
ret := node1.test()
println(ret)

View File

@ -1,13 +1,12 @@
struct Node[T] {
mut:
val T
next &Node[T]
next &Node[T] = unsafe { nil }
}
fn make_node[T](val []T) Node[T] {
return Node[T]{
val: val[0]
next: 0
}
}

View File

@ -15,7 +15,7 @@ fn create[T](arr []T) &List[T] {
assert arr.len > 0
mut n := &ListNode[T]{
val: arr[0]
next: 0
next: unsafe { nil }
}
mut l := &List[T]{
first: n

View File

@ -50,7 +50,7 @@ fn test_sum_type_match() {
baz: &IntAndStr{
foo: 3
bar: 'hello'
baz: 0
baz: unsafe { nil }
}
}) == 'This is the string representation of "5_hi_hello"'
assert as_string(true) == 'This is the string representation of "true"'
@ -532,7 +532,7 @@ fn sumtype_match_with_string_interpolation(code int) string {
baz: &IntAndStr{
foo: 3
bar: 'hello'
baz: 0
baz: unsafe { nil }
}
})
match bar {