checker: add more checks for operator overloading (#8030)
parent
1559e72d0d
commit
5a1699dec2
|
@ -5114,7 +5114,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
c.error('.str() methods should have 0 arguments', node.pos)
|
c.error('.str() methods should have 0 arguments', node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.language == .v && node.is_method && node.name in ['+', '-', '*', '%', '/', '<', '>', '==', '!='] {
|
if node.language == .v && node.is_method && node.name in
|
||||||
|
['+', '-', '*', '%', '/', '<', '>', '==', '!=', '>=', '<='] {
|
||||||
if node.params.len != 2 {
|
if node.params.len != 2 {
|
||||||
c.error('operator methods should have exactly 1 argument', node.pos)
|
c.error('operator methods should have exactly 1 argument', node.pos)
|
||||||
} else {
|
} else {
|
||||||
|
@ -5124,7 +5125,11 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
c.error('operator methods are only allowed for struct and type alias',
|
c.error('operator methods are only allowed for struct and type alias',
|
||||||
node.pos)
|
node.pos)
|
||||||
} else {
|
} else {
|
||||||
if node.receiver.typ != node.params[1].typ {
|
if node.rec_mut {
|
||||||
|
c.error('receiver cannot be `mut` for operator overloading', node.receiver_pos)
|
||||||
|
} else if node.params[1].is_mut {
|
||||||
|
c.error('argument cannot be `mut` for operator overloading', 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)
|
c.error('both sides of an operator must be the same type', node.pos)
|
||||||
} else if node.name in ['<', '>', '==', '!=', '>=', '<='] &&
|
} else if node.name in ['<', '>', '==', '!=', '>=', '<='] &&
|
||||||
node.return_type != table.bool_type {
|
node.return_type != table.bool_type {
|
||||||
|
|
|
@ -19,23 +19,37 @@ vlib/v/checker/tests/method_op_err.vv:18:1: error: operator comparison methods s
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
19 | return User{}
|
19 | return User{}
|
||||||
20 | }
|
20 | }
|
||||||
vlib/v/checker/tests/method_op_err.vv:24:24: error: infix expr: cannot use `Foo` (right expression) as `User`
|
vlib/v/checker/tests/method_op_err.vv:22:9: error: receiver cannot be `mut` for operator overloading
|
||||||
22 | fn main() {
|
20 | }
|
||||||
23 | println(User{3, 4})
|
21 |
|
||||||
24 | println(User{3, 4} - Foo{3, 3})
|
22 | fn (mut u User) * (u1 User) User {
|
||||||
|
| ~~~~~~
|
||||||
|
23 | return User{}
|
||||||
|
24 | }
|
||||||
|
vlib/v/checker/tests/method_op_err.vv:26:1: error: argument cannot be `mut` for operator overloading
|
||||||
|
24 | }
|
||||||
|
25 |
|
||||||
|
26 | fn (u User) / (mut u1 User) User {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
27 | return User{}
|
||||||
|
28 | }
|
||||||
|
vlib/v/checker/tests/method_op_err.vv:32:24: error: infix expr: cannot use `Foo` (right expression) as `User`
|
||||||
|
30 | fn main() {
|
||||||
|
31 | println(User{3, 4})
|
||||||
|
32 | println(User{3, 4} - Foo{3, 3})
|
||||||
| ^
|
| ^
|
||||||
25 | println(User{3, 2} < User{2, 4})
|
33 | println(User{3, 2} < User{2, 4})
|
||||||
26 | println(User{3, 4} < Foo{3, 4})
|
34 | println(User{3, 4} < Foo{3, 4})
|
||||||
vlib/v/checker/tests/method_op_err.vv:25:24: error: operation `User` < `User` does not exist, please define it
|
vlib/v/checker/tests/method_op_err.vv:33:24: error: operation `User` < `User` does not exist, please define it
|
||||||
23 | println(User{3, 4})
|
31 | println(User{3, 4})
|
||||||
24 | println(User{3, 4} - Foo{3, 3})
|
32 | println(User{3, 4} - Foo{3, 3})
|
||||||
25 | println(User{3, 2} < User{2, 4})
|
33 | println(User{3, 2} < User{2, 4})
|
||||||
| ^
|
| ^
|
||||||
26 | println(User{3, 4} < Foo{3, 4})
|
34 | println(User{3, 4} < Foo{3, 4})
|
||||||
27 | }
|
35 | }
|
||||||
vlib/v/checker/tests/method_op_err.vv:26:24: error: mismatched types `User` and `Foo`
|
vlib/v/checker/tests/method_op_err.vv:34:24: error: mismatched types `User` and `Foo`
|
||||||
24 | println(User{3, 4} - Foo{3, 3})
|
32 | println(User{3, 4} - Foo{3, 3})
|
||||||
25 | println(User{3, 2} < User{2, 4})
|
33 | println(User{3, 2} < User{2, 4})
|
||||||
26 | println(User{3, 4} < Foo{3, 4})
|
34 | println(User{3, 4} < Foo{3, 4})
|
||||||
| ^
|
| ^
|
||||||
27 | }
|
35 | }
|
||||||
|
|
|
@ -19,6 +19,14 @@ fn (u User) > (u1 User) User {
|
||||||
return User{}
|
return User{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut u User) * (u1 User) User {
|
||||||
|
return User{}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (u User) / (mut u1 User) User {
|
||||||
|
return User{}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println(User{3, 4})
|
println(User{3, 4})
|
||||||
println(User{3, 4} - Foo{3, 3})
|
println(User{3, 4} - Foo{3, 3})
|
||||||
|
|
Loading…
Reference in New Issue