parser: duplicate method declaration on interface (#5825)
parent
8df6e59678
commit
2ee8f93d60
|
@ -0,0 +1,6 @@
|
|||
vlib/v/checker/tests/no_interface_receiver_duplicate_a.v:5:5: error: interfaces cannot be used as method receiver
|
||||
3 | }
|
||||
4 |
|
||||
5 | fn (a Abc) fun() {
|
||||
| ~~~~~
|
||||
6 | }
|
|
@ -0,0 +1,6 @@
|
|||
interface Abc {
|
||||
fun()
|
||||
}
|
||||
|
||||
fn (a Abc) fun() {
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
vlib/v/checker/tests/no_interface_receiver_duplicate_b.v:1:5: error: interfaces cannot be used as method receiver
|
||||
1 | fn (a Abc) fun() {
|
||||
| ~~~~~
|
||||
2 | }
|
||||
3 |
|
|
@ -0,0 +1,6 @@
|
|||
fn (a Abc) fun() {
|
||||
}
|
||||
|
||||
interface Abc {
|
||||
fun()
|
||||
}
|
|
@ -196,7 +196,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
if language == .v && !p.pref.translated && util.contains_capital(name) {
|
||||
p.error('function names cannot contain uppercase letters, use snake_case instead')
|
||||
}
|
||||
if is_method && p.table.get_type_symbol(rec_type).has_method(name) {
|
||||
type_sym := p.table.get_type_symbol(rec_type)
|
||||
// interfaces are handled in the checker, methods can not be defined on them this way
|
||||
if is_method && (type_sym.has_method(name) && type_sym.kind != .interface_) {
|
||||
p.error('duplicate method `$name`')
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +478,8 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
|
|||
p.check_fn_mutable_arguments(typ, pos)
|
||||
}
|
||||
} else if is_shared || is_atomic {
|
||||
p.error_with_pos('generic object cannot be `atomic` or `shared`', pos)
|
||||
p.error_with_pos('generic object cannot be `atomic` or `shared`',
|
||||
pos)
|
||||
}
|
||||
typ = typ.set_nr_muls(1)
|
||||
if is_shared {
|
||||
|
@ -527,7 +530,8 @@ fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position)
|
|||
fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) {
|
||||
sym := p.table.get_type_symbol(typ)
|
||||
if sym.kind !in [.array, .struct_, .map, .placeholder] && !typ.is_ptr() {
|
||||
p.error_with_pos('shared arguments are only allowed for arrays, maps, and structs\n', pos)
|
||||
p.error_with_pos('shared arguments are only allowed for arrays, maps, and structs\n',
|
||||
pos)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -359,12 +359,17 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
|||
}
|
||||
typ := table.new_type(reg_idx)
|
||||
ts := p.table.get_type_symbol(typ)
|
||||
// if methods were declared before, it's an error, ignore them
|
||||
ts.methods.clear()
|
||||
// Parse methods
|
||||
mut methods := []ast.FnDecl{}
|
||||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||
method_start_pos := p.tok.position()
|
||||
line_nr := p.tok.line_nr
|
||||
name := p.check_name()
|
||||
if ts.has_method(name) {
|
||||
p.error_with_pos('duplicate method `$name`', method_start_pos)
|
||||
}
|
||||
if util.contains_capital(name) {
|
||||
p.error('interface methods cannot contain uppercase letters, use snake_case instead')
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
vlib/v/parser/tests/interface_duplicate_method.v:3:2: error: duplicate method `fun`
|
||||
1 | interface Abc {
|
||||
2 | fun()
|
||||
3 | fun()
|
||||
| ~~~
|
||||
4 | }
|
|
@ -0,0 +1,4 @@
|
|||
interface Abc {
|
||||
fun()
|
||||
fun()
|
||||
}
|
Loading…
Reference in New Issue