1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: produce more informative error messages on ~,!,-,<- operator type mismatches

This commit is contained in:
Delyan Angelov
2022-10-16 20:27:40 +03:00
parent 3d2e251bf2
commit 95d2c58148
5 changed files with 45 additions and 39 deletions

View File

@ -3415,42 +3415,48 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
return right_type.ref() return right_type.ref()
} }
} }
right_sym := c.table.final_sym(c.unwrap_generic(right_type))
if node.op == .mul { if node.op == .mul {
if right_type.is_ptr() { if right_type.is_ptr() {
return right_type.deref() return right_type.deref()
} }
if !right_type.is_pointer() && !c.pref.translated && !c.file.is_translated { if !right_type.is_pointer() && !c.pref.translated && !c.file.is_translated {
s := c.table.type_to_str(right_type) s := c.table.type_to_str(right_type)
c.error('invalid indirect of `$s`', node.pos) c.error('invalid indirect of `$s`, the type `$right_sym.name` is not a pointer',
node.pos)
} }
if right_type.is_voidptr() { if right_type.is_voidptr() {
c.error('cannot dereference to void', node.pos) c.error('cannot dereference to void', node.pos)
} }
} }
if node.op == .bit_not && !right_type.is_int() && !c.pref.translated && !c.file.is_translated { if node.op == .bit_not && !right_type.is_int() && !c.pref.translated && !c.file.is_translated {
c.error('operator ~ only defined on int types', node.pos) c.type_error_for_operator('~', 'integer', right_sym.name, node.pos)
} }
if node.op == .not && right_type != ast.bool_type_idx && !c.pref.translated if node.op == .not && right_type != ast.bool_type_idx && !c.pref.translated
&& !c.file.is_translated { && !c.file.is_translated {
c.error('! operator can only be used with bool types', node.pos) c.type_error_for_operator('!', 'bool', right_sym.name, node.pos)
} }
// FIXME // FIXME
// there are currently other issues to investigate if right_type // there are currently other issues to investigate if right_type
// is unwraped directly as initialization, so do it here // is unwraped directly as initialization, so do it here
right_sym := c.table.final_sym(c.unwrap_generic(right_type))
if node.op == .minus && !right_sym.is_number() { if node.op == .minus && !right_sym.is_number() {
c.error('- operator can only be used with numeric types', node.pos) c.type_error_for_operator('-', 'numeric', right_sym.name, node.pos)
} }
if node.op == .arrow { if node.op == .arrow {
if right_sym.kind == .chan { if right_sym.kind == .chan {
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(node.or_block.stmts)
return right_sym.chan_info().elem_type return right_sym.chan_info().elem_type
} }
c.error('<- operator can only be used with `chan` types', node.pos) c.type_error_for_operator('<-', '`chan`', right_sym.name, node.pos)
} }
return right_type return right_type
} }
fn (mut c Checker) type_error_for_operator(op_label string, types_label string, found_type_label string, pos token.Pos) {
c.error('operator `$op_label` can only be used with $types_label types, but the value after `$op_label` is of type `$found_type_label` instead',
pos)
}
fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_type ast.Type, pos token.Pos, range_index bool, is_gated bool) { fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_type ast.Type, pos token.Pos, range_index bool, is_gated bool) {
index_type_sym := c.table.sym(index_type) index_type_sym := c.table.sym(index_type)
if typ_sym.kind in [.array, .array_fixed, .string] { if typ_sym.kind in [.array, .array_fixed, .string] {

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/arrow_op_wrong_right_type_err_b.vv:3:9: error: <- operator can only be used with `chan` types vlib/v/checker/tests/arrow_op_wrong_right_type_err_b.vv:3:9: error: operator `<-` can only be used with `chan` types, but the value after `<-` is of type `i64` instead
1 | fn main() { 1 | fn main() {
2 | ch := i64(3) 2 | ch := i64(3)
3 | obj := <-ch 3 | obj := <-ch

View File

@ -1,24 +1,24 @@
vlib/v/checker/tests/invert_other_types_bits_error.vv:2:13: error: operator ~ only defined on int types vlib/v/checker/tests/invert_other_types_bits_error.vv:2:13: error: operator `~` can only be used with integer types, but the value after `~` is of type `float literal` instead
1 | fn main() { 1 | fn main() {
2 | println(~3.0) 2 | println(~3.0)
| ^ | ^
3 | println(~10.5) 3 | println(~10.5)
4 | println(~'2') 4 | println(~'2')
vlib/v/checker/tests/invert_other_types_bits_error.vv:3:13: error: operator ~ only defined on int types vlib/v/checker/tests/invert_other_types_bits_error.vv:3:13: error: operator `~` can only be used with integer types, but the value after `~` is of type `float literal` instead
1 | fn main() { 1 | fn main() {
2 | println(~3.0) 2 | println(~3.0)
3 | println(~10.5) 3 | println(~10.5)
| ^ | ^
4 | println(~'2') 4 | println(~'2')
5 | println(~[2, 4, 6]) 5 | println(~[2, 4, 6])
vlib/v/checker/tests/invert_other_types_bits_error.vv:4:13: error: operator ~ only defined on int types vlib/v/checker/tests/invert_other_types_bits_error.vv:4:13: error: operator `~` can only be used with integer types, but the value after `~` is of type `string` instead
2 | println(~3.0) 2 | println(~3.0)
3 | println(~10.5) 3 | println(~10.5)
4 | println(~'2') 4 | println(~'2')
| ^ | ^
5 | println(~[2, 4, 6]) 5 | println(~[2, 4, 6])
6 | } 6 | }
vlib/v/checker/tests/invert_other_types_bits_error.vv:5:13: error: operator ~ only defined on int types vlib/v/checker/tests/invert_other_types_bits_error.vv:5:13: error: operator `~` can only be used with integer types, but the value after `~` is of type `[]int` instead
3 | println(~10.5) 3 | println(~10.5)
4 | println(~'2') 4 | println(~'2')
5 | println(~[2, 4, 6]) 5 | println(~[2, 4, 6])

View File

@ -40,21 +40,21 @@ vlib/v/checker/tests/minus_op_wrong_type_err.vv:16:10: error: mismatched types `
| ~~~~~~ | ~~~~~~
17 | println(-Aaa{}) 17 | println(-Aaa{})
18 | println(-a) 18 | println(-a)
vlib/v/checker/tests/minus_op_wrong_type_err.vv:17:10: error: - operator can only be used with numeric types vlib/v/checker/tests/minus_op_wrong_type_err.vv:17:10: error: operator `-` can only be used with numeric types, but the value after `-` is of type `Aaa` instead
15 | println(a - 10) 15 | println(a - 10)
16 | println(10 - a) 16 | println(10 - a)
17 | println(-Aaa{}) 17 | println(-Aaa{})
| ^ | ^
18 | println(-a) 18 | println(-a)
19 | println(-Color.red) 19 | println(-Color.red)
vlib/v/checker/tests/minus_op_wrong_type_err.vv:18:10: error: - operator can only be used with numeric types vlib/v/checker/tests/minus_op_wrong_type_err.vv:18:10: error: operator `-` can only be used with numeric types, but the value after `-` is of type `map[string]int` instead
16 | println(10 - a) 16 | println(10 - a)
17 | println(-Aaa{}) 17 | println(-Aaa{})
18 | println(-a) 18 | println(-a)
| ^ | ^
19 | println(-Color.red) 19 | println(-Color.red)
20 | } 20 | }
vlib/v/checker/tests/minus_op_wrong_type_err.vv:19:10: error: - operator can only be used with numeric types vlib/v/checker/tests/minus_op_wrong_type_err.vv:19:10: error: operator `-` can only be used with numeric types, but the value after `-` is of type `Color` instead
17 | println(-Aaa{}) 17 | println(-Aaa{})
18 | println(-a) 18 | println(-a)
19 | println(-Color.red) 19 | println(-Color.red)

View File

@ -68,7 +68,7 @@ vlib/v/checker/tests/prefix_err.vv:14:6: error: cannot take the address of 1 + 2
| ^ | ^
15 | _ := 12.3 15 | _ := 12.3
16 | 16 |
vlib/v/checker/tests/prefix_err.vv:18:5: error: invalid indirect of `int` vlib/v/checker/tests/prefix_err.vv:18:5: error: invalid indirect of `int`, the type `int` is not a pointer
16 | 16 |
17 | a := 1 17 | a := 1
18 | _ = *a 18 | _ = *a
@ -82,13 +82,13 @@ vlib/v/checker/tests/prefix_err.vv:19:1: error: cannot push on non-channel `int`
| ^ | ^
20 | 20 |
21 | _ = ~true 21 | _ = ~true
vlib/v/checker/tests/prefix_err.vv:21:5: error: operator ~ only defined on int types vlib/v/checker/tests/prefix_err.vv:21:5: error: operator `~` can only be used with integer types, but the value after `~` is of type `bool` instead
19 | a <- 4 19 | a <- 4
20 | 20 |
21 | _ = ~true 21 | _ = ~true
| ^ | ^
22 | _ = !4 22 | _ = !4
vlib/v/checker/tests/prefix_err.vv:22:5: error: ! operator can only be used with bool types vlib/v/checker/tests/prefix_err.vv:22:5: error: operator `!` can only be used with bool types, but the value after `!` is of type `int literal` instead
20 | 20 |
21 | _ = ~true 21 | _ = ~true
22 | _ = !4 22 | _ = !4