From ae0e90f5d8ee2bb3b106c705b2d1db0bd892e44e Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 12 Feb 2022 13:16:51 +0800 Subject: [PATCH] cgen: fix struct init with embed field update (#13444) --- vlib/v/ast/ast.v | 1 + vlib/v/gen/c/cgen.v | 11 +++++++ .../struct_init_with_embed_update_test.v | 32 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 vlib/v/tests/struct_init_with_embed_update_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 990a91f669..d7bb96ea26 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -409,6 +409,7 @@ pub mut: update_expr Expr update_expr_type Type update_expr_comments []Comment + is_update_embed bool has_update_expr bool fields []StructInitField embeds []StructInitEmbed diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 5b9b351caf..da9561ec94 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5456,6 +5456,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) { default_init := ast.StructInit{ ...node typ: embed + is_update_embed: true fields: init_fields_to_embed } inside_cast_in_heap := g.inside_cast_in_heap @@ -5557,6 +5558,16 @@ fn (mut g Gen) struct_init(node ast.StructInit) { } else { g.write('.') } + if node.is_update_embed { + embed_sym := g.table.sym(node.typ) + embed_name := embed_sym.embed_name() + g.write(embed_name) + if node.typ.is_ptr() { + g.write('->') + } else { + g.write('.') + } + } g.write(field.name) } else { if !g.zero_struct_field(field) { diff --git a/vlib/v/tests/struct_init_with_embed_update_test.v b/vlib/v/tests/struct_init_with_embed_update_test.v new file mode 100644 index 0000000000..cb325830f3 --- /dev/null +++ b/vlib/v/tests/struct_init_with_embed_update_test.v @@ -0,0 +1,32 @@ +struct Button { + width int + height int +} + +enum Color { + red + blue + yellow +} + +struct ColoredButton { + Button + color Color +} + +fn change_color(cb ColoredButton, color Color) ColoredButton { + return ColoredButton{ + ...cb + color: color + } +} + +fn test_struct_update_with_embed_field() { + red_button := ColoredButton{Button{100, 100}, .red} + blue_button := change_color(red_button, .blue) + + println(red_button) + println(blue_button) + + assert blue_button == ColoredButton{Button{100, 100}, .blue} +}