checker: remove redundant code of find field with embed (#12600)
parent
87029e5707
commit
6d6a23a1c9
|
@ -878,8 +878,6 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
mut inited_fields := []string{}
|
||||
for i, mut field in node.fields {
|
||||
mut field_info := ast.StructField{}
|
||||
mut embed_type := ast.Type(0)
|
||||
mut is_embed := false
|
||||
mut field_name := ''
|
||||
if node.is_short {
|
||||
if i >= info.fields.len {
|
||||
|
@ -893,27 +891,10 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
} else {
|
||||
field_name = field.name
|
||||
mut exists := true
|
||||
field_info = info.find_field(field_name) or {
|
||||
field_info = c.table.find_field_with_embeds(type_sym, field_name) or {
|
||||
exists = false
|
||||
ast.StructField{}
|
||||
}
|
||||
if !exists {
|
||||
for embed in info.embeds {
|
||||
embed_sym := c.table.get_type_symbol(embed)
|
||||
if embed_sym.embed_name() == field_name {
|
||||
exists = true
|
||||
embed_type = embed
|
||||
is_embed = true
|
||||
break
|
||||
}
|
||||
embed_struct_info := embed_sym.info as ast.Struct
|
||||
if embed_field_info := embed_struct_info.find_field(field_name) {
|
||||
exists = true
|
||||
field_info = embed_field_info
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
c.error('unknown field `$field.name` in struct literal of type `$type_sym.name`',
|
||||
field.pos)
|
||||
|
@ -927,57 +908,43 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
}
|
||||
mut expr_type := ast.Type(0)
|
||||
mut expected_type := ast.Type(0)
|
||||
if is_embed {
|
||||
expected_type = embed_type
|
||||
c.expected_type = expected_type
|
||||
expr_type = c.expr(field.expr)
|
||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||
if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
||||
c.check_expected(expr_type, embed_type) or {
|
||||
c.error('cannot assign to field `$field_info.name`: $err.msg',
|
||||
field.pos)
|
||||
}
|
||||
}
|
||||
node.fields[i].typ = expr_type
|
||||
node.fields[i].expected_type = embed_type
|
||||
} else {
|
||||
inited_fields << field_name
|
||||
field_type_sym := c.table.get_type_symbol(field_info.typ)
|
||||
expected_type = field_info.typ
|
||||
c.expected_type = expected_type
|
||||
expr_type = c.expr(field.expr)
|
||||
if !field_info.typ.has_flag(.optional) {
|
||||
expr_type = c.check_expr_opt_call(field.expr, expr_type)
|
||||
}
|
||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||
if field_type_sym.kind == .interface_ {
|
||||
if c.type_implements(expr_type, field_info.typ, field.pos) {
|
||||
if !expr_type.is_ptr() && !expr_type.is_pointer()
|
||||
&& expr_type_sym.kind != .interface_ && !c.inside_unsafe {
|
||||
c.mark_as_referenced(mut &field.expr, true)
|
||||
}
|
||||
}
|
||||
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
||||
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or {
|
||||
c.error('cannot assign to field `$field_info.name`: $err.msg',
|
||||
field.pos)
|
||||
}
|
||||
}
|
||||
if field_info.typ.has_flag(.shared_f) {
|
||||
if !expr_type.has_flag(.shared_f) && expr_type.is_ptr() {
|
||||
c.error('`shared` field must be initialized with `shared` or value',
|
||||
field.pos)
|
||||
}
|
||||
} else {
|
||||
if field_info.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_pointer()
|
||||
&& !expr_type.is_number() {
|
||||
c.error('reference field must be initialized with reference',
|
||||
field.pos)
|
||||
}
|
||||
}
|
||||
node.fields[i].typ = expr_type
|
||||
node.fields[i].expected_type = field_info.typ
|
||||
inited_fields << field_name
|
||||
field_type_sym := c.table.get_type_symbol(field_info.typ)
|
||||
expected_type = field_info.typ
|
||||
c.expected_type = expected_type
|
||||
expr_type = c.expr(field.expr)
|
||||
if !field_info.typ.has_flag(.optional) {
|
||||
expr_type = c.check_expr_opt_call(field.expr, expr_type)
|
||||
}
|
||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||
if field_type_sym.kind == .interface_ {
|
||||
if c.type_implements(expr_type, field_info.typ, field.pos) {
|
||||
if !expr_type.is_ptr() && !expr_type.is_pointer()
|
||||
&& expr_type_sym.kind != .interface_ && !c.inside_unsafe {
|
||||
c.mark_as_referenced(mut &field.expr, true)
|
||||
}
|
||||
}
|
||||
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
||||
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or {
|
||||
c.error('cannot assign to field `$field_info.name`: $err.msg',
|
||||
field.pos)
|
||||
}
|
||||
}
|
||||
if field_info.typ.has_flag(.shared_f) {
|
||||
if !expr_type.has_flag(.shared_f) && expr_type.is_ptr() {
|
||||
c.error('`shared` field must be initialized with `shared` or value',
|
||||
field.pos)
|
||||
}
|
||||
} else {
|
||||
if field_info.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_pointer()
|
||||
&& !expr_type.is_number() {
|
||||
c.error('reference field must be initialized with reference',
|
||||
field.pos)
|
||||
}
|
||||
}
|
||||
node.fields[i].typ = expr_type
|
||||
node.fields[i].expected_type = field_info.typ
|
||||
|
||||
if field_info.typ.has_flag(.optional) {
|
||||
c.error('field `$field_info.name` is optional, but initialization of optional fields currently unsupported',
|
||||
field.pos)
|
||||
|
@ -1661,23 +1628,11 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
|||
mut typ_sym := c.table.get_final_type_symbol(c.unwrap_generic(expr.expr_type))
|
||||
match typ_sym.kind {
|
||||
.struct_ {
|
||||
struct_info := typ_sym.info as ast.Struct
|
||||
mut has_field := true
|
||||
mut field_info := struct_info.find_field(expr.field_name) or {
|
||||
mut field_info := c.table.find_field_with_embeds(typ_sym, expr.field_name) or {
|
||||
has_field = false
|
||||
ast.StructField{}
|
||||
}
|
||||
if !has_field {
|
||||
for embed in struct_info.embeds {
|
||||
embed_sym := c.table.get_type_symbol(embed)
|
||||
embed_struct_info := embed_sym.info as ast.Struct
|
||||
if embed_field_info := embed_struct_info.find_field(expr.field_name) {
|
||||
has_field = true
|
||||
field_info = embed_field_info
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !has_field {
|
||||
type_str := c.table.type_to_str(expr.expr_type)
|
||||
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)
|
||||
|
|
Loading…
Reference in New Issue