diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8dba4047f2..8accfc7f18 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1849,9 +1849,9 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok styp := c.table.type_to_str(typ) for imethod in inter_sym.methods { if method := typ_sym.find_method(imethod.name) { - if !imethod.is_same_method_as(method) { - sig := c.table.fn_signature(imethod, skip_receiver: true) - c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`, expected `$sig`', + msg := c.table.is_same_method(imethod, method) + if msg.len > 0 { + c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`: $msg', pos) return false } diff --git a/vlib/v/checker/tests/unimplemented_interface_b.out b/vlib/v/checker/tests/unimplemented_interface_b.out index a0d4b902a6..9a95f12bf7 100644 --- a/vlib/v/checker/tests/unimplemented_interface_b.out +++ b/vlib/v/checker/tests/unimplemented_interface_b.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/unimplemented_interface_b.vv:13:6: error: `Cat` incorrectly implements method `name` of interface `Animal`, expected `name() string` +vlib/v/checker/tests/unimplemented_interface_b.vv:13:6: error: `Cat` incorrectly implements method `name` of interface `Animal`: expected return type `string` 11 | fn main() { 12 | c := Cat{} 13 | foo(c) diff --git a/vlib/v/checker/tests/unimplemented_interface_c.out b/vlib/v/checker/tests/unimplemented_interface_c.out index e8685dcde9..6c88e28201 100644 --- a/vlib/v/checker/tests/unimplemented_interface_c.out +++ b/vlib/v/checker/tests/unimplemented_interface_c.out @@ -1,5 +1,5 @@ -vlib/v/checker/tests/unimplemented_interface_c.vv:12:6: error: `Cat` incorrectly implements method `name` of interface `Animal`, expected `name()` - 10 | +vlib/v/checker/tests/unimplemented_interface_c.vv:12:6: error: `Cat` incorrectly implements method `name` of interface `Animal`: expected 1 parameter(s), not 2 + 10 | 11 | fn main() { 12 | foo(Cat{}) | ~~~~~ diff --git a/vlib/v/checker/tests/unimplemented_interface_d.out b/vlib/v/checker/tests/unimplemented_interface_d.out index 19afc42c01..506f7f51b0 100644 --- a/vlib/v/checker/tests/unimplemented_interface_d.out +++ b/vlib/v/checker/tests/unimplemented_interface_d.out @@ -1,5 +1,5 @@ -vlib/v/checker/tests/unimplemented_interface_d.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`, expected `speak(s string)` - 10 | +vlib/v/checker/tests/unimplemented_interface_d.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`: expected 2 parameter(s), not 1 + 10 | 11 | fn main() { 12 | foo(Cat{}) | ~~~~~ diff --git a/vlib/v/checker/tests/unimplemented_interface_e.out b/vlib/v/checker/tests/unimplemented_interface_e.out index 83b3a40425..b240dd4c81 100644 --- a/vlib/v/checker/tests/unimplemented_interface_e.out +++ b/vlib/v/checker/tests/unimplemented_interface_e.out @@ -1,5 +1,5 @@ -vlib/v/checker/tests/unimplemented_interface_e.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`, expected `speak(s string)` - 10 | +vlib/v/checker/tests/unimplemented_interface_e.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`: expected `string`, not `&string` for parameter 1 + 10 | 11 | fn main() { 12 | foo(Cat{}) | ~~~~~ diff --git a/vlib/v/checker/tests/unimplemented_interface_f.out b/vlib/v/checker/tests/unimplemented_interface_f.out index 07feb52d8e..9ed8bec110 100644 --- a/vlib/v/checker/tests/unimplemented_interface_f.out +++ b/vlib/v/checker/tests/unimplemented_interface_f.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/unimplemented_interface_f.vv:11:13: error: `Cat` incorrectly implements method `speak` of interface `Animal`, expected `speak(s string)` +vlib/v/checker/tests/unimplemented_interface_f.vv:11:13: error: `Cat` incorrectly implements method `speak` of interface `Animal`: expected 2 parameter(s), not 1 9 | fn main() { 10 | mut animals := []Animal{} 11 | animals << Cat{} diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 659a7215d7..3421ef0c17 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -129,19 +129,22 @@ pub fn (t &Table) fn_type_source_signature(f &Fn) string { return sig } -pub fn (f &Fn) is_same_method_as(func &Fn) bool { +pub fn (t &Table) is_same_method(f &Fn, func &Fn) string { if f.return_type != func.return_type { - return false + s := t.type_to_str(f.return_type) + return 'expected return type `$s`' } if f.params.len != func.params.len { - return false + return 'expected $f.params.len parameter(s), not $func.params.len' } for i in 1 .. f.params.len { if f.params[i].typ != func.params[i].typ { - return false + exps := t.type_to_str(f.params[i].typ) + gots := t.type_to_str(func.params[i].typ) + return 'expected `$exps`, not `$gots` for parameter $i' } } - return true + return '' } pub fn (t &Table) find_fn(name string) ?Fn {