mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix struct initialization with option value (#17539)
This commit is contained in:
parent
b4f0bb247d
commit
2597efa7f6
@ -70,7 +70,7 @@ fn (mut g Gen) expr_opt_with_cast(expr ast.Expr, expr_typ ast.Type, ret_typ ast.
|
|||||||
} else {
|
} else {
|
||||||
old_inside_opt_or_res := g.inside_opt_or_res
|
old_inside_opt_or_res := g.inside_opt_or_res
|
||||||
g.inside_opt_or_res = false
|
g.inside_opt_or_res = false
|
||||||
g.expr(expr)
|
g.expr_with_cast(expr, expr_typ, ret_typ)
|
||||||
g.inside_opt_or_res = old_inside_opt_or_res
|
g.inside_opt_or_res = old_inside_opt_or_res
|
||||||
}
|
}
|
||||||
g.writeln(' }, (${option_name}*)(&${tmp_var}), sizeof(${styp}));')
|
g.writeln(' }, (${option_name}*)(&${tmp_var}), sizeof(${styp}));')
|
||||||
|
@ -2260,8 +2260,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if got_sym.info !is ast.Interface && exp_sym.info is ast.Interface
|
if got_sym.info !is ast.Interface && exp_sym.info is ast.Interface
|
||||||
&& got_type.idx() != expected_type.idx() && !expected_type.has_flag(.option)
|
&& got_type.idx() != expected_type.idx() && !expected_type.has_flag(.result) {
|
||||||
&& !expected_type.has_flag(.result) {
|
|
||||||
if expr is ast.StructInit && !got_type.is_ptr() {
|
if expr is ast.StructInit && !got_type.is_ptr() {
|
||||||
g.inside_cast_in_heap++
|
g.inside_cast_in_heap++
|
||||||
got_styp := g.cc_type(got_type.ref(), true)
|
got_styp := g.cc_type(got_type.ref(), true)
|
||||||
|
@ -336,12 +336,21 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
|
|||||||
g.write('.${field_name} = ')
|
g.write('.${field_name} = ')
|
||||||
if field.has_default_expr {
|
if field.has_default_expr {
|
||||||
if sym.kind in [.sum_type, .interface_] {
|
if sym.kind in [.sum_type, .interface_] {
|
||||||
g.expr_with_cast(field.default_expr, field.default_expr_typ, field.typ)
|
if field.typ.has_flag(.option) {
|
||||||
|
g.expr_opt_with_cast(field.default_expr, field.default_expr_typ.set_flag(.option),
|
||||||
|
field.typ)
|
||||||
|
} else {
|
||||||
|
g.expr_with_cast(field.default_expr, field.default_expr_typ, field.typ)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.typ.has_flag(.option) && !field.default_expr_typ.has_flag(.option))
|
if field.typ.has_flag(.option) {
|
||||||
|| (field.typ.has_flag(.result) && !field.default_expr_typ.has_flag(.result)) {
|
tmp_var := g.new_tmp_var()
|
||||||
|
g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ,
|
||||||
|
tmp_var)
|
||||||
|
return true
|
||||||
|
} else if field.typ.has_flag(.result) && !field.default_expr_typ.has_flag(.result) {
|
||||||
tmp_var := g.new_tmp_var()
|
tmp_var := g.new_tmp_var()
|
||||||
g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ,
|
g.expr_with_tmp_var(field.default_expr, field.default_expr_typ, field.typ,
|
||||||
tmp_var)
|
tmp_var)
|
||||||
@ -538,10 +547,9 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua
|
|||||||
g.write('/* autoref */&')
|
g.write('/* autoref */&')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sfield.expected_type.has_flag(.option) && !sfield.typ.has_flag(.option))
|
if sfield.expected_type.has_flag(.option)
|
||||||
|| (sfield.expected_type.has_flag(.result) && !sfield.typ.has_flag(.result)) {
|
|| (sfield.expected_type.has_flag(.result) && !sfield.typ.has_flag(.result)) {
|
||||||
tmp_var := g.new_tmp_var()
|
g.expr_with_opt(sfield.expr, sfield.typ, sfield.expected_type)
|
||||||
g.expr_with_tmp_var(sfield.expr, sfield.typ, sfield.expected_type, tmp_var)
|
|
||||||
} else {
|
} else {
|
||||||
g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type)
|
g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type)
|
||||||
}
|
}
|
||||||
|
18
vlib/v/tests/option_struct_init_interface_test.v
Normal file
18
vlib/v/tests/option_struct_init_interface_test.v
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
interface IPerson {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PersonImpl {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Person {
|
||||||
|
other ?IPerson = PersonImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
a := Person{}
|
||||||
|
assert a.other != none
|
||||||
|
}
|
19
vlib/v/tests/option_struct_init_with_opt_test.v
Normal file
19
vlib/v/tests/option_struct_init_with_opt_test.v
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
struct Foo {
|
||||||
|
x ?string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
x := ?string('hi')
|
||||||
|
foo := Foo{
|
||||||
|
x: x
|
||||||
|
}
|
||||||
|
assert foo.x? == 'hi'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_none() {
|
||||||
|
x := ?string(none)
|
||||||
|
foo := Foo{
|
||||||
|
x: x
|
||||||
|
}
|
||||||
|
assert foo.x == none
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user