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:
parent
67e3061ea1
commit
2351856fc3
@ -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`',
|
||||||
|
Loading…
Reference in New Issue
Block a user