diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index 7e072f74f9..02af784a83 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -103,6 +103,11 @@ pub fn (s &Scope) known_var(name string) bool { return true } +pub fn (s &Scope) known_global(name string) bool { + s.find_global(name) or { return false } + return true +} + pub fn (s &Scope) known_const(name string) bool { s.find_const(name) or { return false } return true diff --git a/vlib/v/checker/tests/globals/closure_capture_global_var.out b/vlib/v/checker/tests/globals/closure_capture_global_var.out new file mode 100644 index 0000000000..f81d636fc2 --- /dev/null +++ b/vlib/v/checker/tests/globals/closure_capture_global_var.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/globals/closure_capture_global_var.vv:12:12: error: no need to capture global variable `number` in closure + 10 | + 11 | fn main() { + 12 | f1 := fn [number] () { + | ~~~~~~ + 13 | println(number) + 14 | } diff --git a/vlib/v/checker/tests/globals/closure_capture_global_var.vv b/vlib/v/checker/tests/globals/closure_capture_global_var.vv new file mode 100644 index 0000000000..66d236d488 --- /dev/null +++ b/vlib/v/checker/tests/globals/closure_capture_global_var.vv @@ -0,0 +1,16 @@ +module main + +__global ( + number int +) + +fn init() { + number = 123 +} + +fn main() { + f1 := fn [number] () { + println(number) + } + f1() +} diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 768ab5cd13..b2a64a9be6 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -1031,6 +1031,11 @@ fn (mut p Parser) closure_vars() []ast.Param { p.check(.name) var_name := p.prev_tok.lit mut var := p.scope.parent.find_var(var_name) or { + if p.table.global_scope.known_global(var_name) { + p.error_with_pos('no need to capture global variable `$var_name` in closure', + p.prev_tok.pos()) + continue + } p.error_with_pos('undefined ident: `$var_name`', p.prev_tok.pos()) continue }