checker: improve errors for interface method compatibility (#8097)
parent
47536df2d0
commit
0f2a770b9c
|
@ -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)
|
styp := c.table.type_to_str(typ)
|
||||||
for imethod in inter_sym.methods {
|
for imethod in inter_sym.methods {
|
||||||
if method := typ_sym.find_method(imethod.name) {
|
if method := typ_sym.find_method(imethod.name) {
|
||||||
if !imethod.is_same_method_as(method) {
|
msg := c.table.is_same_method(imethod, method)
|
||||||
sig := c.table.fn_signature(imethod, skip_receiver: true)
|
if msg.len > 0 {
|
||||||
c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`, expected `$sig`',
|
c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`: $msg',
|
||||||
pos)
|
pos)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
11 | fn main() {
|
||||||
12 | c := Cat{}
|
12 | c := Cat{}
|
||||||
13 | foo(c)
|
13 | foo(c)
|
||||||
|
|
|
@ -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()`
|
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 |
|
10 |
|
||||||
11 | fn main() {
|
11 | fn main() {
|
||||||
12 | foo(Cat{})
|
12 | foo(Cat{})
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
|
@ -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)`
|
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 |
|
10 |
|
||||||
11 | fn main() {
|
11 | fn main() {
|
||||||
12 | foo(Cat{})
|
12 | foo(Cat{})
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
|
@ -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)`
|
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 |
|
10 |
|
||||||
11 | fn main() {
|
11 | fn main() {
|
||||||
12 | foo(Cat{})
|
12 | foo(Cat{})
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
|
@ -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() {
|
9 | fn main() {
|
||||||
10 | mut animals := []Animal{}
|
10 | mut animals := []Animal{}
|
||||||
11 | animals << Cat{}
|
11 | animals << Cat{}
|
||||||
|
|
|
@ -129,19 +129,22 @@ pub fn (t &Table) fn_type_source_signature(f &Fn) string {
|
||||||
return sig
|
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 {
|
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 {
|
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 {
|
for i in 1 .. f.params.len {
|
||||||
if f.params[i].typ != func.params[i].typ {
|
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 {
|
pub fn (t &Table) find_fn(name string) ?Fn {
|
||||||
|
|
Loading…
Reference in New Issue