From e5839effbca36d777fc4eb241ad698281b9c54fb Mon Sep 17 00:00:00 2001 From: zakuro Date: Mon, 8 Feb 2021 09:41:47 +0900 Subject: [PATCH] checker/cgen: allow `<<` operator for aliases (#8561) --- vlib/v/checker/checker.v | 10 ++++++---- vlib/v/gen/c/cgen.v | 8 +++++--- vlib/v/tests/array_type_alias_test.v | 9 +++++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7c08bd13f8..219586f760 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -756,7 +756,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { // right_type = c.unwrap_genric(c.expr(infix_expr.right)) infix_expr.right_type = right_type mut right := c.table.get_type_symbol(right_type) + right_final := c.table.get_final_type_symbol(right_type) mut left := c.table.get_type_symbol(left_type) + left_final := c.table.get_final_type_symbol(left_type) left_pos := infix_expr.left.position() right_pos := infix_expr.right.position() if (left_type.is_ptr() || left.is_pointer()) && infix_expr.op in [.plus, .minus] { @@ -919,17 +921,17 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { } } .left_shift { - if left.kind == .array { + if left_final.kind == .array { // `array << elm` infix_expr.auto_locked, _ = c.fail_if_immutable(infix_expr.left) left_value_type := c.table.value_type(left_type) left_value_sym := c.table.get_type_symbol(left_value_type) if left_value_sym.kind == .interface_ { - if right.kind != .array { + if right_final.kind != .array { // []Animal << Cat c.type_implements(right_type, left_value_type, right_pos) } else { - // []Animal << Cat + // []Animal << []Cat c.type_implements(c.table.value_type(right_type), left_value_type, right_pos) } @@ -940,7 +942,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { // []T << T return table.void_type } - if right.kind == .array + if right_final.kind == .array && c.check_types(left_value_type, c.table.value_type(right_type)) { // []T << []T return table.void_type diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 26bdef3282..82f85debdd 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3042,6 +3042,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } left_type := g.unwrap_generic(node.left_type) left_sym := g.table.get_type_symbol(left_type) + left_final_sym := g.table.get_final_type_symbol(left_type) unaliased_left := if left_sym.kind == .alias { (left_sym.info as table.Alias).parent_type } else { @@ -3055,6 +3056,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { op_is_key_in_or_not_in := node.op in [.key_in, .not_in] op_is_eq_or_ne := node.op in [.eq, .ne] right_sym := g.table.get_type_symbol(node.right_type) + right_final_sym := g.table.get_final_type_symbol(node.right_type) has_eq_overloaded := !left_sym.has_method('==') unaliased_right := if right_sym.info is table.Alias { right_sym.info.parent_type @@ -3289,11 +3291,11 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.expr(node.left) g.write(')') } - } else if node.op == .left_shift && left_sym.kind == .array { + } else if node.op == .left_shift && left_final_sym.kind == .array { // arr << val tmp := g.new_tmp_var() - info := left_sym.info as table.Array - if right_sym.kind == .array && info.elem_type != node.right_type { + info := left_final_sym.info as table.Array + if right_final_sym.kind == .array && info.elem_type != node.right_type { // push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`) g.write('_PUSH_MANY(') mut expected_push_many_atype := left_type diff --git a/vlib/v/tests/array_type_alias_test.v b/vlib/v/tests/array_type_alias_test.v index 17ee8d62ec..ca6b693e11 100644 --- a/vlib/v/tests/array_type_alias_test.v +++ b/vlib/v/tests/array_type_alias_test.v @@ -1,6 +1,11 @@ type Test = []int fn test_index() { - t := Test([2,4]) - assert t[1] == 4 + mut t := Test([2, 4]) + assert t[1] == 4 + assert t == Test([2, 4]) + t << 6 + assert t == Test([2, 4, 6]) + t << Test([8, 10]) + assert t == Test([2, 4, 6, 8, 10]) }