diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index eee52c6a32..4ecf8388c1 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -519,6 +519,16 @@ pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) { } } } + } else if sym.info is ast.FnType { + func := (sym.info as ast.FnType).func + if c.table.sym(func.return_type).name.ends_with('.$node.name') { + c.error('sum type `$node.name` cannot be defined recursively', variant.pos) + } + for param in func.params { + if c.table.sym(param.typ).name.ends_with('.$node.name') { + c.error('sum type `$node.name` cannot be defined recursively', variant.pos) + } + } } if sym.name.trim_string_left(sym.mod + '.') == node.name { diff --git a/vlib/v/checker/tests/sumtype_define_recursively.out b/vlib/v/checker/tests/sumtype_define_recursively.out new file mode 100644 index 0000000000..019319e621 --- /dev/null +++ b/vlib/v/checker/tests/sumtype_define_recursively.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/sumtype_define_recursively.vv:1:13: error: sum type `Expr` cannot be defined recursively + 1 | type Expr = fn ([]Expr) Expr | int + | ~~~~~~~~~~~~~~~~ + 2 | + 3 | fn f(exprs []Expr) Expr { diff --git a/vlib/v/checker/tests/sumtype_define_recursively.vv b/vlib/v/checker/tests/sumtype_define_recursively.vv new file mode 100644 index 0000000000..3149b751ae --- /dev/null +++ b/vlib/v/checker/tests/sumtype_define_recursively.vv @@ -0,0 +1,10 @@ +type Expr = fn ([]Expr) Expr | int + +fn f(exprs []Expr) Expr { + return 0 +} + +fn main() { + mut m := map[string]Expr{} + m['f'] = f +}