summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@gmail.com>2016-06-15 16:55:21 +0100
committerDominik Picheta <dominikpicheta@gmail.com>2016-06-15 16:56:28 +0100
commit500aa0cb3f17d28071a9be74047f5600e1a4f6df (patch)
tree12e989530223bd95550aa14b08180ab73c9064ec
parent5f83e869fa000598ab38866485dc8e58dd7d90d0 (diff)
downloadNim-500aa0cb3f17d28071a9be74047f5600e1a4f6df.tar.gz
Reverts 1446dc87c3. Fixes #4333. Fixes #4170.
-rw-r--r--lib/pure/asyncdispatch.nim10
-rw-r--r--tests/async/tasyncexceptions.nim2
-rw-r--r--tests/async/tawaitsemantics.nim59
3 files changed, 65 insertions, 6 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 82166902f..c5b516b39 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -1526,13 +1526,11 @@ proc processBody(node, retFutureSym: NimNode,
       case node[1].kind
       of nnkIdent, nnkInfix:
         # await x
-        result = newNimNode(nnkStmtList, node)
-        var futureValue: NimNode
-        result.useVar(node[1], futureValue, futureValue, node)
-        # -> yield x
-        # -> x.read()
+        # await x or y
+        result = newNimNode(nnkYieldStmt, node).add(node[1]) # -> yield x
       of nnkCall, nnkCommand:
         # await foo(p, x)
+        # await foo p, x
         var futureValue: NimNode
         result.createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
                   futureValue, node)
@@ -1738,7 +1736,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
   result[6] = outerProcBody
 
   #echo(treeRepr(result))
-  #if prc[0].getName == "g":
+  #if prc[0].getName == "testInfix":
   #  echo(toStrLit(result))
 
 macro async*(prc: stmt): stmt {.immediate.} =
diff --git a/tests/async/tasyncexceptions.nim b/tests/async/tasyncexceptions.nim
index aab08e30f..efe31ef27 100644
--- a/tests/async/tasyncexceptions.nim
+++ b/tests/async/tasyncexceptions.nim
@@ -5,6 +5,8 @@ discard """
 """
 import asyncdispatch
 
+# Note: This is a test case for a bug.
+
 proc accept(): Future[int] {.async.} =
   await sleepAsync(100)
   result = 4
diff --git a/tests/async/tawaitsemantics.nim b/tests/async/tawaitsemantics.nim
new file mode 100644
index 000000000..3e0c3903e
--- /dev/null
+++ b/tests/async/tawaitsemantics.nim
@@ -0,0 +1,59 @@
+discard """
+  file: "tawaitsemantics.nim"
+  exitcode: 0
+  output: '''
+Error caught
+Test infix
+Test call
+'''
+"""
+
+import asyncdispatch
+
+# This tests the behaviour of 'await' under different circumstances.
+# For example, when awaiting Future variable and this future has failed the
+# exception shouldn't be raised as described here
+# https://github.com/nim-lang/Nim/issues/4170
+
+proc thrower(): Future[void] =
+  result = newFuture[void]()
+  result.fail(newException(Exception, "Test"))
+
+proc dummy: Future[void] =
+  result = newFuture[void]()
+  result.complete()
+
+proc testInfix() {.async.} =
+  # Test the infix operator semantics.
+  var fut = thrower()
+  var fut2 = dummy()
+  await fut or fut2 # Shouldn't raise.
+  # TODO: what about: await thrower() or fut2?
+
+proc testCall() {.async.} =
+  await thrower()
+
+proc tester() {.async.} =
+  # Test that we can handle exceptions without 'try'
+  var fut = thrower()
+  doAssert fut.finished
+  doAssert fut.failed
+  doAssert fut.error.msg == "Test"
+  await fut # We are awaiting a 'Future', so no `read` occurs.
+  doAssert fut.finished
+  doAssert fut.failed
+  doAssert fut.error.msg == "Test"
+  echo("Error caught")
+
+  fut = testInfix()
+  await fut
+  doAssert fut.finished
+  doAssert(not fut.failed)
+  echo("Test infix")
+
+  fut = testCall()
+  await fut
+  doAssert fut.failed
+  echo("Test call")
+
+waitFor(tester())