Skip to content

Commit 06427ee

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 0035f4f commit 06427ee

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

chronos.nimble

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ license = "MIT or Apache License 2.0"
88
skipDirs = @["tests"]
99

1010
requires "nim >= 1.2.0",
11-
"stew",
11+
"stew#assign-result",
1212
"bearssl",
1313
"httputils",
1414
"unittest2"

chronos/asyncmacro2.nim

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
156156

157157
procBody = prc.body.processBody(castFutureSym, baseType)
158158

159+
# Support `let x = ? await ...`
160+
assignResultSym = ident "assignResult?"
161+
assignResult = quote do:
162+
when declared(Result):
163+
template `assignResultSym`(v: Result) {.used.} =
164+
complete(`castFutureSym`, v)
165+
159166
# don't do anything with forward bodies (empty)
160167
if procBody.kind != nnkEmpty:
161168
let
@@ -185,7 +192,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
185192

186193
completeDecl = completeWithNode(castFutureSym, baseType, procBodyBlck)
187194

188-
closureBody = newStmtList(resultDecl, completeDecl)
195+
closureBody = newStmtList(assignResult, resultDecl, completeDecl)
189196

190197
internalFutureParameter = nnkIdentDefs.newTree(
191198
internalFutureSym, newIdentNode("FutureBase"), newEmptyNode())

tests/testmacro.nim

Lines changed: 29 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
@@ -226,3 +240,18 @@ suite "Closure iterator's exception transformation issues":
226240

227241
waitFor(x())
228242

243+
suite "Result integration":
244+
test "question mark":
245+
# generics are tricky and buggy, test them more!
246+
proc someFunc2[T](v: T): Future[Result[T, string]] {.async.} =
247+
return ok(v)
248+
proc someFunc[T](v: T): Future[Result[T, string]] {.async.} =
249+
let tmp = ? await someFunc2(v)
250+
return ok(tmp + 2)
251+
252+
proc caller(v: int): Future[Result[int, string]] {.async.} =
253+
return ok(3 + ? await someFunc(v))
254+
255+
check waitFor(testResult()).error() == "string"
256+
257+
check waitFor(caller(42))[] == 42 + 2 + 3

0 commit comments

Comments
 (0)