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) {
 | 
							if language == .v && !p.pref.translated && util.contains_capital(name) {
 | 
				
			||||||
			p.error('function names cannot contain uppercase letters, use snake_case instead')
 | 
								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`')
 | 
								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)
 | 
											p.check_fn_mutable_arguments(typ, pos)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else if is_shared || is_atomic {
 | 
									} 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)
 | 
									typ = typ.set_nr_muls(1)
 | 
				
			||||||
				if is_shared {
 | 
									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) {
 | 
					fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) {
 | 
				
			||||||
	sym := p.table.get_type_symbol(typ)
 | 
						sym := p.table.get_type_symbol(typ)
 | 
				
			||||||
	if sym.kind !in [.array, .struct_, .map, .placeholder] && !typ.is_ptr() {
 | 
						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)
 | 
						typ := table.new_type(reg_idx)
 | 
				
			||||||
	ts := p.table.get_type_symbol(typ)
 | 
						ts := p.table.get_type_symbol(typ)
 | 
				
			||||||
 | 
						// if methods were declared before, it's an error, ignore them
 | 
				
			||||||
 | 
						ts.methods.clear()
 | 
				
			||||||
	// Parse methods
 | 
						// Parse methods
 | 
				
			||||||
	mut methods := []ast.FnDecl{}
 | 
						mut methods := []ast.FnDecl{}
 | 
				
			||||||
	for p.tok.kind != .rcbr && p.tok.kind != .eof {
 | 
						for p.tok.kind != .rcbr && p.tok.kind != .eof {
 | 
				
			||||||
		method_start_pos := p.tok.position()
 | 
							method_start_pos := p.tok.position()
 | 
				
			||||||
		line_nr := p.tok.line_nr
 | 
							line_nr := p.tok.line_nr
 | 
				
			||||||
		name := p.check_name()
 | 
							name := p.check_name()
 | 
				
			||||||
 | 
							if ts.has_method(name) {
 | 
				
			||||||
 | 
								p.error_with_pos('duplicate method `$name`', method_start_pos)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if util.contains_capital(name) {
 | 
							if util.contains_capital(name) {
 | 
				
			||||||
			p.error('interface methods cannot contain uppercase letters, use snake_case instead')
 | 
								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