summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorVindaar <basti90@gmail.com>2022-11-10 21:42:53 +0100
committerGitHub <noreply@github.com>2022-11-10 15:42:53 -0500
commitcc2b0f01725d69d617ed214cf89b647936b93f80 (patch)
tree8a82d17ce637cd42835cb94a7dc4d447f101ff73 /lib/pure
parenta15872ba9ecd118dc69f2346285d5c039e1efd42 (diff)
downloadNim-cc2b0f01725d69d617ed214cf89b647936b93f80.tar.gz
[sugar] handle HiddenDeref in capture, error at CT if unsupported nnk (#20680)
* [sugar] handle HiddenDeref in capture, error at CT if unsupported nnk

Instead of running into trouble of the `.strVal` access failing, it's
better to error at CT.

* [tests] remove unnecessary import in test case

* improve ident extraction & extend test cases

* [tests] improve tests for `capture` of different types & act. check
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/sugar.nim16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim
index ff2a3bb58..d8e00d1f8 100644
--- a/lib/pure/sugar.nim
+++ b/lib/pure/sugar.nim
@@ -231,9 +231,19 @@ macro capture*(locals: varargs[typed], body: untyped): untyped {.since: (1, 1).}
   let locals = if locals.len == 1 and locals[0].kind == nnkBracket: locals[0]
                else: locals
   for arg in locals:
-    if arg.strVal == "result":
-      error("The variable name cannot be `result`!", arg)
-    params.add(newIdentDefs(ident(arg.strVal), freshIdentNodes getTypeInst arg))
+    proc getIdent(n: NimNode): NimNode =
+      case n.kind
+      of nnkIdent, nnkSym:
+        let nStr = n.strVal
+        if nStr == "result":
+          error("The variable name cannot be `result`!", n)
+        result = ident(nStr)
+      of nnkHiddenDeref: result = n[0].getIdent()
+      else:
+        error("The argument to be captured `" & n.repr & "` is not a pure identifier. " &
+          "It is an unsupported `" & $n.kind & "` node.", n)
+    let argName = getIdent(arg)
+    params.add(newIdentDefs(argName, freshIdentNodes getTypeInst arg))
   result = newNimNode(nnkCall)
   result.add(newProc(newEmptyNode(), params, body, nnkLambda))
   for arg in locals: result.add(arg)