Skip to content

Commit f45f30a

Browse files
checker, cgen: fix aliased array methods (#10603)
1 parent 58df35b commit f45f30a

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

vlib/v/checker/checker.v

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,13 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
18251825
if !c.check_types(arg_type, info.elem_type) && !c.check_types(left_type, arg_type) {
18261826
c.error('cannot $method_name `$arg_sym.name` to `$left_type_sym.name`', arg_expr.position())
18271827
}
1828+
} else if c.table.get_final_type_symbol(left_type).kind == .array
1829+
&& method_name in ['first', 'last', 'pop'] {
1830+
info := c.table.get_final_type_symbol(left_type).info
1831+
if info is ast.Array {
1832+
call_expr.return_type = info.elem_type
1833+
return info.elem_type
1834+
}
18281835
} else if left_type_sym.kind == .thread && method_name == 'wait' {
18291836
info := left_type_sym.info as ast.Thread
18301837
if call_expr.args.len > 0 {

vlib/v/gen/c/fn.v

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
558558
return
559559
}
560560
left_sym := g.table.get_type_symbol(node.left_type)
561+
final_left_sym := g.table.get_final_type_symbol(node.left_type)
561562
if left_sym.kind == .array {
562563
match node.name {
563564
'filter' {
@@ -645,16 +646,11 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
645646
if left_sym.kind == .map && node.name in ['clone', 'move'] {
646647
receiver_type_name = 'map'
647648
}
648-
// TODO performance, detect `array` method differently
649-
if left_sym.kind == .array
649+
if final_left_sym.kind == .array
650650
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
651-
// && rec_sym.name == 'array' {
652-
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
653-
// `array_byte_clone` => `array_clone`
654-
receiver_type_name = 'array'
655-
if false && node.name == 'free' && typ_sym.has_method(node.name) {
656-
// TODO: allow for more specific overrides of array .free() like `pub fn (x []string) free() {`
657-
receiver_type_name = g.typ(unwrapped_rec_type).trim('*')
651+
if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
652+
// `array_Xyz_clone` => `array_clone`
653+
receiver_type_name = 'array'
658654
}
659655
if node.name in ['last', 'first', 'pop'] {
660656
return_type_str := g.typ(node.return_type)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type Ints = []int
2+
3+
fn test_first() {
4+
ints := Ints([5, 10])
5+
assert ints.first() == 5
6+
}
7+
8+
fn test_last() {
9+
ints := Ints([7, 4])
10+
assert ints.last() == 4
11+
}
12+
13+
fn test_index() {
14+
ints := Ints([1, 5, 2, 3])
15+
assert ints[2] == 2
16+
}

0 commit comments

Comments
 (0)