From 3b6045865b0f6ed489a77d953021ef5922428301 Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 12 Jun 2021 14:15:25 +0200 Subject: [PATCH] checker: improve error message when using fields as methods (#10367) --- vlib/v/checker/checker.v | 8 ++++++-- vlib/v/checker/tests/filter_on_non_arr_err.out | 2 +- .../checker/tests/no_method_on_interface_propagation.out | 4 ++-- vlib/v/checker/tests/unknown_field.out | 2 +- vlib/v/checker/tests/unknown_method.out | 2 +- vlib/v/checker/tests/unknown_method_suggest_name.out | 2 +- .../v/checker/tests/unknown_struct_field_suggest_name.out | 2 +- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 42ea814576..ee346066ae 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1730,7 +1730,11 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type { call_expr.receiver_type = left_type left_type_sym := c.table.get_type_symbol(c.unwrap_generic(left_type)) method_name := call_expr.name - mut unknown_method_msg := 'unknown method: `${left_type_sym.name}.$method_name`' + mut unknown_method_msg := if field := c.table.find_field(left_type_sym, method_name) { + 'unknown method `$field.name` did you mean to access the field with the same name instead?' + } else { + 'unknown method or field: `${left_type_sym.name}.$method_name`' + } if left_type.has_flag(.optional) { c.error('optional type cannot be called directly', call_expr.left.position()) return ast.void_type @@ -2896,7 +2900,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { return ast.u32_type } } - mut unknown_field_msg := 'type `$sym.name` has no field or method `$field_name`' + mut unknown_field_msg := 'type `$sym.name` has no field named `$field_name`' mut has_field := false mut field := ast.StructField{} if field_name.len > 0 && field_name[0].is_capital() && sym.info is ast.Struct diff --git a/vlib/v/checker/tests/filter_on_non_arr_err.out b/vlib/v/checker/tests/filter_on_non_arr_err.out index 5716e571ef..d01f0fd2e4 100644 --- a/vlib/v/checker/tests/filter_on_non_arr_err.out +++ b/vlib/v/checker/tests/filter_on_non_arr_err.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/filter_on_non_arr_err.vv:2:14: error: unknown method: `string.filter` +vlib/v/checker/tests/filter_on_non_arr_err.vv:2:14: error: unknown method or field: `string.filter` 1 | fn main() { 2 | _ := 'test'.filter(it == `t`) | ~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/no_method_on_interface_propagation.out b/vlib/v/checker/tests/no_method_on_interface_propagation.out index 03e11baa9b..b55e1d4e06 100644 --- a/vlib/v/checker/tests/no_method_on_interface_propagation.out +++ b/vlib/v/checker/tests/no_method_on_interface_propagation.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/no_method_on_interface_propagation.vv:18:5: error: unknown method: `Cat.foo` +vlib/v/checker/tests/no_method_on_interface_propagation.vv:18:5: error: unknown method or field: `Cat.foo` 16 | a := new_animal('persian') 17 | if a is Cat { 18 | a.foo() | ~~~~~ 19 | } - 20 | } \ No newline at end of file + 20 | } diff --git a/vlib/v/checker/tests/unknown_field.out b/vlib/v/checker/tests/unknown_field.out index 4596830351..395eedff82 100644 --- a/vlib/v/checker/tests/unknown_field.out +++ b/vlib/v/checker/tests/unknown_field.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/unknown_field.vv:7:12: error: type `Test` has no field or method `sdd` +vlib/v/checker/tests/unknown_field.vv:7:12: error: type `Test` has no field named `sdd` 5 | fn main() { 6 | t := Test{} 7 | println(t.sdd) diff --git a/vlib/v/checker/tests/unknown_method.out b/vlib/v/checker/tests/unknown_method.out index 2a29e0a718..037d2f382e 100644 --- a/vlib/v/checker/tests/unknown_method.out +++ b/vlib/v/checker/tests/unknown_method.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/unknown_method.vv:7:12: error: unknown method: `Test.sdd` +vlib/v/checker/tests/unknown_method.vv:7:12: error: unknown method or field: `Test.sdd` 5 | fn main() { 6 | t := Test{} 7 | println(t.sdd()) diff --git a/vlib/v/checker/tests/unknown_method_suggest_name.out b/vlib/v/checker/tests/unknown_method_suggest_name.out index a6fa8b7f3e..aadc8f40a7 100644 --- a/vlib/v/checker/tests/unknown_method_suggest_name.out +++ b/vlib/v/checker/tests/unknown_method_suggest_name.out @@ -6,7 +6,7 @@ Did you mean `crc32.Crc32`? | ~~~~~ 14 | } 15 | -vlib/v/checker/tests/unknown_method_suggest_name.vv:27:9: error: unknown method: `Point.tranzlate`. +vlib/v/checker/tests/unknown_method_suggest_name.vv:27:9: error: unknown method or field: `Point.tranzlate`. Did you mean `translate`? 25 | p := Point{1, 2, 3} 26 | v := Vector{x: 5, y: 5, z: 10} diff --git a/vlib/v/checker/tests/unknown_struct_field_suggest_name.out b/vlib/v/checker/tests/unknown_struct_field_suggest_name.out index cc4d87077e..8efbe047ae 100644 --- a/vlib/v/checker/tests/unknown_struct_field_suggest_name.out +++ b/vlib/v/checker/tests/unknown_struct_field_suggest_name.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/unknown_struct_field_suggest_name.vv:11:16: error: type `Points` has no field or method `xxxa`. +vlib/v/checker/tests/unknown_struct_field_suggest_name.vv:11:16: error: type `Points` has no field named `xxxa`. Did you mean `xxxx`? 9 | p := Points{[1], [2], [3]} 10 | println('p: $p')