From a0835ac139de7f70f935e61f5939c5ccec0c8a51 Mon Sep 17 00:00:00 2001 From: zakuro Date: Mon, 26 Apr 2021 00:17:54 +0900 Subject: [PATCH] checker/cgen: implement in expression for alias of array/map (#9871) --- vlib/v/checker/checker.v | 6 +++--- vlib/v/gen/c/array.v | 3 ++- vlib/v/gen/c/cgen.v | 2 +- vlib/v/tests/in_expression_test.v | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 5cdf7c7293..6c09926407 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -786,9 +786,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type { } } .key_in, .not_in { - match right.kind { + match right_final.kind { .array { - elem_type := right.array_info().elem_type + elem_type := right_final.array_info().elem_type // if left_default.kind != right_sym.kind { 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', @@ -796,7 +796,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type { } } .map { - map_info := right.map_info() + map_info := right_final.map_info() 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', left_right_pos) diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 9f1d2e8353..3fb1d519d8 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -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 { 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('*', '') fn_name := '${left_type_str}_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) elem_sym := g.table.get_type_symbol(left_info.elem_type) if elem_sym.kind == .function { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d3badbda31..8fbac4be7b 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -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] { g.infix_gen_equality(node, left_type, left_sym, right_sym) } 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 { // arr << val tmp := g.new_tmp_var() diff --git a/vlib/v/tests/in_expression_test.v b/vlib/v/tests/in_expression_test.v index 9a4d363087..356fed7f46 100644 --- a/vlib/v/tests/in_expression_test.v +++ b/vlib/v/tests/in_expression_test.v @@ -107,6 +107,23 @@ fn test_in_expression_with_string() { 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() { m := map{ 'one': 1