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