Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Illegal capture of closure iterator, when should be legal

Open yglukhov opened this issue 1 year ago • 1 comments

proc foo() =
  iterator it() {.closure.} =
    discard
  proc useIter() {.nimcall.} =
    var iii = it # <-- illegal capture
  useIter()
foo()
nim c test
.../test.nim(5, 15) Error: illegal capture 'it' because 'useIter' has the calling convention: <nimcall>

This capture should be legal as it is a fresh local instance of the iterator.

nim --version
Nim Compiler Version 1.7.1 [Linux: amd64]
Compiled at 2022-08-03
Copyright (c) 2006-2022 by Andreas Rumpf

git hash: 0d734d7966644018207a20cf23f16912f9c276d8
active boot switches: -d:release

yglukhov avatar Aug 04 '22 08:08 yglukhov

This capture should be legal as it is a fresh local instance of the iterator.

If this is true, this shall be a regression since 1.4.0 , https://github.com/nim-lang/Nim/commit/b022576ce96f5c166c7f5684bef9de682704cb1b looks suspicious, I'm looking into it.

ringabout avatar Aug 04 '22 10:08 ringabout

is this true? tests\closure\tinvalidclosure4.nim exists ensure it's a illegal capture

bung87 avatar Oct 13 '22 23:10 bung87

But tinvalidclosure4.nim demonstrates a case when a nimcall function tries to capture outer variable, which is technically impossible and thus illegal. In my example it doesn't capture anything and so should be possible to instantiate from within a nimcall function. Something like in the following valid code:

proc foo() =
  proc bar() = # Local function, but not a closure, because no captures
    echo "hi"
  proc baz() {.nimcall.} = # Calls local function
    bar()
  baz()
foo()

I believe this is because closure iterators are always treated as closures internally in nim, even if they don't capture anything, but I could be wrong.

yglukhov avatar Oct 15 '22 10:10 yglukhov

yeah, it marked as closure even it does not has to be.

bung87 avatar Oct 15 '22 10:10 bung87

backport pls

arnetheduck avatar Oct 21 '22 09:10 arnetheduck