From 130f35c7766a759c3c844c7ab0b4865e9cd3120c Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 26 Mar 2023 16:33:01 +0800 Subject: [PATCH] checker: fix embedded struct field with default value (#17777) --- vlib/v/checker/struct.v | 12 +++--- .../embed_struct_field_default_value_test.v | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 vlib/v/tests/embed_struct_field_default_value_test.v diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 8cc1e714fb..e83131e84a 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -118,17 +118,15 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { if field.has_default_expr { c.expected_type = field.typ - default_expr_type := c.expr(field.default_expr) if !field.typ.has_flag(.option) && !field.typ.has_flag(.result) { - c.check_expr_opt_call(field.default_expr, default_expr_type) + c.check_expr_opt_call(field.default_expr, field.default_expr_typ) } - struct_sym.info.fields[i].default_expr_typ = default_expr_type interface_implemented := sym.kind == .interface_ - && c.type_implements(default_expr_type, field.typ, field.pos) - c.check_expected(default_expr_type, field.typ) or { + && c.type_implements(field.default_expr_typ, field.typ, field.pos) + c.check_expected(field.default_expr_typ, field.typ) or { if sym.kind == .interface_ && interface_implemented { - if !c.inside_unsafe && !default_expr_type.is_real_pointer() { - if c.table.sym(default_expr_type).kind != .interface_ { + if !c.inside_unsafe && !field.default_expr_typ.is_real_pointer() { + if c.table.sym(field.default_expr_typ).kind != .interface_ { c.mark_as_referenced(mut &node.fields[i].default_expr, true) } diff --git a/vlib/v/tests/embed_struct_field_default_value_test.v b/vlib/v/tests/embed_struct_field_default_value_test.v new file mode 100644 index 0000000000..0921fcecd4 --- /dev/null +++ b/vlib/v/tests/embed_struct_field_default_value_test.v @@ -0,0 +1,37 @@ +struct Papa { + fam_name string +} + +pub struct Child { + Papa +pub mut: + activity Activity = Fun.roll + age u8 = 2 +} + +type Activity = Fun | Other + +pub enum Fun { + run + roll + jump +} + +pub struct Other {} + +// Same struct without embedding just works. +pub struct Human { + fam_name string +pub mut: + activity Activity = Fun.roll + age u8 = 2 +} + +fn test_embed_struct_field_default_value() { + c := Child{} + println(c.activity) + assert c.activity == Activity(Fun.roll) + h := Human{} + println(h.activity) + assert h.activity == Activity(Fun.roll) +}