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