checker: improve message and positioning for operator overloading (#8133)
parent
ee9f9c9d81
commit
ef627c9d21
|
@ -792,7 +792,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
left_name := c.table.type_to_str(left_type)
|
left_name := c.table.type_to_str(left_type)
|
||||||
right_name := c.table.type_to_str(right_type)
|
right_name := c.table.type_to_str(right_type)
|
||||||
if left_name == right_name {
|
if left_name == right_name {
|
||||||
c.error('operation `$left_name` $infix_expr.op.str() `$right_name` does not exist, please define it',
|
c.error('undefined operation `$left_name` $infix_expr.op.str() `$right_name`',
|
||||||
left_pos)
|
left_pos)
|
||||||
} else {
|
} else {
|
||||||
c.error('mismatched types `$left_name` and `$right_name`', left_pos)
|
c.error('mismatched types `$left_name` and `$right_name`', left_pos)
|
||||||
|
@ -809,7 +809,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
left_name := c.table.type_to_str(left_type)
|
left_name := c.table.type_to_str(left_type)
|
||||||
right_name := c.table.type_to_str(right_type)
|
right_name := c.table.type_to_str(right_type)
|
||||||
if left_name == right_name {
|
if left_name == right_name {
|
||||||
c.error('operation `$left_name` $infix_expr.op.str() `$right_name` does not exist, please define it',
|
c.error('undefined operation `$left_name` $infix_expr.op.str() `$right_name`',
|
||||||
right_pos)
|
right_pos)
|
||||||
} else {
|
} else {
|
||||||
c.error('mismatched types `$left_name` and `$right_name`', right_pos)
|
c.error('mismatched types `$left_name` and `$right_name`', right_pos)
|
||||||
|
@ -852,7 +852,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
left_name := c.table.type_to_str(left_type)
|
left_name := c.table.type_to_str(left_type)
|
||||||
right_name := c.table.type_to_str(right_type)
|
right_name := c.table.type_to_str(right_type)
|
||||||
if left_name == right_name {
|
if left_name == right_name {
|
||||||
c.error('operation `$left_name` $infix_expr.op.str() `$right_name` does not exist, please define it',
|
c.error('undefined operation `$left_name` $infix_expr.op.str() `$right_name`',
|
||||||
infix_expr.pos)
|
infix_expr.pos)
|
||||||
} else {
|
} else {
|
||||||
c.error('mismatched types `$left_name` and `$right_name`', infix_expr.pos)
|
c.error('mismatched types `$left_name` and `$right_name`', infix_expr.pos)
|
||||||
|
@ -2600,7 +2600,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
assign_stmt.pos)
|
assign_stmt.pos)
|
||||||
}
|
}
|
||||||
if left_name == right_name {
|
if left_name == right_name {
|
||||||
c.error('operation `$left_name` $extracted_op `$right_name` does not exist, please define it',
|
c.error('undefined operation `$left_name` $extracted_op `$right_name`',
|
||||||
assign_stmt.pos)
|
assign_stmt.pos)
|
||||||
} else {
|
} else {
|
||||||
c.error('mismatched types `$left_name` and `$right_name`', assign_stmt.pos)
|
c.error('mismatched types `$left_name` and `$right_name`', assign_stmt.pos)
|
||||||
|
@ -5227,7 +5227,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
} else if node.params[1].is_mut {
|
} else if node.params[1].is_mut {
|
||||||
c.error('argument cannot be `mut` for operator overloading', node.pos)
|
c.error('argument cannot be `mut` for operator overloading', node.pos)
|
||||||
} else if node.receiver.typ != node.params[1].typ {
|
} 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('expected `$receiver_sym.name` not `$param_sym.name` - both operands must be the same type for operator overloading',
|
||||||
|
node.params[1].type_pos)
|
||||||
} else if node.name in ['<', '>', '==', '!=', '>=', '<='] &&
|
} else if node.name in ['<', '>', '==', '!=', '>=', '<='] &&
|
||||||
node.return_type != table.bool_type
|
node.return_type != table.bool_type
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
vlib/v/checker/tests/method_op_alias_err.vv:4:1: error: both sides of an operator must be the same type
|
vlib/v/checker/tests/method_op_alias_err.vv:4:18: error: expected `Foo` not `Foo2` - both operands must be the same type for operator overloading
|
||||||
2 | type Foo2 = string
|
2 | type Foo2 = string
|
||||||
3 |
|
3 |
|
||||||
4 | fn (f Foo) + (f1 Foo2) Foo2 {
|
4 | fn (f Foo) + (f1 Foo2) Foo2 {
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~
|
||||||
5 | return Foo2(f + f1)
|
5 | return Foo2(f + f1)
|
||||||
6 | }
|
6 | }
|
||||||
vlib/v/checker/tests/method_op_alias_err.vv:5:19: error: infix expr: cannot use `string` (right expression) as `string`
|
vlib/v/checker/tests/method_op_alias_err.vv:5:19: error: infix expr: cannot use `string` (right expression) as `string`
|
||||||
|
|
|
@ -5,11 +5,11 @@ vlib/v/checker/tests/method_op_err.vv:11:1: error: operator methods should have
|
||||||
| ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~
|
||||||
12 | }
|
12 | }
|
||||||
13 |
|
13 |
|
||||||
vlib/v/checker/tests/method_op_err.vv:14:1: error: both sides of an operator must be the same type
|
vlib/v/checker/tests/method_op_err.vv:14:18: error: expected `User` not `Foo` - both operands must be the same type for operator overloading
|
||||||
12 | }
|
12 | }
|
||||||
13 |
|
13 |
|
||||||
14 | fn (u User) - (f Foo) User {
|
14 | fn (u User) - (f Foo) User {
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~
|
||||||
15 | return User{u.a - f.a, u.b-f.a}
|
15 | return User{u.a - f.a, u.b-f.a}
|
||||||
16 | }
|
16 | }
|
||||||
vlib/v/checker/tests/method_op_err.vv:18:1: error: operator comparison methods should return `bool`
|
vlib/v/checker/tests/method_op_err.vv:18:1: error: operator comparison methods should return `bool`
|
||||||
|
@ -40,7 +40,7 @@ vlib/v/checker/tests/method_op_err.vv:36:24: error: infix expr: cannot use `Foo`
|
||||||
| ^
|
| ^
|
||||||
37 | println(User{3, 2} < User{2, 4})
|
37 | println(User{3, 2} < User{2, 4})
|
||||||
38 | println(User{3, 4} < Foo{3, 4})
|
38 | println(User{3, 4} < Foo{3, 4})
|
||||||
vlib/v/checker/tests/method_op_err.vv:37:24: error: operation `User` < `User` does not exist, please define it
|
vlib/v/checker/tests/method_op_err.vv:37:24: error: undefined operation `User` < `User`
|
||||||
35 | println(User{3, 4})
|
35 | println(User{3, 4})
|
||||||
36 | println(User{3, 4} - Foo{3, 3})
|
36 | println(User{3, 4} - Foo{3, 3})
|
||||||
37 | println(User{3, 2} < User{2, 4})
|
37 | println(User{3, 2} < User{2, 4})
|
||||||
|
|
|
@ -609,6 +609,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
|
||||||
}
|
}
|
||||||
mut arg_pos := [p.tok.position()]
|
mut arg_pos := [p.tok.position()]
|
||||||
mut arg_names := [p.check_name()]
|
mut arg_names := [p.check_name()]
|
||||||
|
mut type_pos := [p.tok.position()]
|
||||||
// `a, b, c int`
|
// `a, b, c int`
|
||||||
for p.tok.kind == .comma {
|
for p.tok.kind == .comma {
|
||||||
if !p.pref.is_fmt {
|
if !p.pref.is_fmt {
|
||||||
|
@ -618,6 +619,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
|
||||||
p.next()
|
p.next()
|
||||||
arg_pos << p.tok.position()
|
arg_pos << p.tok.position()
|
||||||
arg_names << p.check_name()
|
arg_names << p.check_name()
|
||||||
|
type_pos << p.tok.position()
|
||||||
}
|
}
|
||||||
if p.tok.kind == .key_mut {
|
if p.tok.kind == .key_mut {
|
||||||
// TODO remove old syntax
|
// TODO remove old syntax
|
||||||
|
@ -665,6 +667,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
|
||||||
name: arg_name
|
name: arg_name
|
||||||
is_mut: is_mut
|
is_mut: is_mut
|
||||||
typ: typ
|
typ: typ
|
||||||
|
type_pos: type_pos[i]
|
||||||
}
|
}
|
||||||
// if typ.typ.kind == .variadic && p.tok.kind == .comma {
|
// if typ.typ.kind == .variadic && p.tok.kind == .comma {
|
||||||
if is_variadic && p.tok.kind == .comma {
|
if is_variadic && p.tok.kind == .comma {
|
||||||
|
|
|
@ -53,6 +53,7 @@ pub:
|
||||||
name string
|
name string
|
||||||
is_mut bool
|
is_mut bool
|
||||||
typ Type
|
typ Type
|
||||||
|
type_pos token.Position
|
||||||
is_hidden bool // interface first arg
|
is_hidden bool // interface first arg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue