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

checker: clean up in struct_init() (#18154)

This commit is contained in:
yuyi 2023-05-12 14:34:55 +08:00 committed by GitHub
parent 67e3061ea1
commit 2351856fc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -493,58 +493,58 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
continue continue
} }
} }
mut expr_type := ast.Type(0) mut got_type := ast.Type(0)
mut expected_type := ast.Type(0) mut exp_type := ast.Type(0)
inited_fields << field_name inited_fields << field_name
field_type_sym := c.table.sym(field_info.typ) exp_type = field_info.typ
expected_type = field_info.typ exp_type_sym := c.table.sym(exp_type)
c.expected_type = expected_type c.expected_type = exp_type
expr_type = c.expr(field.expr) got_type = c.expr(field.expr)
if expr_type == ast.void_type { got_type_sym := c.table.sym(got_type)
if got_type == ast.void_type {
c.error('`${field.expr}` (no value) used as value', field.pos) c.error('`${field.expr}` (no value) used as value', field.pos)
} }
if !field_info.typ.has_flag(.option) && !field.typ.has_flag(.result) { if !exp_type.has_flag(.option) && !got_type.has_flag(.result) {
expr_type = c.check_expr_opt_call(field.expr, expr_type) got_type = c.check_expr_opt_call(field.expr, got_type)
if expr_type.has_flag(.option) { if got_type.has_flag(.option) {
c.error('cannot assign an Option value to a non-option struct field', c.error('cannot assign an Option value to a non-option struct field',
field.pos) field.pos)
} }
} }
expr_type_sym := c.table.sym(expr_type) if exp_type_sym.kind == .voidptr && got_type_sym.kind == .struct_
if field_type_sym.kind == .voidptr && expr_type_sym.kind == .struct_ && !got_type.is_ptr() {
&& !expr_type.is_ptr() {
c.error('allocate on the heap for use in other functions', field.pos) c.error('allocate on the heap for use in other functions', field.pos)
} }
if field_type_sym.kind == .interface_ { if exp_type_sym.kind == .interface_ {
if c.type_implements(expr_type, field_info.typ, field.pos) { if c.type_implements(got_type, exp_type, field.pos) {
if !c.inside_unsafe && expr_type_sym.kind != .interface_ if !c.inside_unsafe && got_type_sym.kind != .interface_
&& !expr_type.is_real_pointer() { && !got_type.is_real_pointer() {
c.mark_as_referenced(mut &field.expr, true) c.mark_as_referenced(mut &field.expr, true)
} }
} }
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder } else if got_type != ast.void_type && got_type_sym.kind != .placeholder
&& !field_info.typ.has_flag(.generic) { && !exp_type.has_flag(.generic) {
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or { c.check_expected(c.unwrap_generic(got_type), c.unwrap_generic(exp_type)) or {
c.error('cannot assign to field `${field_info.name}`: ${err.msg()}', c.error('cannot assign to field `${field_info.name}`: ${err.msg()}',
field.pos) field.pos)
} }
} }
if field_info.typ.has_flag(.shared_f) { if exp_type.has_flag(.shared_f) {
if !expr_type.has_flag(.shared_f) && expr_type.is_ptr() { if !got_type.has_flag(.shared_f) && got_type.is_ptr() {
c.error('`shared` field must be initialized with `shared` or value', c.error('`shared` field must be initialized with `shared` or value',
field.pos) field.pos)
} }
} else { } else {
if field_info.typ.is_ptr() && !expr_type.is_real_pointer() if exp_type.is_ptr() && !got_type.is_real_pointer() && field.expr.str() != '0'
&& field.expr.str() != '0' && !field_info.typ.has_flag(.option) { && !exp_type.has_flag(.option) {
c.error('reference field must be initialized with reference', c.error('reference field must be initialized with reference',
field.pos) field.pos)
} }
} }
node.fields[i].typ = expr_type node.fields[i].typ = got_type
node.fields[i].expected_type = field_info.typ node.fields[i].expected_type = exp_type
if expr_type.is_ptr() && expected_type.is_ptr() { if got_type.is_ptr() && exp_type.is_ptr() {
if mut field.expr is ast.Ident { if mut field.expr is ast.Ident {
if mut field.expr.obj is ast.Var { if mut field.expr.obj is ast.Var {
mut obj := unsafe { &field.expr.obj } mut obj := unsafe { &field.expr.obj }
@ -575,7 +575,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
} }
} }
if field_type_sym.kind == .struct_ && !(field_type_sym.info as ast.Struct).is_anon if exp_type_sym.kind == .struct_ && !(exp_type_sym.info as ast.Struct).is_anon
&& mut field.expr is ast.StructInit { && mut field.expr is ast.StructInit {
if field.expr.is_anon { if field.expr.is_anon {
c.error('cannot assign anonymous `struct` to a typed `struct`', c.error('cannot assign anonymous `struct` to a typed `struct`',