From 9631eac9c5bb4154ceee50aff08f58d14a6ec4f3 Mon Sep 17 00:00:00 2001 From: yuyi Date: Tue, 29 Dec 2020 01:33:57 +0800 Subject: [PATCH] cgen: fix `array.index()` of ref struct (#7652) --- vlib/builtin/array_test.v | 12 +++++++ vlib/v/gen/array.v | 69 ++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index c31aafe750..3836c36fc1 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -1278,3 +1278,15 @@ fn test_array_struct_ref_contains() { println(exists) assert exists == true } + +fn test_array_struct_ref_index() { + mut coords := []&Coord{} + coord_1 := &Coord{ + x: 1 + y: 2 + z: -1 + } + coords << coord_1 + println(coords.index(coord_1)) + assert coords.index(coord_1) == 0 +} diff --git a/vlib/v/gen/array.v b/vlib/v/gen/array.v index 7481b31f16..f98e17b422 100644 --- a/vlib/v/gen/array.v +++ b/vlib/v/gen/array.v @@ -393,15 +393,15 @@ fn (mut g Gen) gen_array_prepend(node ast.CallExpr) { fn (mut g Gen) gen_array_contains_method(left_type table.Type) string { mut left_sym := g.table.get_type_symbol(left_type) mut left_type_str := g.typ(left_type).replace('*', '') - left_info := left_sym.info as table.Array - mut elem_type_str := g.typ(left_info.elem_type) - elem_sym := g.table.get_type_symbol(left_info.elem_type) - if elem_sym.kind == .function { - left_type_str = 'array_voidptr' - elem_type_str = 'voidptr' - } fn_name := '${left_type_str}_contains' if !left_sym.has_method('contains') { + left_info := left_sym.info as table.Array + mut elem_type_str := g.typ(left_info.elem_type) + elem_sym := g.table.get_type_symbol(left_info.elem_type) + if elem_sym.kind == .function { + left_type_str = 'array_voidptr' + elem_type_str = 'voidptr' + } g.type_definitions.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v); // auto') mut fn_builder := strings.new_builder(512) fn_builder.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v) {') @@ -455,42 +455,35 @@ fn (mut g Gen) gen_array_contains(node ast.CallExpr) { fn (mut g Gen) gen_array_index_method(left_type table.Type) string { mut left_sym := g.table.get_type_symbol(left_type) - mut left_type_str := g.typ(left_type).replace('*', '') - left_info := left_sym.info as table.Array - mut elem_type_str := g.typ(left_info.elem_type) - elem_sym := g.table.get_type_symbol(left_info.elem_type) - if elem_sym.kind == .function { - left_type_str = 'array_voidptr' - elem_type_str = 'voidptr' - } + mut left_type_str := g.typ(left_type).trim('*') fn_name := '${left_type_str}_index' if !left_sym.has_method('index') { + info := left_sym.info as table.Array + mut elem_type_str := g.typ(info.elem_type) + elem_sym := g.table.get_type_symbol(info.elem_type) + if elem_sym.kind == .function { + left_type_str = 'array_voidptr' + elem_type_str = 'voidptr' + } g.type_definitions.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v); // auto') mut fn_builder := strings.new_builder(512) fn_builder.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v) {') fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {') - match elem_sym.kind { - .string { - fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {') - } - .array { - ptr_typ := g.gen_array_equality_fn(left_info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {') - } - .function { - fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {') - } - .map { - ptr_typ := g.gen_map_equality_fn(left_info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {') - } - .struct_ { - ptr_typ := g.gen_struct_equality_fn(left_info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {') - } - else { - fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {') - } + if elem_sym.kind == .string { + fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {') + } else if elem_sym.kind == .array && !info.elem_type.is_ptr() { + ptr_typ := g.gen_array_equality_fn(info.elem_type) + fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {') + } else if elem_sym.kind == .function && !info.elem_type.is_ptr() { + fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {') + } else if elem_sym.kind == .map && !info.elem_type.is_ptr() { + ptr_typ := g.gen_map_equality_fn(info.elem_type) + fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {') + } else if elem_sym.kind == .struct_ && !info.elem_type.is_ptr() { + ptr_typ := g.gen_struct_equality_fn(info.elem_type) + fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {') + } else { + fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {') } fn_builder.writeln('\t\t\treturn i;') fn_builder.writeln('\t\t}') @@ -503,7 +496,7 @@ fn (mut g Gen) gen_array_index_method(left_type table.Type) string { params: [table.Param{ typ: left_type }, table.Param{ - typ: left_info.elem_type + typ: info.elem_type }] }) }