checker, cgen: fix aliased array methods (#10603)
parent
58df35b453
commit
f45f30a9c2
|
@ -1825,6 +1825,13 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
|
||||||
if !c.check_types(arg_type, info.elem_type) && !c.check_types(left_type, arg_type) {
|
if !c.check_types(arg_type, info.elem_type) && !c.check_types(left_type, arg_type) {
|
||||||
c.error('cannot $method_name `$arg_sym.name` to `$left_type_sym.name`', arg_expr.position())
|
c.error('cannot $method_name `$arg_sym.name` to `$left_type_sym.name`', arg_expr.position())
|
||||||
}
|
}
|
||||||
|
} else if c.table.get_final_type_symbol(left_type).kind == .array
|
||||||
|
&& method_name in ['first', 'last', 'pop'] {
|
||||||
|
info := c.table.get_final_type_symbol(left_type).info
|
||||||
|
if info is ast.Array {
|
||||||
|
call_expr.return_type = info.elem_type
|
||||||
|
return info.elem_type
|
||||||
|
}
|
||||||
} else if left_type_sym.kind == .thread && method_name == 'wait' {
|
} else if left_type_sym.kind == .thread && method_name == 'wait' {
|
||||||
info := left_type_sym.info as ast.Thread
|
info := left_type_sym.info as ast.Thread
|
||||||
if call_expr.args.len > 0 {
|
if call_expr.args.len > 0 {
|
||||||
|
|
|
@ -558,6 +558,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
left_sym := g.table.get_type_symbol(node.left_type)
|
left_sym := g.table.get_type_symbol(node.left_type)
|
||||||
|
final_left_sym := g.table.get_final_type_symbol(node.left_type)
|
||||||
if left_sym.kind == .array {
|
if left_sym.kind == .array {
|
||||||
match node.name {
|
match node.name {
|
||||||
'filter' {
|
'filter' {
|
||||||
|
@ -645,16 +646,11 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
if left_sym.kind == .map && node.name in ['clone', 'move'] {
|
if left_sym.kind == .map && node.name in ['clone', 'move'] {
|
||||||
receiver_type_name = 'map'
|
receiver_type_name = 'map'
|
||||||
}
|
}
|
||||||
// TODO performance, detect `array` method differently
|
if final_left_sym.kind == .array
|
||||||
if left_sym.kind == .array
|
|
||||||
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
|
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
|
||||||
// && rec_sym.name == 'array' {
|
if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
|
||||||
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
|
// `array_Xyz_clone` => `array_clone`
|
||||||
// `array_byte_clone` => `array_clone`
|
|
||||||
receiver_type_name = 'array'
|
receiver_type_name = 'array'
|
||||||
if false && node.name == 'free' && typ_sym.has_method(node.name) {
|
|
||||||
// TODO: allow for more specific overrides of array .free() like `pub fn (x []string) free() {`
|
|
||||||
receiver_type_name = g.typ(unwrapped_rec_type).trim('*')
|
|
||||||
}
|
}
|
||||||
if node.name in ['last', 'first', 'pop'] {
|
if node.name in ['last', 'first', 'pop'] {
|
||||||
return_type_str := g.typ(node.return_type)
|
return_type_str := g.typ(node.return_type)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
type Ints = []int
|
||||||
|
|
||||||
|
fn test_first() {
|
||||||
|
ints := Ints([5, 10])
|
||||||
|
assert ints.first() == 5
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_last() {
|
||||||
|
ints := Ints([7, 4])
|
||||||
|
assert ints.last() == 4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_index() {
|
||||||
|
ints := Ints([1, 5, 2, 3])
|
||||||
|
assert ints[2] == 2
|
||||||
|
}
|
Loading…
Reference in New Issue