From 7c1ace02f37f6bfcd12da29b1e95ece1e38ce389 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 19 Jun 2023 23:22:25 +0800 Subject: [PATCH] checker: fix a bug checking generic closures (#18489) --- vlib/v/checker/fn.v | 4 ++-- ...r.out => generic_closure_fn_decl_err_a.out} | 2 +- ...err.vv => generic_closure_fn_decl_err_a.vv} | 0 .../tests/generic_closure_fn_decl_err_b.out | 7 +++++++ .../tests/generic_closure_fn_decl_err_b.vv | 18 ++++++++++++++++++ 5 files changed, 28 insertions(+), 3 deletions(-) rename vlib/v/checker/tests/{generic_closure_fn_decl_err.out => generic_closure_fn_decl_err_a.out} (56%) rename vlib/v/checker/tests/{generic_closure_fn_decl_err.vv => generic_closure_fn_decl_err_a.vv} (100%) create mode 100644 vlib/v/checker/tests/generic_closure_fn_decl_err_b.out create mode 100644 vlib/v/checker/tests/generic_closure_fn_decl_err_b.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index e42942d5b1f627..e7846d1b9878e2 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -459,12 +459,12 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type { } node.decl.scope.update_var_type(var.name, var.typ) } - c.stmts(node.decl.stmts) - c.fn_decl(mut node.decl) if has_generic && node.decl.generic_names.len == 0 { c.error('generic closure fn must specify type parameter, e.g. fn [foo] [T]()', node.decl.pos) } + c.stmts(node.decl.stmts) + c.fn_decl(mut node.decl) return node.typ } diff --git a/vlib/v/checker/tests/generic_closure_fn_decl_err.out b/vlib/v/checker/tests/generic_closure_fn_decl_err_a.out similarity index 56% rename from vlib/v/checker/tests/generic_closure_fn_decl_err.out rename to vlib/v/checker/tests/generic_closure_fn_decl_err_a.out index d4dcfef8f97870..fd77a3cefca5be 100644 --- a/vlib/v/checker/tests/generic_closure_fn_decl_err.out +++ b/vlib/v/checker/tests/generic_closure_fn_decl_err_a.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/generic_closure_fn_decl_err.vv:5:2: error: generic closure fn must specify type parameter, e.g. fn [foo] [T]() +vlib/v/checker/tests/generic_closure_fn_decl_err_a.vv:5:2: error: generic closure fn must specify type parameter, e.g. fn [foo] [T]() 3 | 4 | pub fn (mut app App) register[T](service T) { 5 | fn [service] () { diff --git a/vlib/v/checker/tests/generic_closure_fn_decl_err.vv b/vlib/v/checker/tests/generic_closure_fn_decl_err_a.vv similarity index 100% rename from vlib/v/checker/tests/generic_closure_fn_decl_err.vv rename to vlib/v/checker/tests/generic_closure_fn_decl_err_a.vv diff --git a/vlib/v/checker/tests/generic_closure_fn_decl_err_b.out b/vlib/v/checker/tests/generic_closure_fn_decl_err_b.out new file mode 100644 index 00000000000000..807e4bba7ac061 --- /dev/null +++ b/vlib/v/checker/tests/generic_closure_fn_decl_err_b.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/generic_closure_fn_decl_err_b.vv:13:2: error: generic closure fn must specify type parameter, e.g. fn [foo] [T]() + 11 | println(typeof(my_plugin).name) // MyPlugin + 12 | + 13 | fn[my_plugin](){ my_plugin.on_update() }() + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 14 | } + 15 | diff --git a/vlib/v/checker/tests/generic_closure_fn_decl_err_b.vv b/vlib/v/checker/tests/generic_closure_fn_decl_err_b.vv new file mode 100644 index 00000000000000..53375f6de52443 --- /dev/null +++ b/vlib/v/checker/tests/generic_closure_fn_decl_err_b.vv @@ -0,0 +1,18 @@ +struct MyPlugin { +} + +fn (p MyPlugin) on_update() { + println('[MyPlugin.on_update]') +} + +fn foo[T](my_plugin T) { + println('[foo]') + println(T.name) // MyPlugin + println(typeof(my_plugin).name) // MyPlugin + + fn[my_plugin](){ my_plugin.on_update() }() +} + +fn main() { + foo[MyPlugin](MyPlugin{}) +}