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{}
|
mut inited_fields := []string{}
|
||||||
for i, mut field in node.fields {
|
for i, mut field in node.fields {
|
||||||
mut field_info := ast.StructField{}
|
mut field_info := ast.StructField{}
|
||||||
mut embed_type := ast.Type(0)
|
|
||||||
mut is_embed := false
|
|
||||||
mut field_name := ''
|
mut field_name := ''
|
||||||
if node.is_short {
|
if node.is_short {
|
||||||
if i >= info.fields.len {
|
if i >= info.fields.len {
|
||||||
|
@ -893,27 +891,10 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
||||||
} else {
|
} else {
|
||||||
field_name = field.name
|
field_name = field.name
|
||||||
mut exists := true
|
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
|
exists = false
|
||||||
ast.StructField{}
|
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 {
|
if !exists {
|
||||||
c.error('unknown field `$field.name` in struct literal of type `$type_sym.name`',
|
c.error('unknown field `$field.name` in struct literal of type `$type_sym.name`',
|
||||||
field.pos)
|
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 expr_type := ast.Type(0)
|
||||||
mut expected_type := ast.Type(0)
|
mut expected_type := ast.Type(0)
|
||||||
if is_embed {
|
inited_fields << field_name
|
||||||
expected_type = embed_type
|
field_type_sym := c.table.get_type_symbol(field_info.typ)
|
||||||
c.expected_type = expected_type
|
expected_type = field_info.typ
|
||||||
expr_type = c.expr(field.expr)
|
c.expected_type = expected_type
|
||||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
expr_type = c.expr(field.expr)
|
||||||
if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
if !field_info.typ.has_flag(.optional) {
|
||||||
c.check_expected(expr_type, embed_type) or {
|
expr_type = c.check_expr_opt_call(field.expr, expr_type)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if field_info.typ.has_flag(.optional) {
|
||||||
c.error('field `$field_info.name` is optional, but initialization of optional fields currently unsupported',
|
c.error('field `$field_info.name` is optional, but initialization of optional fields currently unsupported',
|
||||||
field.pos)
|
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))
|
mut typ_sym := c.table.get_final_type_symbol(c.unwrap_generic(expr.expr_type))
|
||||||
match typ_sym.kind {
|
match typ_sym.kind {
|
||||||
.struct_ {
|
.struct_ {
|
||||||
struct_info := typ_sym.info as ast.Struct
|
|
||||||
mut has_field := true
|
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
|
has_field = false
|
||||||
ast.StructField{}
|
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 {
|
if !has_field {
|
||||||
type_str := c.table.type_to_str(expr.expr_type)
|
type_str := c.table.type_to_str(expr.expr_type)
|
||||||
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)
|
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)
|
||||||
|
|
Loading…
Reference in New Issue