From 083eb3450be533516f8d33af1eca8574ee0b200c Mon Sep 17 00:00:00 2001 From: shove Date: Mon, 11 Dec 2023 06:59:50 +0800 Subject: [PATCH] checker: fix struct init update with generics (fix #20136) (#20139) --- vlib/v/checker/struct.v | 3 ++- .../struct_init_update_with_generics_test.v | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/struct_init_update_with_generics_test.v diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 33bf4a60dc..f5a156ed95 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -874,9 +874,10 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', if node.has_update_expr { update_type := c.expr(mut node.update_expr) node.update_expr_type = update_type + expr_sym := c.table.final_sym(c.unwrap_generic(update_type)) if node.update_expr is ast.ComptimeSelector { c.error('cannot use struct update syntax in compile time expressions', node.update_expr_pos) - } else if c.table.final_sym(update_type).kind != .struct_ { + } else if expr_sym.kind != .struct_ { s := c.table.type_to_str(update_type) c.error('expected struct, found `${s}`', node.update_expr.pos()) } else if update_type != node.typ { diff --git a/vlib/v/tests/struct_init_update_with_generics_test.v b/vlib/v/tests/struct_init_update_with_generics_test.v new file mode 100644 index 0000000000..c1f30a80f5 --- /dev/null +++ b/vlib/v/tests/struct_init_update_with_generics_test.v @@ -0,0 +1,20 @@ +struct Foo { + a int + b string + isbool bool +} + +fn do[T](f T) T { + return T{ + ...f + isbool: true + } +} + +fn test_main() { + foo := do(Foo{ + a: 1 + b: '2' + }) + assert foo.a == 1 && foo.b == '2' && foo.isbool +}