1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: disallow assigning nil to struct fields (#18725)

This commit is contained in:
Swastik Baranwal 2023-07-02 16:34:28 +05:30 committed by GitHub
parent 44a6741bc3
commit 0ce3e46823
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 0 deletions

View File

@ -596,6 +596,13 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
inited_fields << struct_field.name 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 // Check uninitialized refs/sum types
// The variable `fields` contains two parts, the first part is the same as info.fields, // The variable `fields` contains two parts, the first part is the same as info.fields,

View File

@ -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)

View File

@ -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)