checker/cgen: implement in expression for alias of array/map (#9871)

pull/9876/head
zakuro 2021-04-26 00:17:54 +09:00 committed by GitHub
parent 160b605640
commit a0835ac139
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 5 deletions

View File

@ -786,9 +786,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type {
} }
} }
.key_in, .not_in { .key_in, .not_in {
match right.kind { match right_final.kind {
.array { .array {
elem_type := right.array_info().elem_type elem_type := right_final.array_info().elem_type
// if left_default.kind != right_sym.kind { // if left_default.kind != right_sym.kind {
c.check_expected(left_type, elem_type) or { c.check_expected(left_type, elem_type) or {
c.error('left operand to `$infix_expr.op` does not match the array element type: $err.msg', c.error('left operand to `$infix_expr.op` does not match the array element type: $err.msg',
@ -796,7 +796,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type {
} }
} }
.map { .map {
map_info := right.map_info() map_info := right_final.map_info()
c.check_expected(left_type, map_info.key_type) or { c.check_expected(left_type, map_info.key_type) or {
c.error('left operand to `$infix_expr.op` does not match the map key type: $err.msg', c.error('left operand to `$infix_expr.op` does not match the map key type: $err.msg',
left_right_pos) left_right_pos)

View File

@ -454,10 +454,11 @@ fn (mut g Gen) gen_array_prepend(node ast.CallExpr) {
fn (mut g Gen) gen_array_contains_method(left_type ast.Type) string { fn (mut g Gen) gen_array_contains_method(left_type ast.Type) string {
mut left_sym := g.table.get_type_symbol(left_type) mut left_sym := g.table.get_type_symbol(left_type)
left_final_sym := g.table.get_final_type_symbol(left_type)
mut left_type_str := g.typ(left_type).replace('*', '') mut left_type_str := g.typ(left_type).replace('*', '')
fn_name := '${left_type_str}_contains' fn_name := '${left_type_str}_contains'
if !left_sym.has_method('contains') { if !left_sym.has_method('contains') {
left_info := left_sym.info as ast.Array left_info := left_final_sym.info as ast.Array
mut elem_type_str := g.typ(left_info.elem_type) mut elem_type_str := g.typ(left_info.elem_type)
elem_sym := g.table.get_type_symbol(left_info.elem_type) elem_sym := g.table.get_type_symbol(left_info.elem_type)
if elem_sym.kind == .function { if elem_sym.kind == .function {

View File

@ -3640,7 +3640,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
&& left_sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type] { && left_sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type] {
g.infix_gen_equality(node, left_type, left_sym, right_sym) g.infix_gen_equality(node, left_type, left_sym, right_sym)
} else if op_is_key_in_or_not_in { } else if op_is_key_in_or_not_in {
g.infix_in_or_not_in(node, left_sym, right_sym) g.infix_in_or_not_in(node, left_final_sym, right_final_sym)
} else if node.op == .left_shift && left_final_sym.kind == .array { } else if node.op == .left_shift && left_final_sym.kind == .array {
// arr << val // arr << val
tmp := g.new_tmp_var() tmp := g.new_tmp_var()

View File

@ -107,6 +107,23 @@ fn test_in_expression_with_string() {
assert a == false assert a == false
} }
type MapAlias = map[string]int
type ArrayAlias = []int
fn test_in_expression_in_alias() {
arr := ArrayAlias([0, 1])
assert 0 in arr
assert 100 !in arr
m := MapAlias(map{
'one': 1
'two': 2
'three': 3
})
assert 'one' in m
assert 'four' !in m
}
fn test_in_expression_in_map() { fn test_in_expression_in_map() {
m := map{ m := map{
'one': 1 'one': 1