checker: check duplicated field and method (only for fields that are anon-fns for now) (#10927)
parent
a621149fc2
commit
3be8ef3b5a
|
@ -521,6 +521,13 @@ pub fn (mut c Checker) interface_decl(mut decl ast.InterfaceDecl) {
|
|||
for param in method.params {
|
||||
c.ensure_type_exists(param.typ, param.pos) or { return }
|
||||
}
|
||||
for field in decl.fields {
|
||||
field_sym := c.table.get_type_symbol(field.typ)
|
||||
if field.name == method.name && field_sym.kind == .function {
|
||||
c.error('type `$decl_sym.name` has both field and method named `$method.name`',
|
||||
method.pos)
|
||||
}
|
||||
}
|
||||
for j in 0 .. i {
|
||||
if method.name == decl.methods[j].name {
|
||||
c.error('duplicate method name `$method.name`', method.pos)
|
||||
|
@ -7888,15 +7895,23 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||
}
|
||||
// make sure interface does not implement its own interface methods
|
||||
if sym.kind == .interface_ && sym.has_method(node.name) {
|
||||
if sym.info is ast.Interface {
|
||||
info := sym.info as ast.Interface
|
||||
if mut sym.info is ast.Interface {
|
||||
// if the method is in info.methods then it is an interface method
|
||||
if info.has_method(node.name) {
|
||||
if sym.info.has_method(node.name) {
|
||||
c.error('interface `$sym.name` cannot implement its own interface method `$node.name`',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
if mut sym.info is ast.Struct {
|
||||
if field := c.table.find_field(sym, node.name) {
|
||||
field_sym := c.table.get_type_symbol(field.typ)
|
||||
if field_sym.kind == .function {
|
||||
c.error('type `$sym.name` has both field and method named `$node.name`',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
// needed for proper error reporting during vweb route checking
|
||||
if node.method_idx < sym.methods.len {
|
||||
sym.methods[node.method_idx].source_fn = voidptr(node)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
vlib/v/checker/tests/duplicate_field_method_err.vv:5:1: error: type `St` has both field and method named `attr`
|
||||
3 | }
|
||||
4 |
|
||||
5 | fn (s St) attr() {}
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
6 |
|
||||
7 | interface Foo {
|
||||
vlib/v/checker/tests/duplicate_field_method_err.vv:9:2: error: type `Foo` has both field and method named `bar`
|
||||
7 | interface Foo {
|
||||
8 | bar fn ()
|
||||
9 | bar()
|
||||
| ~~~~~
|
||||
10 | }
|
|
@ -0,0 +1,10 @@
|
|||
struct St{
|
||||
attr fn()
|
||||
}
|
||||
|
||||
fn (s St) attr() {}
|
||||
|
||||
interface Foo {
|
||||
bar fn ()
|
||||
bar()
|
||||
}
|
Loading…
Reference in New Issue