From 09797e493efba713a405983d5239218bb74ec975 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 20 Jan 2022 14:57:25 +0800 Subject: [PATCH] checker: check generics undefined operation of infix expression (#13223) --- vlib/v/checker/checker.v | 26 +++++++------------ .../tests/generics_undefined_operation.out | 7 +++++ .../tests/generics_undefined_operation.vv | 14 ++++++++++ 3 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 vlib/v/checker/tests/generics_undefined_operation.out create mode 100644 vlib/v/checker/tests/generics_undefined_operation.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index f9b77b10cd..c1f02725cf 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -679,31 +679,25 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } } if left_sym.kind in [.array, .array_fixed, .map, .struct_] { - if left_sym.has_method(node.op.str()) { - if method := left_sym.find_method(node.op.str()) { + if left_sym.has_method_with_generic_parent(node.op.str()) { + if method := left_sym.find_method_with_generic_parent(node.op.str()) { return_type = method.return_type } else { return_type = left_type } } else { - if left_sym.kind == .struct_ - && (left_sym.info as ast.Struct).generic_types.len > 0 { - return_type = left_type + left_name := c.table.type_to_str(left_type) + right_name := c.table.type_to_str(right_type) + if left_name == right_name { + c.error('undefined operation `$left_name` $node.op.str() `$right_name`', + left_right_pos) } else { - left_name := c.table.type_to_str(left_type) - right_name := c.table.type_to_str(right_type) - if left_name == right_name { - c.error('undefined operation `$left_name` $node.op.str() `$right_name`', - left_right_pos) - } else { - c.error('mismatched types `$left_name` and `$right_name`', - left_right_pos) - } + c.error('mismatched types `$left_name` and `$right_name`', left_right_pos) } } } else if right_sym.kind in [.array, .array_fixed, .map, .struct_] { - if right_sym.has_method(node.op.str()) { - if method := right_sym.find_method(node.op.str()) { + if right_sym.has_method_with_generic_parent(node.op.str()) { + if method := right_sym.find_method_with_generic_parent(node.op.str()) { return_type = method.return_type } else { return_type = right_type diff --git a/vlib/v/checker/tests/generics_undefined_operation.out b/vlib/v/checker/tests/generics_undefined_operation.out new file mode 100644 index 0000000000..49ed8004e4 --- /dev/null +++ b/vlib/v/checker/tests/generics_undefined_operation.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/generics_undefined_operation.vv:12:5: error: undefined operation `V2d` * `V2d` + 10 | v3 := V2d{4, 6} + 11 | + 12 | if v1 * v2 == v3 { + | ~~~~~~~ + 13 | } + 14 | } diff --git a/vlib/v/checker/tests/generics_undefined_operation.vv b/vlib/v/checker/tests/generics_undefined_operation.vv new file mode 100644 index 0000000000..28184f2640 --- /dev/null +++ b/vlib/v/checker/tests/generics_undefined_operation.vv @@ -0,0 +1,14 @@ +struct V2d { +mut: + x T + y T +} + +fn main() { + v1 := V2d{2, 2} + v2 := V2d{2, 3} + v3 := V2d{4, 6} + + if v1 * v2 == v3 { + } +}