From d73f478bdcbf774622c24c1a4ef58cc56beacb49 Mon Sep 17 00:00:00 2001 From: bptato <60043228+bptato@users.noreply.github.com> Date: Thu, 11 Sep 2025 09:22:47 +0200 Subject: [PATCH] Allow assignment of nested non-closure procs to globals (#25154) For memory-safety, this only seems problematic in case of closures, so I just special cased that. Fixes #25131 --- compiler/semstmts.nim | 2 +- tests/global/tglobalclosure.nim | 14 ++++++++++++++ tests/global/tglobalclosure2.nim | 17 +++++++++++++++++ tests/global/tglobalproc.nim | 17 +++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/global/tglobalclosure.nim create mode 100644 tests/global/tglobalclosure2.nim create mode 100644 tests/global/tglobalproc.nim diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index ce8b59f9cd..6c8542b584 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -725,7 +725,7 @@ template isLocalSym(sym: PSym): bool = sym.typ.kind == tyTypeDesc or sfCompileTime in sym.flags) or sym.kind in {skProc, skFunc, skIterator} and - sfGlobal notin sym.flags + sfGlobal notin sym.flags and sym.typ.callConv == ccClosure proc usesLocalVar(n: PNode): bool = case n.kind diff --git a/tests/global/tglobalclosure.nim b/tests/global/tglobalclosure.nim new file mode 100644 index 0000000000..81cdba37da --- /dev/null +++ b/tests/global/tglobalclosure.nim @@ -0,0 +1,14 @@ +discard """ + errormsg: "cannot assign local to global variable" + line: 11 +""" + +proc main() = + var x = "hi" + proc p() = + echo x + + let a {.global.} = p + p() + +main() diff --git a/tests/global/tglobalclosure2.nim b/tests/global/tglobalclosure2.nim new file mode 100644 index 0000000000..bd6b9bfd61 --- /dev/null +++ b/tests/global/tglobalclosure2.nim @@ -0,0 +1,17 @@ +discard """ + errormsg: "cannot assign local to global variable" + line: 14 +""" + +type X = object + p: proc() {.closure.} + +proc main() = + var x = "hi" + proc p() = + echo x + + let a {.global.} = X(p: p) + a.p() + +main() diff --git a/tests/global/tglobalproc.nim b/tests/global/tglobalproc.nim new file mode 100644 index 0000000000..ba6f5a7999 --- /dev/null +++ b/tests/global/tglobalproc.nim @@ -0,0 +1,17 @@ +discard """ +output: "hi\nhi" +""" + +type X = object + p: proc() {.nimcall.} + +proc main() = + proc p() = + echo "hi" + + let a {.global.} = p + let b {.global.} = X(p: p) + a() + b.p() + +main()