cgen: cast default struct field value to correct SumType/interface (#8619)
parent
e2ff26a066
commit
5abd49d9bc
|
@ -465,10 +465,14 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) {
|
||||||
if field.has_default_expr {
|
if field.has_default_expr {
|
||||||
c.expected_type = field.typ
|
c.expected_type = field.typ
|
||||||
field_expr_type := c.expr(field.default_expr)
|
field_expr_type := c.expr(field.default_expr)
|
||||||
|
struct_sym.info.fields[i].default_expr_typ = field_expr_type
|
||||||
c.check_expected(field_expr_type, field.typ) or {
|
c.check_expected(field_expr_type, field.typ) or {
|
||||||
|
if !(sym.kind == .interface_
|
||||||
|
&& c.type_implements(field_expr_type, field.typ, field.pos)) {
|
||||||
c.error('incompatible initializer for field `$field.name`: $err',
|
c.error('incompatible initializer for field `$field.name`: $err',
|
||||||
field.default_expr.position())
|
field.default_expr.position())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Check for unnecessary inits like ` = 0` and ` = ''`
|
// Check for unnecessary inits like ` = 0` and ` = ''`
|
||||||
if field.typ.is_ptr() {
|
if field.typ.is_ptr() {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -5074,8 +5074,14 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
fn (mut g Gen) zero_struct_field(field table.Field) {
|
fn (mut g Gen) zero_struct_field(field table.Field) {
|
||||||
field_name := c_name(field.name)
|
field_name := c_name(field.name)
|
||||||
g.write('.$field_name = ')
|
g.write('.$field_name = ')
|
||||||
|
sym := g.table.get_type_symbol(field.typ)
|
||||||
|
defex := ast.fe2ex(field.default_expr)
|
||||||
if field.has_default_expr {
|
if field.has_default_expr {
|
||||||
g.expr(ast.fe2ex(field.default_expr))
|
if sym.kind in [.sum_type, .interface_] {
|
||||||
|
g.expr_with_cast(defex, field.default_expr_typ, field.typ)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.expr(defex)
|
||||||
} else {
|
} else {
|
||||||
g.write(g.type_default(field.typ))
|
g.write(g.type_default(field.typ))
|
||||||
}
|
}
|
||||||
|
|
|
@ -694,6 +694,7 @@ pub mut:
|
||||||
typ Type
|
typ Type
|
||||||
default_expr FExpr
|
default_expr FExpr
|
||||||
has_default_expr bool
|
has_default_expr bool
|
||||||
|
default_expr_typ Type
|
||||||
default_val string
|
default_val string
|
||||||
attrs []Attr
|
attrs []Attr
|
||||||
is_pub bool
|
is_pub bool
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
struct Foo {
|
||||||
|
x int
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FooBar {
|
||||||
|
x int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Abc {
|
||||||
|
foobar FooBar = Foo { x: 123 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_struct_field_default_value_interface_cast() {
|
||||||
|
x := Abc{}
|
||||||
|
assert x.foobar is Foo
|
||||||
|
assert x.foobar.x == 123
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
struct Foo {
|
||||||
|
x int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar {}
|
||||||
|
|
||||||
|
type FooBar = Foo | Bar
|
||||||
|
|
||||||
|
struct Abc {
|
||||||
|
foobar FooBar = Foo { x: 123 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_struct_field_default_value_sumtype_cast() {
|
||||||
|
x := Abc{}
|
||||||
|
assert x.foobar is Foo
|
||||||
|
assert (x.foobar as Foo).x == 123
|
||||||
|
}
|
Loading…
Reference in New Issue