diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2024-05-27 22:58:43 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-27 16:58:43 +0200 |
commit | cc5ce72376872c7080543593ee5e7234b16a62bd (patch) | |
tree | 95f7365b324ce01f37ef2b38da39e90237424211 | |
parent | c615828ccb2b309ac03aab93d94b40af6b4079ff (diff) | |
download | Nim-cc5ce72376872c7080543593ee5e7234b16a62bd.tar.gz |
fixes #23635; tasks.toTask Doesn't Expect a Dot Expression (#23641)
fixes #23635 --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
-rw-r--r-- | lib/std/tasks.nim | 24 | ||||
-rw-r--r-- | tests/stdlib/ttasks.nim | 36 |
2 files changed, 56 insertions, 4 deletions
diff --git a/lib/std/tasks.nim b/lib/std/tasks.nim index 1892acd72..7e59747f5 100644 --- a/lib/std/tasks.nim +++ b/lib/std/tasks.nim @@ -110,6 +110,19 @@ template addAllNode(assignParam: NimNode, procParam: NimNode) = tempAssignList.add newLetStmt(tempNode, newDotExpr(objTemp, formalParams[i][0])) scratchRecList.add newIdentDefs(newIdentNode(formalParams[i][0].strVal), assignParam) +proc analyseRootSym(s: NimNode): NimNode = + result = s + while true: + case result.kind + of nnkBracketExpr, nnkDerefExpr, nnkHiddenDeref, + nnkAddr, nnkHiddenAddr, + nnkObjDownConv, nnkObjUpConv: + result = result[0] + of nnkDotExpr, nnkCheckedFieldExpr, nnkHiddenStdConv, nnkHiddenSubConv: + result = result[1] + else: + break + macro toTask*(e: typed{nkCall | nkInfix | nkPrefix | nkPostfix | nkCommand | nkCallStrLit}): Task = ## Converts the call and its arguments to `Task`. runnableExamples: @@ -121,11 +134,14 @@ macro toTask*(e: typed{nkCall | nkInfix | nkPrefix | nkPostfix | nkCommand | nkC let retType = getTypeInst(e) let returnsVoid = retType.typeKind == ntyVoid + let rootSym = analyseRootSym(e[0]) + expectKind rootSym, nnkSym + when compileOption("threads"): - if not isGcSafe(e[0]): + if not isGcSafe(rootSym): error("'toTask' takes a GC safe call expression", e) - if hasClosure(e[0]): + if hasClosure(rootSym): error("closure call is not allowed", e) if e.len > 1: @@ -209,7 +225,7 @@ macro toTask*(e: typed{nkCall | nkInfix | nkPrefix | nkPostfix | nkCommand | nkC let funcCall = newCall(e[0], callNode) functionStmtList.add tempAssignList - let funcName = genSym(nskProc, e[0].strVal) + let funcName = genSym(nskProc, rootSym.strVal) let destroyName = genSym(nskProc, "destroyScratch") let objTemp2 = genSym(ident = "obj") let tempNode = quote("@") do: @@ -241,7 +257,7 @@ macro toTask*(e: typed{nkCall | nkInfix | nkPrefix | nkPostfix | nkCommand | nkC Task(callback: `funcName`, args: `scratchIdent`, destroy: `destroyName`) else: let funcCall = newCall(e[0]) - let funcName = genSym(nskProc, e[0].strVal) + let funcName = genSym(nskProc, rootSym.strVal) if returnsVoid: result = quote do: diff --git a/tests/stdlib/ttasks.nim b/tests/stdlib/ttasks.nim index 347c3347a..ba65590d9 100644 --- a/tests/stdlib/ttasks.nim +++ b/tests/stdlib/ttasks.nim @@ -523,3 +523,39 @@ block: doAssert resB == "abcdef" testReturnValues() + + +block: # bug #23635 + block: + type + Store = object + run: proc (a: int) {.nimcall, gcsafe.} + + block: + var count = 0 + proc hello(a: int) = + inc count, a + + var store = Store() + store.run = hello + + let b = toTask store.run(13) + b.invoke() + doAssert count == 13 + + block: + type + Store = object + run: proc () {.nimcall, gcsafe.} + + block: + var count = 0 + proc hello() = + inc count, 1 + + var store = Store() + store.run = hello + + let b = toTask store.run() + b.invoke() + doAssert count == 1 |