checker: add checks for operator overloading (#7737)
parent
5597925d58
commit
a834f33661
|
@ -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') {
|
||||
|
|
|
@ -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 | }
|
|
@ -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})
|
||||
}
|
Loading…
Reference in New Issue