From 00a08c4fbee66713d4855e319f122f00d61020b7 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 15 Feb 2025 17:59:45 -0300 Subject: [PATCH] checker, cgen: fix sumtype smartcasted var as inherited var (fix #23716) (#23731) --- vlib/v/checker/fn.v | 9 +++++-- vlib/v/gen/c/fn.v | 11 ++++++-- .../sumtypes/sumtype_inherited_var_test.v | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/sumtypes/sumtype_inherited_var_test.v diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index d81f800311dfca..f886586ba5a5e3 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -634,8 +634,13 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type { c.error('original `${parent_var.name}` is immutable, declare it with `mut` to make it mutable', var.pos) } + ptyp := if parent_var.smartcasts.len > 0 { + parent_var.smartcasts.last() + } else { + parent_var.typ + } if parent_var.typ != ast.no_type { - parent_var_sym := c.table.final_sym(parent_var.typ) + parent_var_sym := c.table.final_sym(ptyp) if parent_var_sym.info is ast.FnType { ret_typ := c.unwrap_generic(parent_var_sym.info.func.return_type) if ret_typ.has_flag(.generic) { @@ -663,7 +668,7 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type { var.typ = parent_var.expr.expr_type.clear_option_and_result() } } else { - var.typ = parent_var.typ + var.typ = ptyp } if var.typ.has_flag(.generic) { has_generic = true diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 9f0e2a0e1c5b2b..506576916f0e5c 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -662,13 +662,20 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) { g.writeln('.${var_name} = string_clone(${var_name}),') } else { mut is_auto_heap := false + mut field_name := '' if obj := node.decl.scope.parent.find(var.name) { if obj is ast.Var { is_auto_heap = !obj.is_stack_obj && obj.is_auto_heap + if obj.smartcasts.len > 0 { + if g.table.type_kind(obj.typ) == .sum_type { + cast_sym := g.table.sym(obj.smartcasts.last()) + field_name += '._${cast_sym.cname}' + } + } } } - if is_auto_heap && !is_ptr { - g.writeln('.${var_name} = *${var_name},') + if (is_auto_heap && !is_ptr) || field_name != '' { + g.writeln('.${var_name} = *${var_name}${field_name},') } else { g.writeln('.${var_name} = ${var_name},') } diff --git a/vlib/v/tests/sumtypes/sumtype_inherited_var_test.v b/vlib/v/tests/sumtypes/sumtype_inherited_var_test.v new file mode 100644 index 00000000000000..13f6c0e7749732 --- /dev/null +++ b/vlib/v/tests/sumtypes/sumtype_inherited_var_test.v @@ -0,0 +1,26 @@ +struct Aa { + a int +} + +struct Bb { + b int +} + +type Type = Aa | Bb + +fn test_main() { + t := Type(Aa{ + a: 2 + }) + match t { + Aa { + assert t.a == 2 + func := fn [t] () { + assert typeof(t).name == 'Aa' + assert t.a == 2 + } + func() + } + Bb {} + } +}