checker: fix generic type ignores implemented interface (#9124)
							parent
							
								
									cce006b129
								
							
						
					
					
						commit
						208cabc994
					
				| 
						 | 
					@ -2030,10 +2030,11 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok
 | 
				
			||||||
	$if debug_interface_type_implements ? {
 | 
						$if debug_interface_type_implements ? {
 | 
				
			||||||
		eprintln('> type_implements typ: $typ.debug() | inter_typ: $inter_typ.debug()')
 | 
							eprintln('> type_implements typ: $typ.debug() | inter_typ: $inter_typ.debug()')
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	typ_sym := c.table.get_type_symbol(typ)
 | 
						utyp := c.unwrap_generic(typ)
 | 
				
			||||||
 | 
						typ_sym := c.table.get_type_symbol(utyp)
 | 
				
			||||||
	mut inter_sym := c.table.get_type_symbol(inter_typ)
 | 
						mut inter_sym := c.table.get_type_symbol(inter_typ)
 | 
				
			||||||
	styp := c.table.type_to_str(typ)
 | 
						styp := c.table.type_to_str(utyp)
 | 
				
			||||||
	same_base_type := typ.idx() == inter_typ.idx()
 | 
						same_base_type := utyp.idx() == inter_typ.idx()
 | 
				
			||||||
	if typ_sym.kind == .interface_ && inter_sym.kind == .interface_ && !same_base_type {
 | 
						if typ_sym.kind == .interface_ && inter_sym.kind == .interface_ && !same_base_type {
 | 
				
			||||||
		c.error('cannot implement interface `$inter_sym.name` with a different interface `$styp`',
 | 
							c.error('cannot implement interface `$inter_sym.name` with a different interface `$styp`',
 | 
				
			||||||
			pos)
 | 
								pos)
 | 
				
			||||||
| 
						 | 
					@ -2077,8 +2078,8 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok
 | 
				
			||||||
			c.error("`$styp` doesn't implement field `$ifield.name` of interface `$inter_sym.name`",
 | 
								c.error("`$styp` doesn't implement field `$ifield.name` of interface `$inter_sym.name`",
 | 
				
			||||||
				pos)
 | 
									pos)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if typ !in inter_sym.info.types && typ_sym.kind != .interface_ {
 | 
							if utyp !in inter_sym.info.types && typ_sym.kind != .interface_ {
 | 
				
			||||||
			inter_sym.info.types << typ
 | 
								inter_sym.info.types << utyp
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					// The series of i?_test.v files, do test different edge cases for
 | 
				
			||||||
 | 
					// interface table generation. The differences may seem very minor
 | 
				
			||||||
 | 
					// (placement of the interface declaration, whether or not there are
 | 
				
			||||||
 | 
					// helper methods, etc), but PLEASE do NOT be tempted to merge them in
 | 
				
			||||||
 | 
					// a single _test.v file. Debugging interface code generation issues
 | 
				
			||||||
 | 
					// is *much easier* when the _test.v files are very short and focused.
 | 
				
			||||||
 | 
					struct Point {
 | 
				
			||||||
 | 
						x i8
 | 
				
			||||||
 | 
						y i8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn (p Point) draw() string {
 | 
				
			||||||
 | 
						return 'Point($p.x,$p.y)'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn to_string(d Drawer) {
 | 
				
			||||||
 | 
						println(d.draw())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Drawer {
 | 
				
			||||||
 | 
						draw() string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn to_string_generic<T>(t T) {
 | 
				
			||||||
 | 
						to_string(t)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_to_string_generic_can_be_called() {
 | 
				
			||||||
 | 
						p := Point{
 | 
				
			||||||
 | 
							x: 2
 | 
				
			||||||
 | 
							y: 3
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						to_string_generic(p)
 | 
				
			||||||
 | 
						assert true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue