checker: improve errors for interface method compatibility (#8097)
							parent
							
								
									47536df2d0
								
							
						
					
					
						commit
						0f2a770b9c
					
				|  | @ -1849,9 +1849,9 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok | ||||||
| 	styp := c.table.type_to_str(typ) | 	styp := c.table.type_to_str(typ) | ||||||
| 	for imethod in inter_sym.methods { | 	for imethod in inter_sym.methods { | ||||||
| 		if method := typ_sym.find_method(imethod.name) { | 		if method := typ_sym.find_method(imethod.name) { | ||||||
| 			if !imethod.is_same_method_as(method) { | 			msg := c.table.is_same_method(imethod, method) | ||||||
| 				sig := c.table.fn_signature(imethod, skip_receiver: true) | 			if msg.len > 0 { | ||||||
| 				c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`, expected `$sig`', | 				c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`: $msg', | ||||||
| 					pos) | 					pos) | ||||||
| 				return false | 				return false | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| vlib/v/checker/tests/unimplemented_interface_b.vv:13:6: error: `Cat` incorrectly implements method `name` of interface `Animal`, expected `name() string` | vlib/v/checker/tests/unimplemented_interface_b.vv:13:6: error: `Cat` incorrectly implements method `name` of interface `Animal`: expected return type `string` | ||||||
|    11 | fn main() { |    11 | fn main() { | ||||||
|    12 |     c := Cat{} |    12 |     c := Cat{} | ||||||
|    13 |     foo(c) |    13 |     foo(c) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| vlib/v/checker/tests/unimplemented_interface_c.vv:12:6: error: `Cat` incorrectly implements method `name` of interface `Animal`, expected `name()` | vlib/v/checker/tests/unimplemented_interface_c.vv:12:6: error: `Cat` incorrectly implements method `name` of interface `Animal`: expected 1 parameter(s), not 2 | ||||||
|    10 |  |    10 |  | ||||||
|    11 | fn main() { |    11 | fn main() { | ||||||
|    12 |     foo(Cat{}) |    12 |     foo(Cat{}) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| vlib/v/checker/tests/unimplemented_interface_d.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`, expected `speak(s string)` | vlib/v/checker/tests/unimplemented_interface_d.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`: expected 2 parameter(s), not 1 | ||||||
|    10 |  |    10 |  | ||||||
|    11 | fn main() { |    11 | fn main() { | ||||||
|    12 |     foo(Cat{}) |    12 |     foo(Cat{}) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| vlib/v/checker/tests/unimplemented_interface_e.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`, expected `speak(s string)` | vlib/v/checker/tests/unimplemented_interface_e.vv:12:6: error: `Cat` incorrectly implements method `speak` of interface `Animal`: expected `string`, not `&string` for parameter 1 | ||||||
|    10 |  |    10 |  | ||||||
|    11 | fn main() { |    11 | fn main() { | ||||||
|    12 |     foo(Cat{}) |    12 |     foo(Cat{}) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| vlib/v/checker/tests/unimplemented_interface_f.vv:11:13: error: `Cat` incorrectly implements method `speak` of interface `Animal`, expected `speak(s string)` | vlib/v/checker/tests/unimplemented_interface_f.vv:11:13: error: `Cat` incorrectly implements method `speak` of interface `Animal`: expected 2 parameter(s), not 1 | ||||||
|     9 | fn main() { |     9 | fn main() { | ||||||
|    10 |     mut animals := []Animal{} |    10 |     mut animals := []Animal{} | ||||||
|    11 |     animals << Cat{} |    11 |     animals << Cat{} | ||||||
|  |  | ||||||
|  | @ -129,19 +129,22 @@ pub fn (t &Table) fn_type_source_signature(f &Fn) string { | ||||||
| 	return sig | 	return sig | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (f &Fn) is_same_method_as(func &Fn) bool { | pub fn (t &Table) is_same_method(f &Fn, func &Fn) string { | ||||||
| 	if f.return_type != func.return_type { | 	if f.return_type != func.return_type { | ||||||
| 		return false | 		s := t.type_to_str(f.return_type) | ||||||
|  | 		return 'expected return type `$s`' | ||||||
| 	} | 	} | ||||||
| 	if f.params.len != func.params.len { | 	if f.params.len != func.params.len { | ||||||
| 		return false | 		return 'expected $f.params.len parameter(s), not $func.params.len' | ||||||
| 	} | 	} | ||||||
| 	for i in 1 .. f.params.len { | 	for i in 1 .. f.params.len { | ||||||
| 		if f.params[i].typ != func.params[i].typ { | 		if f.params[i].typ != func.params[i].typ { | ||||||
| 			return false | 			exps := t.type_to_str(f.params[i].typ) | ||||||
|  | 			gots := t.type_to_str(func.params[i].typ) | ||||||
|  | 			return 'expected `$exps`, not `$gots` for parameter $i' | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return true | 	return '' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (t &Table) find_fn(name string) ?Fn { | pub fn (t &Table) find_fn(name string) ?Fn { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue