checker: improve 'operator not defined on right operand type' error (#7185)

pull/7187/head
Nick Treleaven 2020-12-07 17:37:17 +00:00 committed by GitHub
parent 744a36ed71
commit a100b05647
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 24 deletions

View File

@ -2218,28 +2218,27 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
// Single side check
match assign_stmt.op {
.assign {} // No need to do single side check for =. But here put it first for speed.
.plus_assign {
if !left_sym.is_number() && left_type != table.string_type && !left_sym.is_pointer() {
c.error('operator += not defined on left operand type `$left_sym.name`',
left.position())
} else if !right_sym.is_number() && right_type != table.string_type && !right_sym.is_pointer() {
c.error('operator += not defined on right operand type `$right_sym.name`',
right.position())
}
if right is ast.IntegerLiteral && right.str().int() == 1 {
c.error('use `++` instead of `+= 1`', assign_stmt.pos)
}
}
.minus_assign {
if !left_sym.is_number() && !left_sym.is_pointer() {
c.error('operator -= not defined on left operand type `$left_sym.name`',
.plus_assign, .minus_assign {
if left_type == table.string_type {
if assign_stmt.op != .plus_assign {
c.error('operator `$assign_stmt.op` not defined on left operand type `$left_sym.name`',
left.position())
}
if right_type != table.string_type {
c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name',
right.position())
}
} else if !left_sym.is_number() && !left_sym.is_pointer() {
c.error('operator `$assign_stmt.op` not defined on left operand type `$left_sym.name`',
left.position())
} else if !right_sym.is_number() && !right_sym.is_pointer() {
c.error('operator -= not defined on right operand type `$right_sym.name`',
c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name',
right.position())
}
if right is ast.IntegerLiteral && right.str().int() == 1 {
c.error('use `--` instead of `-= 1`', assign_stmt.pos)
} else if right is ast.IntegerLiteral {
if right.val == '1' {
op := if assign_stmt.op == .plus_assign { token.Kind.inc } else { token.Kind.dec }
c.error('use `$op` instead of `$assign_stmt.op 1`', assign_stmt.pos)
}
}
}
.mult_assign, .div_assign {

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/assign_expr_type_err_e.vv:3:2: error: operator -= not defined on left operand type `string`
vlib/v/checker/tests/assign_expr_type_err_e.vv:3:2: error: operator `-=` not defined on left operand type `string`
1 | fn main() {
2 | mut foo := 'hello'
3 | foo -= `a`

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/assign_expr_type_err_f.vv:3:9: error: operator -= not defined on right operand type `bool`
vlib/v/checker/tests/assign_expr_type_err_f.vv:3:9: error: invalid right operand: int -= bool
1 | fn main() {
2 | mut foo := 10
3 | foo -= false

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/assign_expr_type_err_g.vv:3:2: error: operator += not defined on left operand type `bool`
vlib/v/checker/tests/assign_expr_type_err_g.vv:3:2: error: operator `+=` not defined on left operand type `bool`
1 | fn main() {
2 | mut foo := true
3 | foo += false

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/assign_expr_type_err_h.vv:3:9: error: operator += not defined on right operand type `bool`
vlib/v/checker/tests/assign_expr_type_err_h.vv:3:9: error: invalid right operand: string += bool
1 | fn main() {
2 | mut foo := 'hello'
3 | foo += false

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/assign_expr_type_err_i.vv:3:9: error: cannot assign to `foo`: expected `f64`, not `string`
vlib/v/checker/tests/assign_expr_type_err_i.vv:3:9: error: invalid right operand: f64 += string
1 | fn main() {
2 | mut foo := 1.5
3 | foo += 'hello'