From bc30608e92b825b0bbb6578d4f8ed61aee5d8637 Mon Sep 17 00:00:00 2001 From: Taegon Kim Date: Tue, 8 Nov 2022 22:50:59 +0900 Subject: [PATCH] checker: always trigger error for anon fns without a body block (#16358) --- vlib/v/checker/fn.v | 3 +++ vlib/v/checker/struct.v | 9 --------- vlib/v/checker/tests/anon_fn_without_body.out | 7 +++++++ vlib/v/checker/tests/anon_fn_without_body.vv | 7 +++++++ .../tests/globals/global_anon_fn_without_body.out | 3 +++ .../checker/tests/globals/global_anon_fn_without_body.vv | 1 + .../tests/struct_field_init_with_nobody_anon_fn_err.out | 2 +- 7 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 vlib/v/checker/tests/anon_fn_without_body.out create mode 100644 vlib/v/checker/tests/anon_fn_without_body.vv create mode 100644 vlib/v/checker/tests/globals/global_anon_fn_without_body.out create mode 100644 vlib/v/checker/tests/globals/global_anon_fn_without_body.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index be525218ec..cc23897e59 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -410,6 +410,9 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type { c.inside_anon_fn = keep_inside_anon c.cur_anon_fn = keep_anon_fn } + if node.decl.no_body { + c.error('anonymous function must declare a body', node.decl.pos) + } for param in node.decl.params { if param.name.len == 0 { c.error('use `_` to name an unused parameter', param.pos) diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 40cf9f222c..1128fc8edd 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -450,15 +450,6 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { field.pos) } } - if field_type_sym.kind == .function && field_type_sym.language == .v { - pos := field.expr.pos() - if mut field.expr is ast.AnonFn { - if field.expr.decl.no_body { - c.error('cannot initialize the fn field with anonymous fn that does not have a body', - pos) - } - } - } node.fields[i].typ = expr_type node.fields[i].expected_type = field_info.typ diff --git a/vlib/v/checker/tests/anon_fn_without_body.out b/vlib/v/checker/tests/anon_fn_without_body.out new file mode 100644 index 0000000000..edb2328c9c --- /dev/null +++ b/vlib/v/checker/tests/anon_fn_without_body.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/anon_fn_without_body.vv:4:10: error: anonymous function must declare a body + 2 | + 3 | fn main() { + 4 | func := fn () int + | ~~~~~~~~~ + 5 | + 6 | println(func()) diff --git a/vlib/v/checker/tests/anon_fn_without_body.vv b/vlib/v/checker/tests/anon_fn_without_body.vv new file mode 100644 index 0000000000..f8445b4732 --- /dev/null +++ b/vlib/v/checker/tests/anon_fn_without_body.vv @@ -0,0 +1,7 @@ +module main + +fn main() { + func := fn () int + + println(func()) +} diff --git a/vlib/v/checker/tests/globals/global_anon_fn_without_body.out b/vlib/v/checker/tests/globals/global_anon_fn_without_body.out new file mode 100644 index 0000000000..7d1e6513cc --- /dev/null +++ b/vlib/v/checker/tests/globals/global_anon_fn_without_body.out @@ -0,0 +1,3 @@ +vlib/v/checker/tests/globals/global_anon_fn_without_body.vv:1:14: error: anonymous function must declare a body + 1 | __global f = fn () + | ~~~~~ diff --git a/vlib/v/checker/tests/globals/global_anon_fn_without_body.vv b/vlib/v/checker/tests/globals/global_anon_fn_without_body.vv new file mode 100644 index 0000000000..c6281bbe93 --- /dev/null +++ b/vlib/v/checker/tests/globals/global_anon_fn_without_body.vv @@ -0,0 +1 @@ +__global f = fn () diff --git a/vlib/v/checker/tests/struct_field_init_with_nobody_anon_fn_err.out b/vlib/v/checker/tests/struct_field_init_with_nobody_anon_fn_err.out index 3602a1fcc2..5e0591b5ab 100644 --- a/vlib/v/checker/tests/struct_field_init_with_nobody_anon_fn_err.out +++ b/vlib/v/checker/tests/struct_field_init_with_nobody_anon_fn_err.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/struct_field_init_with_nobody_anon_fn_err.vv:7:7: error: cannot initialize the fn field with anonymous fn that does not have a body +vlib/v/checker/tests/struct_field_init_with_nobody_anon_fn_err.vv:7:7: error: anonymous function must declare a body 5 | fn main() { 6 | _ = App{ 7 | cb: fn(x int) // Note the missing `{}` (the function body) here