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