checker: verify interface is not used as receiver
parent
7d32476841
commit
0f8ed84333
|
@ -206,6 +206,7 @@ pub:
|
|||
is_variadic bool
|
||||
is_anon bool
|
||||
receiver Field
|
||||
receiver_pos token.Position
|
||||
is_method bool
|
||||
rec_mut bool // is receiver mutable
|
||||
is_c bool
|
||||
|
|
|
@ -1385,12 +1385,15 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
|||
c.check_expr_opt_call(it.expr, etype, false)
|
||||
}
|
||||
ast.FnDecl {
|
||||
// if it.is_method {
|
||||
// sym := c.table.get_type_symbol(it.receiver.typ)
|
||||
// if sym.has_method(it.name) {
|
||||
// c.warn('duplicate method `$it.name`', it.pos)
|
||||
// }
|
||||
// }
|
||||
if it.is_method {
|
||||
sym := c.table.get_type_symbol(it.receiver.typ)
|
||||
if sym.kind == .interface_ {
|
||||
c.error('interaces cannot be used as method receiver', it.receiver_pos)
|
||||
}
|
||||
// if sym.has_method(it.name) {
|
||||
// c.warn('duplicate method `$it.name`', it.pos)
|
||||
// }
|
||||
}
|
||||
if !it.is_c {
|
||||
// Make sure all types are valid
|
||||
for arg in it.args {
|
||||
|
@ -1748,7 +1751,8 @@ pub fn (mut c Checker) ident(ident mut ast.Ident) table.Type {
|
|||
if sym.info is table.FnType {
|
||||
// anon/local fn assigned to new variable uses this
|
||||
info := sym.info as table.FnType
|
||||
fn_type := table.new_type(c.table.find_or_register_fn_type(info.func, true, true))
|
||||
fn_type := table.new_type(c.table.find_or_register_fn_type(info.func,
|
||||
true, true))
|
||||
ident.kind = .function
|
||||
ident.info = ast.IdentFn{
|
||||
typ: fn_type
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
vlib/v/checker/tests/no_interface_receiver.v:5:5: error: interaces cannot be used as method receiver
|
||||
3 | }
|
||||
4 |
|
||||
5 | fn (a Animal) str() {}
|
||||
| ~~~~~~~~
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
interface Animal {
|
||||
speak()
|
||||
}
|
||||
|
||||
fn (a Animal) str() {}
|
|
@ -109,6 +109,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
// Receiver?
|
||||
mut rec_name := ''
|
||||
mut is_method := false
|
||||
mut receiver_pos := token.Position{}
|
||||
mut rec_type := table.void_type
|
||||
mut rec_mut := false
|
||||
mut args := []table.Arg{}
|
||||
|
@ -119,11 +120,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
if rec_mut {
|
||||
p.next() // `mut`
|
||||
}
|
||||
rec_start_pos := p.tok.position()
|
||||
rec_name = p.check_name()
|
||||
if !rec_mut {
|
||||
rec_mut = p.tok.kind == .key_mut
|
||||
}
|
||||
is_amp := p.tok.kind == .amp
|
||||
receiver_pos = rec_start_pos.extend(p.tok.position())
|
||||
// if rec_mut {
|
||||
// p.check(.key_mut)
|
||||
// }
|
||||
|
@ -256,6 +259,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
name: rec_name
|
||||
typ: rec_type
|
||||
}
|
||||
receiver_pos: receiver_pos
|
||||
is_method: is_method
|
||||
rec_mut: rec_mut
|
||||
is_c: is_c
|
||||
|
|
Loading…
Reference in New Issue