cgen: fix infix_expr_in_optimization compile error when treating some kind cannot directly use '==' (#14015)

pull/14006/head
牧心 2022-04-12 21:19:44 +08:00 committed by GitHub
parent 8788512c4d
commit a810fbb80e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 28 deletions

View File

@ -675,11 +675,7 @@ fn (mut g Gen) gen_array_contains_methods() {
fn_name := '${left_type_str}_contains'
left_info := left_final_sym.info as ast.Array
mut elem_type_str := g.typ(left_info.elem_type)
mut elem_sym := g.table.sym(left_info.elem_type)
if elem_sym.kind == .alias {
info := elem_sym.info as ast.Alias
elem_sym = g.table.sym(info.parent_type)
}
elem_sym := g.table.sym(left_info.elem_type)
if elem_sym.kind == .function {
left_type_str = 'Array_voidptr'
elem_type_str = 'voidptr'
@ -707,6 +703,9 @@ fn (mut g Gen) gen_array_contains_methods() {
} else if elem_sym.kind == .sum_type && left_info.elem_type.nr_muls() == 0 {
ptr_typ := g.equality_fn(left_info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq((($elem_type_str*)a.data)[i], v)) {')
} else if elem_sym.kind == .alias && left_info.elem_type.nr_muls() == 0 {
ptr_typ := g.equality_fn(left_info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq((($elem_type_str*)a.data)[i], v)) {')
} else {
fn_builder.writeln('\t\tif ((($elem_type_str*)a.data)[i] == v) {')
}
@ -757,11 +756,7 @@ fn (mut g Gen) gen_array_index_methods() {
fn_name := '${left_type_str}_index'
info := final_left_sym.info as ast.Array
mut elem_type_str := g.typ(info.elem_type)
mut elem_sym := g.table.sym(info.elem_type)
if elem_sym.kind == .alias {
info_t := elem_sym.info as ast.Alias
elem_sym = g.table.sym(info_t.parent_type)
}
elem_sym := g.table.sym(info.elem_type)
if elem_sym.kind == .function {
left_type_str = 'Array_voidptr'
elem_type_str = 'voidptr'
@ -790,6 +785,9 @@ fn (mut g Gen) gen_array_index_methods() {
} else if elem_sym.kind == .sum_type {
ptr_typ := g.equality_fn(info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(*pelem, v)) {')
} else if elem_sym.kind == .alias {
ptr_typ := g.equality_fn(info.elem_type)
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(*pelem, v)) {')
} else {
fn_builder.writeln('\t\tif (*pelem == v) {')
}

View File

@ -454,25 +454,38 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
// and transform them in a serie of equality comparison
// i.e. `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
is_str := right.elem_type.idx() == ast.string_type_idx
elem_sym := g.table.sym(right.elem_type)
is_array := elem_sym.kind == .array
mut elem_sym := g.table.sym(right.elem_type)
for i, array_expr in right.exprs {
if is_str {
g.write('string__eq(')
} else if is_array {
ptr_typ := g.equality_fn(right.elem_type)
g.write('${ptr_typ}_arr_eq(')
}
g.expr(left)
if is_str || is_array {
g.write(', ')
} else {
g.write(' == ')
}
g.expr(array_expr)
if is_str || is_array {
g.write(')')
match elem_sym.kind {
.string, .alias, .sum_type, .map, .interface_, .array, .struct_ {
if elem_sym.kind == .string {
g.write('string__eq(')
} else {
ptr_typ := g.equality_fn(right.elem_type)
if elem_sym.kind == .alias {
g.write('${ptr_typ}_alias_eq(')
} else if elem_sym.kind == .sum_type {
g.write('${ptr_typ}_sumtype_eq(')
} else if elem_sym.kind == .map {
g.write('${ptr_typ}_map_eq(')
} else if elem_sym.kind == .interface_ {
g.write('${ptr_typ}_interface_eq(')
} else if elem_sym.kind == .array {
g.write('${ptr_typ}_arr_eq(')
} else if elem_sym.kind == .struct_ {
g.write('${ptr_typ}_struct_eq(')
}
}
g.expr(left)
g.write(', ')
g.expr(array_expr)
g.write(')')
}
else { // works in function kind
g.expr(left)
g.write(' == ')
g.expr(array_expr)
}
}
if i < right.exprs.len - 1 {
g.write(' || ')

View File

@ -287,3 +287,25 @@ fn test_in_sumtype_array() {
assert Foo1{} in foos
assert Foo2{} !in foos
}
fn test_in_struct_array() {
assert Foo1{} == Foo1{}
}
fn fn1() {}
fn fn2() {}
fn fn3() {}
fn test_in_func_array() {
assert fn1 in [fn1, fn2, fn3]
}
type Str = string
type Struct = Foo1
fn test_in_alias_array() {
assert Str('') in [Str(''), Str('a')]
assert Struct{} == Struct{}
}