Skip to content

Commit 00a08c4

Browse files
authored
checker, cgen: fix sumtype smartcasted var as inherited var (fix #23716) (#23731)
1 parent f4aa139 commit 00a08c4

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

vlib/v/checker/fn.v

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,13 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type {
634634
c.error('original `${parent_var.name}` is immutable, declare it with `mut` to make it mutable',
635635
var.pos)
636636
}
637+
ptyp := if parent_var.smartcasts.len > 0 {
638+
parent_var.smartcasts.last()
639+
} else {
640+
parent_var.typ
641+
}
637642
if parent_var.typ != ast.no_type {
638-
parent_var_sym := c.table.final_sym(parent_var.typ)
643+
parent_var_sym := c.table.final_sym(ptyp)
639644
if parent_var_sym.info is ast.FnType {
640645
ret_typ := c.unwrap_generic(parent_var_sym.info.func.return_type)
641646
if ret_typ.has_flag(.generic) {
@@ -663,7 +668,7 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type {
663668
var.typ = parent_var.expr.expr_type.clear_option_and_result()
664669
}
665670
} else {
666-
var.typ = parent_var.typ
671+
var.typ = ptyp
667672
}
668673
if var.typ.has_flag(.generic) {
669674
has_generic = true

vlib/v/gen/c/fn.v

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,13 +662,20 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) {
662662
g.writeln('.${var_name} = string_clone(${var_name}),')
663663
} else {
664664
mut is_auto_heap := false
665+
mut field_name := ''
665666
if obj := node.decl.scope.parent.find(var.name) {
666667
if obj is ast.Var {
667668
is_auto_heap = !obj.is_stack_obj && obj.is_auto_heap
669+
if obj.smartcasts.len > 0 {
670+
if g.table.type_kind(obj.typ) == .sum_type {
671+
cast_sym := g.table.sym(obj.smartcasts.last())
672+
field_name += '._${cast_sym.cname}'
673+
}
674+
}
668675
}
669676
}
670-
if is_auto_heap && !is_ptr {
671-
g.writeln('.${var_name} = *${var_name},')
677+
if (is_auto_heap && !is_ptr) || field_name != '' {
678+
g.writeln('.${var_name} = *${var_name}${field_name},')
672679
} else {
673680
g.writeln('.${var_name} = ${var_name},')
674681
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
struct Aa {
2+
a int
3+
}
4+
5+
struct Bb {
6+
b int
7+
}
8+
9+
type Type = Aa | Bb
10+
11+
fn test_main() {
12+
t := Type(Aa{
13+
a: 2
14+
})
15+
match t {
16+
Aa {
17+
assert t.a == 2
18+
func := fn [t] () {
19+
assert typeof(t).name == 'Aa'
20+
assert t.a == 2
21+
}
22+
func()
23+
}
24+
Bb {}
25+
}
26+
}

0 commit comments

Comments
 (0)