Skip to content

Commit 0ef6cf4

Browse files
committed
results.? compatibity
This PR uses the facilities provided in status-im/nim-stew#134 to support `?` in `async` proc's.
1 parent ef94d75 commit 0ef6cf4

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

chronos/asyncmacro2.nim

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
# distribution, for details about the copyright.
88
#
99

10-
import std/[macros]
10+
import
11+
std/[macros]
1112

1213
proc skipUntilStmtList(node: NimNode): NimNode {.compileTime.} =
1314
# Skips a nest of StmtList's.
@@ -17,7 +18,6 @@ proc skipUntilStmtList(node: NimNode): NimNode {.compileTime.} =
1718

1819
proc processBody(node, retFutureSym: NimNode,
1920
subTypeIsVoid: bool): NimNode {.compileTime.} =
20-
#echo(node.treeRepr)
2121
result = node
2222
case node.kind
2323
of nnkReturnStmt:
@@ -147,6 +147,12 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
147147
# fix #13899, `defer` should not escape its original scope
148148
procBody = newStmtList(newTree(nnkBlockStmt, newEmptyNode(), procBody))
149149

150+
# Support `let x = ? await ...`
151+
let ar = ident "assignResult?"
152+
procBody.insert 0, quote do:
153+
template `ar`(v: Result) =
154+
`internalFutureSym`.complete(v)
155+
150156
if not subtypeIsVoid:
151157
procBody.insert(0, newNimNode(nnkPragma).add(newIdentNode("push"),
152158
newNimNode(nnkExprColonExpr).add(newNimNode(nnkBracketExpr).add(
@@ -328,5 +334,5 @@ macro async*(prc: untyped): untyped =
328334
result.add asyncSingleProc(oneProc)
329335
else:
330336
result = asyncSingleProc(prc)
331-
when chronosDumpAsync:
337+
when true or chronosDumpAsync:
332338
echo repr result

tests/testmacro.nim

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ proc testAwaitne(): Future[bool] {.async.} =
9494

9595
return true
9696

97+
proc resultOk(): Future[Result[int, string]] {.async.} =
98+
return ok(42)
99+
100+
proc resultErr(): Future[Result[int, string]] {.async.} =
101+
return err("string")
102+
103+
proc testResult: Future[Result[int, string]] {.async.} =
104+
let
105+
x = ? await resultOk()
106+
107+
if x == 42:
108+
let _ = ? await resultErr()
109+
return err("not this one")
110+
97111
suite "Macro transformations test suite":
98112
test "`await` command test":
99113
check waitFor(testAwait()) == true
@@ -139,3 +153,19 @@ suite "Closure iterator's exception transformation issues":
139153
answer.inc(10)
140154
waitFor(a())
141155
check answer == 42
156+
157+
suite "Result integration":
158+
test "question mark":
159+
# generics are tricky and buggy, test them more!
160+
proc someFunc2[T](v: T): Future[Result[T, string]] {.async.} =
161+
return ok(v)
162+
proc someFunc[T](v: T): Future[Result[T, string]] {.async.} =
163+
let tmp = ? await someFunc2(v)
164+
return ok(tmp + 2)
165+
166+
proc caller(v: int): Future[Result[int, string]] {.async.} =
167+
return ok(3 + ? await someFunc(v))
168+
169+
check waitFor(testResult()).error() == "string"
170+
171+
check waitFor(caller(42))[] == 42 + 2 + 3

0 commit comments

Comments
 (0)