Skip to content

Commit 537605a

Browse files
authored
checker: fix map when casting to interface (fix #23790) (#23799)
1 parent ab2eb00 commit 537605a

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

vlib/v/gen/c/array.v

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,9 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
560560
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
561561
g.indent++
562562
var_name := g.get_array_expr_param_name(mut expr)
563-
g.write_prepared_var(var_name, inp_elem_type, inp_elem_styp, past.tmp_var, i, left_is_array)
563+
is_auto_heap := expr is ast.CastExpr && (expr.expr is ast.Ident && expr.expr.is_auto_heap())
564+
g.write_prepared_var(var_name, inp_elem_type, inp_elem_styp, past.tmp_var, i, left_is_array,
565+
is_auto_heap)
564566
g.set_current_pos_as_last_stmt_pos()
565567
mut is_embed_map_filter := false
566568
match mut expr {
@@ -976,7 +978,8 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
976978
i := g.new_tmp_var()
977979
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
978980
g.indent++
979-
g.write_prepared_var(var_name, info.elem_type, elem_type_str, past.tmp_var, i, true)
981+
g.write_prepared_var(var_name, info.elem_type, elem_type_str, past.tmp_var, i, true,
982+
false)
980983
g.set_current_pos_as_last_stmt_pos()
981984
mut is_embed_map_filter := false
982985
match mut expr {
@@ -1477,7 +1480,8 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
14771480
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
14781481
g.indent++
14791482

1480-
g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array)
1483+
g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array,
1484+
false)
14811485
g.set_current_pos_as_last_stmt_pos()
14821486
mut is_embed_map_filter := false
14831487
match mut expr {
@@ -1567,7 +1571,8 @@ fn (mut g Gen) gen_array_count(node ast.CallExpr) {
15671571
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
15681572
g.indent++
15691573

1570-
g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array)
1574+
g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array,
1575+
false)
15711576
g.set_current_pos_as_last_stmt_pos()
15721577
mut is_embed_map_filter := false
15731578
match mut expr {
@@ -1659,7 +1664,8 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
16591664

16601665
g.writeln('for (int ${i} = 0; ${i} < ${past.tmp_var}_len; ++${i}) {')
16611666
g.indent++
1662-
g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array)
1667+
g.write_prepared_var(var_name, elem_type, elem_type_str, past.tmp_var, i, left_is_array,
1668+
false)
16631669
g.empty_line = true
16641670
g.set_current_pos_as_last_stmt_pos()
16651671
mut is_embed_map_filter := false
@@ -1770,7 +1776,7 @@ fn (mut g Gen) write_prepared_tmp_value(tmp string, node &ast.CallExpr, tmp_styp
17701776
}
17711777

17721778
fn (mut g Gen) write_prepared_var(var_name string, elem_type ast.Type, inp_elem_type string, tmp string,
1773-
i string, is_array bool) {
1779+
i string, is_array bool, auto_heap bool) {
17741780
elem_sym := g.table.sym(elem_type)
17751781
if is_array {
17761782
if elem_sym.kind == .array_fixed {
@@ -1779,16 +1785,34 @@ fn (mut g Gen) write_prepared_var(var_name string, elem_type ast.Type, inp_elem_
17791785
} else if elem_sym.kind == .function {
17801786
g.writeln('voidptr ${var_name} = ((${inp_elem_type}*) ${tmp}_orig.data)[${i}];')
17811787
} else {
1782-
g.writeln('${inp_elem_type} ${var_name} = ((${inp_elem_type}*) ${tmp}_orig.data)[${i}];')
1788+
g.write('${inp_elem_type} ')
1789+
if auto_heap {
1790+
g.write('*')
1791+
}
1792+
g.write('${var_name} = ')
1793+
if auto_heap {
1794+
g.write('&')
1795+
}
1796+
g.writeln('((${inp_elem_type}*) ${tmp}_orig.data)[${i}];')
17831797
}
17841798
} else {
17851799
if elem_sym.kind == .array_fixed {
17861800
g.writeln('${inp_elem_type} ${var_name};')
17871801
g.writeln('memcpy(&${var_name}, &${tmp}_orig[${i}], sizeof(${inp_elem_type}));')
1802+
} else if auto_heap {
1803+
g.writeln('${inp_elem_type} *${var_name} = &${tmp}_orig[${i}];')
17881804
} else if elem_sym.kind == .function {
17891805
g.writeln('voidptr ${var_name} = (voidptr)${tmp}_orig[${i}];')
17901806
} else {
1791-
g.writeln('${inp_elem_type} ${var_name} = ${tmp}_orig[${i}];')
1807+
g.write('${inp_elem_type} ')
1808+
if auto_heap {
1809+
g.write('*')
1810+
}
1811+
g.write('${var_name} = ')
1812+
if auto_heap {
1813+
g.write('&')
1814+
}
1815+
g.writeln('${tmp}_orig[${i}];')
17921816
}
17931817
}
17941818
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
interface Rect {
2+
width u32
3+
height u32
4+
}
5+
6+
struct Square {
7+
side u32
8+
width u32
9+
height u32
10+
}
11+
12+
fn test_main() {
13+
squares := [Square{
14+
side: 5
15+
width: 5
16+
height: 5
17+
}]
18+
rects := squares.map(Rect(it))
19+
20+
assert rects.str() == '[Rect(Square{
21+
side: 5
22+
width: 5
23+
height: 5
24+
})]'
25+
}
26+
27+
fn test_fixed_array() {
28+
squares := [Square{
29+
side: 5
30+
width: 5
31+
height: 5
32+
}]!
33+
rects := squares.map(Rect(it))
34+
}

0 commit comments

Comments
 (0)