Skip to content

Commit aa502c2

Browse files
authored
checker, cgen: fix arrays alias built-in methods call(fix #19896) (#19910)
1 parent fb3d0cd commit aa502c2

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

vlib/v/checker/fn.v

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,8 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
17101710
if !c.check_types(arg_type, info.elem_type) && !c.check_types(left_type, arg_type) {
17111711
c.error('cannot ${method_name} `${arg_sym.name}` to `${left_sym.name}`', arg_expr.pos())
17121712
}
1713-
} else if final_left_sym.kind == .array && method_name in ['first', 'last', 'pop'] {
1713+
} else if final_left_sym.kind == .array
1714+
&& method_name in ['filter', 'map', 'sort', 'sorted', 'contains', 'any', 'all', 'first', 'last', 'pop'] {
17141715
return c.array_builtin_method_call(mut node, left_type, final_left_sym)
17151716
} else if c.pref.backend.is_js() && left_sym.name.starts_with('Promise[')
17161717
&& method_name == 'wait' {
@@ -2613,10 +2614,12 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
26132614
c.error('.slice() is a private method, use `x[start..end]` instead', node.pos)
26142615
return ast.void_type
26152616
}
2617+
unwrapped_left_type := c.unwrap_generic(left_type)
2618+
unaliased_left_type := c.table.unaliased_type(unwrapped_left_type)
26162619
array_info := if left_sym.info is ast.Array {
26172620
left_sym.info as ast.Array
26182621
} else {
2619-
c.table.sym(c.unwrap_generic(left_type)).info as ast.Array
2622+
c.table.sym(unaliased_left_type).info as ast.Array
26202623
}
26212624
elem_typ = array_info.elem_type
26222625
if method_name in ['filter', 'map', 'any', 'all'] {
@@ -2708,7 +2711,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
27082711
}
27092712
}
27102713
// map/filter are supposed to have 1 arg only
2711-
mut arg_type := left_type
2714+
mut arg_type := unaliased_left_type
27122715
for mut arg in node.args {
27132716
arg_type = c.check_expr_opt_call(arg.expr, c.expr(mut arg.expr))
27142717
}
@@ -2810,7 +2813,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
28102813
}
28112814
} else if method_name == 'delete' {
28122815
c.fail_if_immutable(mut node.left)
2813-
unwrapped_left_sym := c.table.sym(c.unwrap_generic(left_type))
2816+
unwrapped_left_sym := c.table.sym(unwrapped_left_type)
28142817
if method := c.table.find_method(unwrapped_left_sym, method_name) {
28152818
node.receiver_type = method.receiver_type
28162819
}

vlib/v/gen/c/array.v

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,8 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
468468
}
469469

470470
ret_typ := g.typ(node.return_type)
471-
ret_sym := g.table.sym(node.return_type)
472-
inp_sym := g.table.sym(node.receiver_type)
471+
ret_sym := g.table.final_sym(node.return_type)
472+
inp_sym := g.table.final_sym(node.receiver_type)
473473
ret_info := ret_sym.info as ast.Array
474474
mut ret_elem_type := g.typ(ret_info.elem_type)
475475
inp_info := inp_sym.info as ast.Array
@@ -581,7 +581,7 @@ fn (mut g Gen) gen_array_sorted(node ast.CallExpr) {
581581
g.past_tmp_var_done(past)
582582
}
583583
atype := g.typ(node.return_type)
584-
sym := g.table.sym(node.return_type)
584+
sym := g.table.final_sym(node.return_type)
585585
info := sym.info as ast.Array
586586
depth := g.get_array_depth(info.elem_type)
587587

@@ -601,7 +601,7 @@ fn (mut g Gen) gen_array_sorted(node ast.CallExpr) {
601601
// `users.sort(a.age < b.age)`
602602
fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
603603
// println('filter s="$s"')
604-
rec_sym := g.table.sym(node.receiver_type)
604+
rec_sym := g.table.final_sym(node.receiver_type)
605605
if rec_sym.kind != .array {
606606
println(node.name)
607607
println(g.typ(node.receiver_type))
@@ -724,7 +724,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
724724
g.past_tmp_var_done(past)
725725
}
726726

727-
sym := g.table.sym(node.return_type)
727+
sym := g.table.final_sym(node.return_type)
728728
if sym.kind != .array {
729729
verror('filter() requires an array')
730730
}
@@ -1121,7 +1121,7 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
11211121
g.past_tmp_var_done(past)
11221122
}
11231123

1124-
sym := g.table.sym(node.left_type)
1124+
sym := g.table.final_sym(node.left_type)
11251125
info := sym.info as ast.Array
11261126
// styp := g.typ(node.return_type)
11271127
elem_type_str := g.typ(info.elem_type)
@@ -1200,7 +1200,7 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
12001200
g.past_tmp_var_done(past)
12011201
}
12021202

1203-
sym := g.table.sym(node.left_type)
1203+
sym := g.table.final_sym(node.left_type)
12041204
info := sym.info as ast.Array
12051205
// styp := g.typ(node.return_type)
12061206
elem_type_str := g.typ(info.elem_type)

vlib/v/gen/c/fn.v

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
12571257
}
12581258
left_sym := g.table.sym(left_type)
12591259
final_left_sym := g.table.final_sym(left_type)
1260-
if left_sym.kind == .array {
1260+
if left_sym.kind == .array || (final_left_sym.kind == .array
1261+
&& node.name in ['filter', 'map', 'sort', 'sorted', 'contains', 'any', 'all']) {
12611262
if g.gen_array_method_call(node, left_type) {
12621263
return
12631264
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
type IntArray = []int
2+
3+
fn test_alias_array_method() {
4+
mut arr := IntArray([0, 1, 2, 3])
5+
res := arr.filter(it > 0)
6+
assert res == IntArray([1, 2, 3])
7+
8+
assert arr.first() == 0
9+
assert arr.last() == 3
10+
arr.pop()
11+
assert arr == IntArray([0, 1, 2])
12+
13+
arr2 := arr.map(it)
14+
assert arr2 == [0, 1, 2]
15+
16+
assert arr.any(it > 0)
17+
assert !arr.all(it > 0)
18+
19+
arr.sort(a > b)
20+
assert arr == IntArray([2, 1, 0])
21+
arr.sort()
22+
assert arr == IntArray([0, 1, 2])
23+
24+
assert arr.contains(1)
25+
}

0 commit comments

Comments
 (0)