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