summary refs log tree commit diff stats
path: root/tests/iter/tyieldintry.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/iter/tyieldintry.nim')
-rw-r--r--tests/iter/tyieldintry.nim104
1 files changed, 73 insertions, 31 deletions
diff --git a/tests/iter/tyieldintry.nim b/tests/iter/tyieldintry.nim
index 35df55c24..e51ab7f0d 100644
--- a/tests/iter/tyieldintry.nim
+++ b/tests/iter/tyieldintry.nim
@@ -1,17 +1,16 @@
 discard """
-targets: "c"
-output: "ok"
+  matrix: "; --experimental:strictdefs; -d:nimOptIters"
+  targets: "c cpp"
 """
-var closureIterResult = newSeq[int]()
 
-# XXX Investigate why this fails now for 'nim cpp'
+var closureIterResult = newSeq[int]()
 
 proc checkpoint(arg: int) =
   closureIterResult.add(arg)
 
 type
-  TestException = object of Exception
-  AnotherException = object of Exception
+  TestError = object of CatchableError
+  AnotherError = object of CatchableError
 
 proc testClosureIterAux(it: iterator(): int, exceptionExpected: bool, expectedResults: varargs[int]) =
   closureIterResult.setLen(0)
@@ -21,7 +20,7 @@ proc testClosureIterAux(it: iterator(): int, exceptionExpected: bool, expectedRe
   try:
     for i in it():
       closureIterResult.add(i)
-  except TestException:
+  except TestError:
     exceptionCaught = true
 
   if closureIterResult != @expectedResults or exceptionCaught != exceptionExpected:
@@ -39,8 +38,8 @@ proc test(it: iterator(): int, expectedResults: varargs[int]) =
 proc testExc(it: iterator(): int, expectedResults: varargs[int]) =
   testClosureIterAux(it, true, expectedResults)
 
-proc raiseException() =
-  raise newException(TestException, "Test exception!")
+proc raiseTestError() =
+  raise newException(TestError, "Test exception!")
 
 block:
   iterator it(): int {.closure.} =
@@ -58,8 +57,8 @@ block:
     yield 0
     try:
       checkpoint(1)
-      raiseException()
-    except TestException:
+      raiseTestError()
+    except TestError:
       checkpoint(2)
       yield 3
       checkpoint(4)
@@ -89,7 +88,7 @@ block:
     yield 0
     try:
       yield 1
-      raiseException()
+      raiseTestError()
       yield 2
     finally:
       checkpoint(3)
@@ -103,8 +102,8 @@ block:
   iterator it(): int {.closure.} =
     try:
       try:
-        raiseException()
-      except AnotherException:
+        raiseTestError()
+      except AnotherError:
         yield 123
       finally:
         checkpoint(3)
@@ -117,8 +116,8 @@ block:
   iterator it(): int {.closure.} =
     try:
       yield 1
-      raiseException()
-    except AnotherException:
+      raiseTestError()
+    except AnotherError:
       checkpoint(123)
     finally:
       checkpoint(2)
@@ -134,12 +133,12 @@ block:
         yield 1
         try:
           yield 2
-          raiseException()
-        except AnotherException:
+          raiseTestError()
+        except AnotherError:
           yield 123
         finally:
           yield 3
-      except AnotherException:
+      except AnotherError:
         yield 124
       finally:
         yield 4
@@ -170,10 +169,10 @@ block:
     try:
       try:
         yield 0
-        raiseException()
+        raiseTestError()
       finally:
         checkpoint(1)
-    except TestException:
+    except TestError:
       yield 2
       return
     finally:
@@ -188,10 +187,10 @@ block:
     try:
       try:
         yield 0
-        raiseException()
+        raiseTestError()
       finally:
         return # Return in finally should stop exception propagation
-    except AnotherException:
+    except AnotherError:
       yield 2
       return
     finally:
@@ -228,9 +227,9 @@ block:
     var foo = 123
     let i = try:
         yield 0
-        raiseException()
+        raiseTestError()
         1
-      except TestException as e:
+      except TestError as e:
         assert(e.msg == "Test exception!")
         case foo
         of 1:
@@ -262,9 +261,9 @@ block:
     template tryexcept: int =
       try:
         yield 1
-        raiseException()
+        raiseTestError()
         123
-      except TestException:
+      except TestError:
         yield 2
         checkpoint(3)
         4
@@ -323,11 +322,11 @@ block:
     for i in 0 .. 1:
       try:
         yield 1
-        raiseException()
-      except TestException as e:
+        raiseTestError()
+      except TestError as e:
         doAssert(e.msg == "Test exception!")
         yield 2
-      except AnotherException:
+      except AnotherError:
         yield 123
       except:
         yield 1234
@@ -483,5 +482,48 @@ block: # nnkChckRange
 
   test(it, 1, 2, 3)
 
-echo "ok"
+block: #17849 - yield in case subject
+  template yieldInCase: int =
+    yield 2
+    3
+
+  iterator it(): int {.closure.} =
+    yield 1
+    case yieldInCase()
+    of 1: checkpoint(11)
+    of 3: checkpoint(13)
+    else: checkpoint(14)
+    yield 5
+
+  test(it, 1, 2, 13, 5)
 
+block: # void iterator
+  iterator it() {.closure.} =
+    try:
+      yield
+    except:
+      discard
+  var a = it
+
+if defined(nimOptIters): # Locals present in only 1 state should be on the stack
+  proc checkOnStack(a: pointer, shouldBeOnStack: bool) =
+    # Quick and dirty way to check if a points to stack
+    var dummy = 0
+    let dummyAddr = addr dummy
+    let distance = abs(cast[int](dummyAddr) - cast[int](a))
+    const requiredDistance = 300
+    if shouldBeOnStack:
+      doAssert(distance <= requiredDistance, "a is not on stack, but should")
+    else:
+      doAssert(distance > requiredDistance, "a is on stack, but should not")
+
+  iterator it(): int {.closure.} =
+    var a = 1
+    var b = 2
+    var c {.liftLocals.} = 3
+    checkOnStack(addr a, true)
+    checkOnStack(addr b, false)
+    checkOnStack(addr c, false)
+    yield a
+    yield b
+  test(it, 1, 2)