checker, cgen: fix aliased array methods (#10603)

pull/10257/head
shadowninja55 2021-06-29 05:14:37 -04:00 committed by GitHub
parent 58df35b453
commit f45f30a9c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 9 deletions

View File

@ -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) {
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' {
info := left_type_sym.info as ast.Thread
if call_expr.args.len > 0 {

View File

@ -558,6 +558,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
return
}
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 {
match node.name {
'filter' {
@ -645,16 +646,11 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
if left_sym.kind == .map && node.name in ['clone', 'move'] {
receiver_type_name = 'map'
}
// TODO performance, detect `array` method differently
if left_sym.kind == .array
if final_left_sym.kind == .array
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
// && rec_sym.name == 'array' {
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
// `array_byte_clone` => `array_clone`
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 !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
// `array_Xyz_clone` => `array_clone`
receiver_type_name = 'array'
}
if node.name in ['last', 'first', 'pop'] {
return_type_str := g.typ(node.return_type)

View File

@ -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
}