diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8418195ef4..3b52c1c1f9 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4868,6 +4868,22 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.error('.str() methods should have 0 arguments', node.pos) } } + if node.language == .v && node.is_method && node.name in ['+', '-', '*', '%', '/'] { + if node.params.len != 2 { + c.error('operator methods should have exactly 1 argument', node.pos) + } else { + receiver_sym := c.table.get_type_symbol(node.receiver.typ) + param_sym := c.table.get_type_symbol(node.params[1].typ) + if param_sym.kind !in [.struct_, .alias] || receiver_sym.kind !in [.struct_, .alias] { + c.error('operator methods are only allowed for struct and type alias', + node.pos) + } else { + if node.receiver.typ != node.params[1].typ { + c.error('both sides of an operator must be the same type', node.pos) + } + } + } + } // TODO c.pref.is_vet if node.language == .v && !node.is_method && node.params.len == 0 && node.name.after('.').starts_with('test_') { if !c.file.path.ends_with('_test.v') { diff --git a/vlib/v/checker/tests/method_op_err.out b/vlib/v/checker/tests/method_op_err.out new file mode 100644 index 0000000000..f63d6cbc40 --- /dev/null +++ b/vlib/v/checker/tests/method_op_err.out @@ -0,0 +1,20 @@ +vlib/v/checker/tests/method_op_err.vv:11:1: error: operator methods should have exactly 1 argument + 9 | } + 10 | + 11 | fn (u User) + () { + | ~~~~~~~~~~~~~~~~ + 12 | } + 13 | +vlib/v/checker/tests/method_op_err.vv:14:1: error: both sides of an operator must be the same type + 12 | } + 13 | + 14 | fn (u User) - (f Foo) User { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + 15 | return User{u.a - f.a, u.b-f.a} + 16 | } +vlib/v/checker/tests/method_op_err.vv:20:24: error: infix expr: cannot use `Foo` (right expression) as `User` + 18 | fn main() { + 19 | println(User{3, 4}) + 20 | println(User{3, 4} - Foo{3, 3}) + | ^ + 21 | } diff --git a/vlib/v/checker/tests/method_op_err.vv b/vlib/v/checker/tests/method_op_err.vv new file mode 100644 index 0000000000..4e97ce4e4b --- /dev/null +++ b/vlib/v/checker/tests/method_op_err.vv @@ -0,0 +1,21 @@ +struct User { + a int + b int +} + +struct Foo { + a int + b int +} + +fn (u User) + () { +} + +fn (u User) - (f Foo) User { + return User{u.a - f.a, u.b-f.a} +} + +fn main() { + println(User{3, 4}) + println(User{3, 4} - Foo{3, 3}) +}