Skip to content

Commit

Permalink
checker: disallow assigning nil to struct fields (#18725)
Browse files Browse the repository at this point in the history
  • Loading branch information
Delta456 committed Jul 2, 2023
1 parent 44a6741 commit 0ce3e46
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
7 changes: 7 additions & 0 deletions vlib/v/checker/struct.v
Expand Up @@ -596,6 +596,13 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
inited_fields << struct_field.name
}
}
expected_type_sym := c.table.final_sym(init_field.expected_type)
if expected_type_sym.kind in [.string, .array, .map, .array_fixed, .chan, .struct_]
&& init_field.expr.is_nil() && !init_field.expected_type.is_ptr()
&& mut init_field.expr is ast.UnsafeExpr {
c.error('cannot assign `nil` to struct field `${init_field.name}` with type `${expected_type_sym.name}`',
init_field.expr.pos.extend(init_field.expr.expr.pos()))
}
}
// Check uninitialized refs/sum types
// The variable `fields` contains two parts, the first part is the same as info.fields,
Expand Down
@@ -0,0 +1,42 @@
vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv:15:8: error: cannot assign `nil` to struct field `name` with type `string`
13 |
14 | a := &Foo{
15 | name: unsafe { nil }
| ~~~~~~~~~~~~
16 | bar: unsafe { nil }
17 | name2: unsafe { nil }
vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv:16:7: error: cannot assign `nil` to struct field `bar` with type `Bar`
14 | a := &Foo{
15 | name: unsafe { nil }
16 | bar: unsafe { nil }
| ~~~~~~~~~~~~
17 | name2: unsafe { nil }
18 | arr: unsafe { nil }
vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv:17:9: error: cannot assign `nil` to struct field `name2` with type `string`
15 | name: unsafe { nil }
16 | bar: unsafe { nil }
17 | name2: unsafe { nil }
| ~~~~~~~~~~~~
18 | arr: unsafe { nil }
19 | mp: unsafe { nil }
vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv:18:7: error: cannot assign `nil` to struct field `arr` with type `[]int`
16 | bar: unsafe { nil }
17 | name2: unsafe { nil }
18 | arr: unsafe { nil }
| ~~~~~~~~~~~~
19 | mp: unsafe { nil }
20 | arr_fix: unsafe { nil }
vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv:19:6: error: cannot assign `nil` to struct field `mp` with type `map[string]string`
17 | name2: unsafe { nil }
18 | arr: unsafe { nil }
19 | mp: unsafe { nil }
| ~~~~~~~~~~~~
20 | arr_fix: unsafe { nil }
21 | }
vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv:20:11: error: cannot assign `nil` to struct field `arr_fix` with type `[3]int`
18 | arr: unsafe { nil }
19 | mp: unsafe { nil }
20 | arr_fix: unsafe { nil }
| ~~~~~~~~~~~~
21 | }
22 | println(a)
22 changes: 22 additions & 0 deletions vlib/v/checker/tests/struct_field_assign_internal_types_nil_err.vv
@@ -0,0 +1,22 @@
type String = string

struct Bar {}

struct Foo {
name string
bar Bar
name2 String
arr []int
mp map[string]string
arr_fix [3]int
}

a := &Foo{
name: unsafe { nil }
bar: unsafe { nil }
name2: unsafe { nil }
arr: unsafe { nil }
mp: unsafe { nil }
arr_fix: unsafe { nil }
}
println(a)

0 comments on commit 0ce3e46

Please sign in to comment.