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 {
|
for param in method.params {
|
||||||
c.ensure_type_exists(param.typ, param.pos) or { return }
|
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 {
|
for j in 0 .. i {
|
||||||
if method.name == decl.methods[j].name {
|
if method.name == decl.methods[j].name {
|
||||||
c.error('duplicate method name `$method.name`', method.pos)
|
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
|
// make sure interface does not implement its own interface methods
|
||||||
if sym.kind == .interface_ && sym.has_method(node.name) {
|
if sym.kind == .interface_ && sym.has_method(node.name) {
|
||||||
if sym.info is ast.Interface {
|
if mut sym.info is ast.Interface {
|
||||||
info := sym.info as ast.Interface
|
|
||||||
// if the method is in info.methods then it is an interface method
|
// 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`',
|
c.error('interface `$sym.name` cannot implement its own interface method `$node.name`',
|
||||||
node.pos)
|
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
|
// needed for proper error reporting during vweb route checking
|
||||||
if node.method_idx < sym.methods.len {
|
if node.method_idx < sym.methods.len {
|
||||||
sym.methods[node.method_idx].source_fn = voidptr(node)
|
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