From 95d2c58148e16e810609bb69d75c3b31a9a20af4 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 16 Oct 2022 20:27:40 +0300 Subject: [PATCH] checker: produce more informative error messages on ~,!,-,<- operator type mismatches --- vlib/v/checker/checker.v | 18 ++++--- .../tests/arrow_op_wrong_right_type_err_b.out | 2 +- .../tests/invert_other_types_bits_error.out | 52 +++++++++---------- .../checker/tests/minus_op_wrong_type_err.out | 6 +-- vlib/v/checker/tests/prefix_err.out | 6 +-- 5 files changed, 45 insertions(+), 39 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c16ec82887..4529f8e8b2 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3415,42 +3415,48 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type { return right_type.ref() } } + right_sym := c.table.final_sym(c.unwrap_generic(right_type)) if node.op == .mul { if right_type.is_ptr() { return right_type.deref() } if !right_type.is_pointer() && !c.pref.translated && !c.file.is_translated { 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() { c.error('cannot dereference to void', node.pos) } } 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 && !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 // there are currently other issues to investigate if right_type // 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() { - 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 right_sym.kind == .chan { c.stmts_ending_with_expression(node.or_block.stmts) 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 } +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) { index_type_sym := c.table.sym(index_type) if typ_sym.kind in [.array, .array_fixed, .string] { diff --git a/vlib/v/checker/tests/arrow_op_wrong_right_type_err_b.out b/vlib/v/checker/tests/arrow_op_wrong_right_type_err_b.out index ae9be3877a..f5f39f855a 100644 --- a/vlib/v/checker/tests/arrow_op_wrong_right_type_err_b.out +++ b/vlib/v/checker/tests/arrow_op_wrong_right_type_err_b.out @@ -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() { 2 | ch := i64(3) 3 | obj := <-ch diff --git a/vlib/v/checker/tests/invert_other_types_bits_error.out b/vlib/v/checker/tests/invert_other_types_bits_error.out index c6989bae0a..22189f5ceb 100644 --- a/vlib/v/checker/tests/invert_other_types_bits_error.out +++ b/vlib/v/checker/tests/invert_other_types_bits_error.out @@ -1,26 +1,26 @@ -vlib/v/checker/tests/invert_other_types_bits_error.vv:2:13: error: operator ~ only defined on int types - 1 | fn main() { - 2 | println(~3.0) - | ^ - 3 | println(~10.5) - 4 | println(~'2') -vlib/v/checker/tests/invert_other_types_bits_error.vv:3:13: error: operator ~ only defined on int types - 1 | fn main() { - 2 | println(~3.0) - 3 | println(~10.5) - | ^ - 4 | println(~'2') - 5 | println(~[2, 4, 6]) -vlib/v/checker/tests/invert_other_types_bits_error.vv:4:13: error: operator ~ only defined on int types - 2 | println(~3.0) - 3 | println(~10.5) - 4 | println(~'2') - | ^ - 5 | println(~[2, 4, 6]) - 6 | } -vlib/v/checker/tests/invert_other_types_bits_error.vv:5:13: error: operator ~ only defined on int types - 3 | println(~10.5) - 4 | println(~'2') - 5 | println(~[2, 4, 6]) - | ^ - 6 | } +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() { + 2 | println(~3.0) + | ^ + 3 | println(~10.5) + 4 | println(~'2') +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() { + 2 | println(~3.0) + 3 | println(~10.5) + | ^ + 4 | println(~'2') + 5 | println(~[2, 4, 6]) +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) + 3 | println(~10.5) + 4 | println(~'2') + | ^ + 5 | println(~[2, 4, 6]) + 6 | } +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) + 4 | println(~'2') + 5 | println(~[2, 4, 6]) + | ^ + 6 | } diff --git a/vlib/v/checker/tests/minus_op_wrong_type_err.out b/vlib/v/checker/tests/minus_op_wrong_type_err.out index cad020716d..802d7aef8b 100644 --- a/vlib/v/checker/tests/minus_op_wrong_type_err.out +++ b/vlib/v/checker/tests/minus_op_wrong_type_err.out @@ -40,21 +40,21 @@ vlib/v/checker/tests/minus_op_wrong_type_err.vv:16:10: error: mismatched types ` | ~~~~~~ 17 | println(-Aaa{}) 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) 16 | println(10 - a) 17 | println(-Aaa{}) | ^ 18 | println(-a) 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) 17 | println(-Aaa{}) 18 | println(-a) | ^ 19 | println(-Color.red) 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{}) 18 | println(-a) 19 | println(-Color.red) diff --git a/vlib/v/checker/tests/prefix_err.out b/vlib/v/checker/tests/prefix_err.out index 528ddd0126..b2a9a94e18 100644 --- a/vlib/v/checker/tests/prefix_err.out +++ b/vlib/v/checker/tests/prefix_err.out @@ -68,7 +68,7 @@ vlib/v/checker/tests/prefix_err.vv:14:6: error: cannot take the address of 1 + 2 | ^ 15 | _ := 12.3 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 | 17 | a := 1 18 | _ = *a @@ -82,13 +82,13 @@ vlib/v/checker/tests/prefix_err.vv:19:1: error: cannot push on non-channel `int` | ^ 20 | 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 20 | 21 | _ = ~true | ^ 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 | 21 | _ = ~true 22 | _ = !4