diff --git a/chronos.nimble b/chronos.nimble index 7c34fcac..621a243c 100644 --- a/chronos.nimble +++ b/chronos.nimble @@ -1,5 +1,5 @@ packageName = "chronos" -version = "2.4.0" +version = "2.4.1" author = "Status Research & Development GmbH" description = "Chronos" license = "Apache License 2.0 or MIT" diff --git a/chronos/asyncmacro2.nim b/chronos/asyncmacro2.nim index eb7822a0..8daf6a04 100644 --- a/chronos/asyncmacro2.nim +++ b/chronos/asyncmacro2.nim @@ -203,6 +203,9 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} = futureVarIdents) # don't do anything with forward bodies (empty) if procBody.kind != nnkEmpty: + # fix #13899, `defer` should not escape its original scope + procBody = newStmtList(newTree(nnkBlockStmt, newEmptyNode(), procBody)) + procBody.add(createFutureVarCompletions(futureVarIdents, nil)) if not subtypeIsVoid: diff --git a/tests/testbugs.nim b/tests/testbugs.nim index f1be45fc..7fc9a9c2 100644 --- a/tests/testbugs.nim +++ b/tests/testbugs.nim @@ -73,6 +73,31 @@ suite "Asynchronous issues test suite": await sleepAsync(100.milliseconds) result = (checkstr == "FooBarBaz") + proc testDefer(): Future[bool] {.async.} = + proc someConnect() {.async.} = + await sleepAsync(100.milliseconds) + + proc someClose() {.async.} = + await sleepAsync(100.milliseconds) + + proc testFooFails(): Future[bool] {.async.} = + await someConnect() + defer: + await someClose() + result = true + + proc testFooSucceed(): Future[bool] {.async.} = + try: + await someConnect() + finally: + await someClose() + result = true + + let r1 = await testFooFails() + let r2 = await testFooSucceed() + + result = r1 and r2 + test "Issue #6": check waitFor(issue6()) == true @@ -84,3 +109,6 @@ suite "Asynchronous issues test suite": test "Multiple await on single future test [Nim's issue #13889]": check waitFor(testMultipleAwait()) == true + + test "Defer for asynchronous procedures test [Nim's issue #13899]": + check waitFor(testDefer()) == true