diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 424caa69a6..15f9b64b50 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 { + if typ == interface_type { + return true + } $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)}`)') } @@ -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 inferred_type == interface_type { + // terminate early, since otherwise we get an infinite recursion/segfault: + return false + } return c.type_implements(typ, inferred_type, pos) } } diff --git a/vlib/v/checker/tests/interface_generic_err.out b/vlib/v/checker/tests/interface_generic_err.out new file mode 100644 index 0000000000..f0a6c42c66 --- /dev/null +++ b/vlib/v/checker/tests/interface_generic_err.out @@ -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 + 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) + | ~~~~~~~~~ diff --git a/vlib/v/checker/tests/interface_generic_err.vv b/vlib/v/checker/tests/interface_generic_err.vv new file mode 100644 index 0000000000..7c6b2b4286 --- /dev/null +++ b/vlib/v/checker/tests/interface_generic_err.vv @@ -0,0 +1,8 @@ +struct What {} + +// with or without generic +interface Why {} + +// no segfault without generic +what := What{} +why := Why(what)