checker: fix infinite recursion on generic interface cast
parent
df8384b62e
commit
ae036b6146
|
@ -1613,6 +1613,9 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos token.Position) bool {
|
fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos token.Position) bool {
|
||||||
|
if typ == interface_type {
|
||||||
|
return true
|
||||||
|
}
|
||||||
$if debug_interface_type_implements ? {
|
$if debug_interface_type_implements ? {
|
||||||
eprintln('> type_implements typ: $typ.debug() (`${c.table.type_to_str(typ)}`) | inter_typ: $interface_type.debug() (`${c.table.type_to_str(interface_type)}`)')
|
eprintln('> type_implements typ: $typ.debug() (`${c.table.type_to_str(typ)}`) | inter_typ: $interface_type.debug() (`${c.table.type_to_str(interface_type)}`)')
|
||||||
}
|
}
|
||||||
|
@ -1642,6 +1645,10 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if inter_sym.info.is_generic {
|
if inter_sym.info.is_generic {
|
||||||
|
if inferred_type == interface_type {
|
||||||
|
// terminate early, since otherwise we get an infinite recursion/segfault:
|
||||||
|
return false
|
||||||
|
}
|
||||||
return c.type_implements(typ, inferred_type, pos)
|
return c.type_implements(typ, inferred_type, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
vlib/v/checker/tests/interface_generic_err.vv:7:9: error: generic struct init must specify type parameter, e.g. Foo<int>
|
||||||
|
5 |
|
||||||
|
6 | // no segfault without generic
|
||||||
|
7 | what := What{}
|
||||||
|
| ~~~~~~
|
||||||
|
8 | why := Why(what)
|
||||||
|
vlib/v/checker/tests/interface_generic_err.vv:8:8: error: could not infer generic type `T` in interface
|
||||||
|
6 | // no segfault without generic
|
||||||
|
7 | what := What{}
|
||||||
|
8 | why := Why(what)
|
||||||
|
| ~~~~~~~~~
|
|
@ -0,0 +1,8 @@
|
||||||
|
struct What<T> {}
|
||||||
|
|
||||||
|
// with or without generic
|
||||||
|
interface Why<T> {}
|
||||||
|
|
||||||
|
// no segfault without generic
|
||||||
|
what := What{}
|
||||||
|
why := Why(what)
|
Loading…
Reference in New Issue