Skip to content

Commit

Permalink
fixes #23635; tasks.toTask Doesn't Expect a Dot Expression (#23641)
Browse files Browse the repository at this point in the history
fixes #23635

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
  • Loading branch information
ringabout and Araq authored May 27, 2024
1 parent c615828 commit cc5ce72
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
24 changes: 20 additions & 4 deletions lib/std/tasks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
36 changes: 36 additions & 0 deletions tests/stdlib/ttasks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit cc5ce72

Please sign in to comment.