diff options
Diffstat (limited to 'tests/iter')
-rw-r--r-- | tests/iter/t1550.nim | 24 | ||||
-rw-r--r-- | tests/iter/t16076.nim | 45 | ||||
-rw-r--r-- | tests/iter/t20891.nim | 28 | ||||
-rw-r--r-- | tests/iter/t21306.nim | 118 | ||||
-rw-r--r-- | tests/iter/t21737.nim | 22 | ||||
-rw-r--r-- | tests/iter/t22148.nim | 15 | ||||
-rw-r--r-- | tests/iter/t22548.nim | 21 | ||||
-rw-r--r-- | tests/iter/t22619.nim | 83 | ||||
-rw-r--r-- | tests/iter/t2771.nim | 25 | ||||
-rw-r--r-- | tests/iter/tanoniter1.nim | 1 | ||||
-rw-r--r-- | tests/iter/tarrayiter.nim | 14 | ||||
-rw-r--r-- | tests/iter/tclosureiters.nim | 39 | ||||
-rw-r--r-- | tests/iter/tgeniteratorinblock.nim | 54 | ||||
-rw-r--r-- | tests/iter/titer.nim | 90 | ||||
-rw-r--r-- | tests/iter/titer11.nim | 1 | ||||
-rw-r--r-- | tests/iter/titer12.nim | 1 | ||||
-rw-r--r-- | tests/iter/titer13.nim | 2 | ||||
-rw-r--r-- | tests/iter/titer2.nim | 2 | ||||
-rw-r--r-- | tests/iter/titer3.nim | 2 | ||||
-rw-r--r-- | tests/iter/titer_issues.nim | 177 | ||||
-rw-r--r-- | tests/iter/titervaropenarray.nim | 2 | ||||
-rw-r--r-- | tests/iter/tmoditer.nim | 2 | ||||
-rw-r--r-- | tests/iter/tpermutations.nim | 2 | ||||
-rw-r--r-- | tests/iter/tshallowcopy_closures.nim | 1 | ||||
-rw-r--r-- | tests/iter/tyieldintry.nim | 104 |
25 files changed, 832 insertions, 43 deletions
diff --git a/tests/iter/t1550.nim b/tests/iter/t1550.nim new file mode 100644 index 000000000..c971943ee --- /dev/null +++ b/tests/iter/t1550.nim @@ -0,0 +1,24 @@ +discard """ + targets: "c js" +""" + +type + A[T] = iterator(x: T): T {.gcsafe, closure.} + +iterator aimp[T](x: T): T {.gcsafe, closure.} = + var total = 0 + while (total < 100): + yield total + total += x + +iterator bimp(y: A[int], z:int): int {.gcsafe, closure.} = + for i in y(z): + yield i + +for x in aimp[int](3): + discard x + +var y = aimp[int] +var z = bimp +for x in z(y, 1): + discard x \ No newline at end of file diff --git a/tests/iter/t16076.nim b/tests/iter/t16076.nim new file mode 100644 index 000000000..2eb409068 --- /dev/null +++ b/tests/iter/t16076.nim @@ -0,0 +1,45 @@ +discard """ + targets: "c js" +""" + +proc main() = + block: # bug #17485 + type + O = ref object + i: int + + iterator t(o: O): int = + if o != nil: + yield o.i + yield 0 + + proc m = + var data = "" + for i in t(nil): + data.addInt i + + doAssert data == "0" + + m() + + + block: # bug #16076 + type + R = ref object + z: int + + var data = "" + + iterator foo(x: int; y: R = nil): int {.inline.} = + if y == nil: + yield x + else: + yield y.z + + for b in foo(10): + data.addInt b + + doAssert data == "10" + +static: main() +main() diff --git a/tests/iter/t20891.nim b/tests/iter/t20891.nim new file mode 100644 index 000000000..34deec41b --- /dev/null +++ b/tests/iter/t20891.nim @@ -0,0 +1,28 @@ +import macros, tables + +var mapping {.compileTime.}: Table[string, NimNode] + +macro register(a: static[string], b: typed): untyped = + mapping[a] = b + +macro getPtr(a: static[string]): untyped = + result = mapping[a] + +proc foo() = + iterator it() {.closure.} = + discard + proc getIterPtr(): pointer {.nimcall.} = + rawProc(it) + register("foo", getIterPtr()) + discard getIterPtr() # Comment either this to make it work +foo() # or this + +proc bar() = + iterator it() {.closure.} = + discard getPtr("foo") # Or this + discard + proc getIterPtr(): pointer {.nimcall.} = + rawProc(it) + register("bar", getIterPtr()) + discard getIterPtr() +bar() diff --git a/tests/iter/t21306.nim b/tests/iter/t21306.nim new file mode 100644 index 000000000..4d0396294 --- /dev/null +++ b/tests/iter/t21306.nim @@ -0,0 +1,118 @@ +discard """ + targets: "c js" +""" + +# bug #21306 +type + FutureState {.pure.} = enum + Pending, Finished, Cancelled, Failed + + FutureBase = ref object of RootObj + state: FutureState + error: ref CatchableError + id: uint + + Future[T] = ref object of FutureBase + closure: iterator(f: Future[T]): FutureBase {.raises: [Defect, CatchableError, Exception], gcsafe.} + value: T + +template setupFutureBase() = + new(result) + result.state = FutureState.Pending + +proc newFutureImpl[T](): Future[T] = + setupFutureBase() + +template newFuture[T](fromProc: static[string] = ""): Future[T] = + newFutureImpl[T]() + +proc internalRead[T](fut: Future[T]): T = + when T isnot void: + return fut.value + +template await[T](f: Future[T]): untyped = + when declared(chronosInternalRetFuture): + when not declaredInScope(chronosInternalTmpFuture): + var chronosInternalTmpFuture {.inject.}: FutureBase = f + else: + chronosInternalTmpFuture = f + + yield chronosInternalTmpFuture + + when T isnot void: + cast[type(f)](chronosInternalTmpFuture).internalRead() + +type + VerifierError {.pure.} = enum + Invalid + MissingParent + UnviableFork + Duplicate + ProcessingCallback = proc() {.gcsafe, raises: [Defect].} + BlockVerifier = + proc(signedBlock: int): + Future[VerifierError] {.gcsafe, raises: [Defect].} + + SyncQueueKind {.pure.} = enum + Forward, Backward + + SyncRequest[T] = object + kind: SyncQueueKind + index: uint64 + slot: uint64 + count: uint64 + item: T + + SyncResult[T] = object + request: SyncRequest[T] + data: seq[ref int] + + SyncQueue[T] = ref object + kind: SyncQueueKind + readyQueue: seq[SyncResult[T]] + blockVerifier: BlockVerifier + +iterator blocks[T](sq: SyncQueue[T], + sr: SyncResult[T]): ref int = + case sq.kind + of SyncQueueKind.Forward: + for i in countup(0, len(sr.data) - 1): + yield sr.data[i] + of SyncQueueKind.Backward: + for i in countdown(len(sr.data) - 1, 0): + yield sr.data[i] + +proc push[T](sq: SyncQueue[T]; sr: SyncRequest[T]; data: seq[ref int]; + processingCb: ProcessingCallback = nil): Future[void] {. + stackTrace: off, gcsafe.} = + iterator push_436208182(chronosInternalRetFuture: Future[void]): FutureBase {. + closure, gcsafe, raises: [Defect, CatchableError, Exception].} = + block: + template result(): auto {.used.} = + {.fatal: "You should not reference the `result` variable inside" & + " a void async proc".} + + let item = default(SyncResult[T]) + for blk in sq.blocks(item): + let res = await sq.blockVerifier(blk[]) + + var resultFuture = newFuture[void]("push") + resultFuture.closure = push_436208182 + return resultFuture + +type + SomeTPeer = ref object + score: int + +proc getSlice(): seq[ref int] = + discard + +template smokeTest(kkind: SyncQueueKind, start, finish: uint64, + chunkSize: uint64) = + var queue: SyncQueue[SomeTPeer] + var request: SyncRequest[SomeTPeer] + discard queue.push(request, getSlice()) + +for k in {SyncQueueKind.Forward}: + for item in [(uint64(1181), uint64(1399), 41'u64)]: + smokeTest(k, item[0], item[1], item[2]) \ No newline at end of file diff --git a/tests/iter/t21737.nim b/tests/iter/t21737.nim new file mode 100644 index 000000000..da06faea7 --- /dev/null +++ b/tests/iter/t21737.nim @@ -0,0 +1,22 @@ +discard """ + action: compile +""" + +template mytoSeq*(iter: untyped): untyped = + var result: seq[typeof(iter)]# = @[] + for x in iter: + result.add(x) + result + +iterator test(dir:int): int = + yield 1234 + +iterator walkGlobKinds (): int = + let dir2 = 123 + let it = mytoSeq(test(dir2)) + +proc main()= + let it = iterator(): int= + for path in walkGlobKinds(): + yield path +main() diff --git a/tests/iter/t22148.nim b/tests/iter/t22148.nim new file mode 100644 index 000000000..9954eed87 --- /dev/null +++ b/tests/iter/t22148.nim @@ -0,0 +1,15 @@ +discard """ + action: compile +""" + +import std/memfiles + +# bug #22148 +proc make*(input: string) = + var inp = memfiles.open(input) + for line in memSlices(inp): + let lineF = MemFile(mem: line.data, size: line.size) + for word in memSlices(lineF, ','): + discard + +make("") # Must call to trigger diff --git a/tests/iter/t22548.nim b/tests/iter/t22548.nim new file mode 100644 index 000000000..b9abb75d0 --- /dev/null +++ b/tests/iter/t22548.nim @@ -0,0 +1,21 @@ +discard """ + action: compile +""" + +type Xxx[T] = object + +iterator x(v: string): char = + var v2: Xxx[int] + + var y: v2.T + + echo y + +proc bbb(vv: string): proc () = + proc xxx() = + for c in x(vv): + echo c + + return xxx + +bbb("test")() diff --git a/tests/iter/t22619.nim b/tests/iter/t22619.nim new file mode 100644 index 000000000..6a98391f3 --- /dev/null +++ b/tests/iter/t22619.nim @@ -0,0 +1,83 @@ +# bug #22619 + +when false: # todo fixme + block: + type + Resource = object + value: int + + Object = object + r {.cursor.}: Resource + s {.cursor.}: seq[Resource] + + var numDestroy = 0 + + proc `=copy`(x: var Resource, y: Resource) {.error.} # disallow full copies + proc `=destroy`(x: Resource) = + inc numDestroy + + proc test() = + # perform the test in procedure so that globals aren't used (their different + # semantics with regards to destruction would interfere) + var + r = Resource(value: 1) # initialize a resource + s = @[Resource(value: 2)] + + # make sure no copy is required in the initializer expression: + var o = Object(r: r, s: s) + + # copying the object doesn't perform a full copy of the cursor fields: + var o2 = o + discard addr(o2) # prevent `o2` from being turned into a cursor + + # check that the fields were shallow-copied: + doAssert o2.r.value == 1 + doAssert o2.s[0].value == 2 + + # make sure no copy is required with normal field assignments: + o.r = r + o.s = s + + + # when `o` and `o2` are destroyed, their destructor must not be called on + # their fields + + test() + + # one call for the `r` local and one for the object in `s` + doAssert numDestroy == 2 + +block: + type Value = distinct int + + var numDestroy = 0 + + when defined(gcRefc): + proc `=destroy`(x: var Value) = + inc numDestroy + else: + proc `=destroy`(x: Value) = + inc numDestroy + + iterator iter(s: seq[Value]): int {.closure.} = + # because it is used across yields, `s2` is lifted into the iterator's + # environment. Since non-ref cursors in object didn't have their hooks + # disabled inside the environments lifted hooks, this led to double + # frees + var s2 {.cursor.} = s + var i = 0 + let L = s2.len + while i < L: + yield s2[i].int + inc i + + proc test() = + var s = @[Value(1), Value(2)] + let cl = iter + # make sure resuming the iterator works: + doAssert cl(s) == 1 + doAssert cl(s) == 2 + doAssert cl(s) == 0 + + test() + doAssert numDestroy == 2 diff --git a/tests/iter/t2771.nim b/tests/iter/t2771.nim new file mode 100644 index 000000000..71a8a9dcd --- /dev/null +++ b/tests/iter/t2771.nim @@ -0,0 +1,25 @@ +discard """ + targets: "c js" +""" + +template t1(i: int): int= + i+1 +template t2(i: int): int= + i+1 + +doAssert t1(10).t2() == 12 + + +template it1(i: int): iterator(): int = + iterator result(): int {.closure, gensym.} = + yield i+1 + result + +template it2(iter: iterator(): int): iterator(): int = + iterator result(): int {.closure, gensym.} = + yield iter()+1 + result + +let x2 = it1(10).it2() + +doAssert x2() == 12 diff --git a/tests/iter/tanoniter1.nim b/tests/iter/tanoniter1.nim index 9f0d0a74b..fee16497f 100644 --- a/tests/iter/tanoniter1.nim +++ b/tests/iter/tanoniter1.nim @@ -1,4 +1,5 @@ discard """ + targets: "c js" output: '''1 2 3 diff --git a/tests/iter/tarrayiter.nim b/tests/iter/tarrayiter.nim new file mode 100644 index 000000000..eb7ba591a --- /dev/null +++ b/tests/iter/tarrayiter.nim @@ -0,0 +1,14 @@ +block: + iterator `[]`(a: int, r: int): int = + for q in 0 .. r: + yield a + + for val in 10[2]: discard + + type Custom = distinct string + + iterator `[]`(a: Custom, r: int): char = + for q in 0 .. r: + yield a.string[q] + + for val in Custom("test")[2]: discard \ No newline at end of file diff --git a/tests/iter/tclosureiters.nim b/tests/iter/tclosureiters.nim index 345a4867a..4a2639852 100644 --- a/tests/iter/tclosureiters.nim +++ b/tests/iter/tclosureiters.nim @@ -1,4 +1,5 @@ discard """ + targets: "c js" output: '''0 1 2 @@ -19,7 +20,18 @@ discard """ 0 1 2 -70''' +70 +0 +(1, 1) +(1, 2) +(1, 3) +(2, 1) +(2, 2) +(2, 3) +(3, 1) +(3, 2) +(3, 3) +''' """ when true: @@ -96,7 +108,7 @@ proc unused = iterator lineIter2*(filename: string): string {.closure.} = var f = open(filename, bufSize=8000) defer: close(f) # <-- commenting defer "solves" the problem - var res = TaintedString(newStringOfCap(80)) + var res = newStringOfCap(80) while f.readLine(res): yield res proc unusedB = @@ -139,3 +151,26 @@ iterator filesIt(path: string): auto {.closure.} = let prefix = path.splitPath[1] for f in files: yield prefix / f + +# bug #13815 +when not defined(js): + var love = iterator: int {.closure.} = + yield cast[type( + block: + var a = 0 + yield a + a)](0) + + for i in love(): + echo i +else: + echo 0 + +# bug #18474 +iterator pairs(): (int, int) {.closure.} = + for i in 1..3: + for j in 1..3: + yield (i, j) + +for pair in pairs(): + echo pair diff --git a/tests/iter/tgeniteratorinblock.nim b/tests/iter/tgeniteratorinblock.nim new file mode 100644 index 000000000..2ab903996 --- /dev/null +++ b/tests/iter/tgeniteratorinblock.nim @@ -0,0 +1,54 @@ +discard """ + output: '''30 +60 +90 +150 +180 +210 +240 +60 +180 +240 +[60, 180, 240] +[60, 180]''' +""" +import std/enumerate + +template map[T; Y](i: iterable[T], fn: proc(x: T): Y): untyped = + iterator internal(): Y {.gensym.} = + for it in i: + yield fn(it) + internal() + +template filter[T](i: iterable[T], fn: proc(x: T): bool): untyped = + iterator internal(): T {.gensym.} = + for it in i: + if fn(it): + yield it + internal() + +template group[T](i: iterable[T], amount: static int): untyped = + iterator internal(): array[amount, T] {.gensym.} = + var val: array[amount, T] + for ind, it in enumerate i: + val[ind mod amount] = it + if ind mod amount == amount - 1: + yield val + internal() + +var a = [10, 20, 30, 50, 60, 70, 80] + +proc mapFn(x: int): int = x * 3 +proc filterFn(x: int): bool = x mod 20 == 0 + +for x in a.items.map(mapFn): + echo x + +for y in a.items.map(mapFn).filter(filterFn): + echo y + +for y in a.items.map(mapFn).filter(filterFn).group(3): + echo y + +for y in a.items.map(mapFn).filter(filterFn).group(2): + echo y diff --git a/tests/iter/titer.nim b/tests/iter/titer.nim index 22be1bad5..b03d43f36 100644 --- a/tests/iter/titer.nim +++ b/tests/iter/titer.nim @@ -55,3 +55,93 @@ const for i in 0..len(stringArray)-1: echo(stringArray[i]) +# bug #15360 + +type Rule[T] = (int, T) + +var t: seq[Rule[int]] +for (c, t) in t: + discard + + + +import std/sugar + +# bug #14165 +iterator log_nodups_hamming(): int {.inline.} = + let lb3 = 1 + let lb4 = 123 + proc mul3(): int = lb3 + lb4 + yield mul3() + +for h in log_nodups_hamming(): + break +for h in log_nodups_hamming(): + break +for h in log_nodups_hamming(): + break + +# bug #18536 +iterator envPairs*(): int = + var foo: seq[int] + proc fun() = + foo = @[] + fun() + yield 3 + +proc main() = + for a in envPairs(): + discard + for a in envPairs(): + discard +static: main() +main() + +# bug #6269 +iterator makeFn(outer_val: int): proc(a: int): int = + for i in 0..1: + yield proc(a:int): int = + return a + i.int + +let v1 = 42 + +let res = collect: + for fn1 in makeFn(v1): + let v2 = fn1(v1) + for fn2 in makeFn(v2): + fn2(v2) + +doAssert res == @[42, 43, 43, 44] + +block: # bug #21110 + iterator p(): int = + when nimvm: + yield 0 + else: + yield 0 + + template foo = + for k in p(): + let m = "" + proc e() = discard m & "" + e() + static: foo() + foo() + + +# bug #15924 +iterator walk(): (int, int) {.closure.} = + yield (10,11) + +for (i,j) in walk(): + doAssert i == 10 + +proc main123() = + let x = false + iterator it(): (bool, bool) {.closure.} = # normally {.closure.} here makes #21476 work + discard x + + for (_, _) in it(): + discard + +main123() diff --git a/tests/iter/titer11.nim b/tests/iter/titer11.nim index 2b39c74f7..153b3c29a 100644 --- a/tests/iter/titer11.nim +++ b/tests/iter/titer11.nim @@ -1,4 +1,5 @@ discard """ +targets: "c js" output: ''' [ 1 diff --git a/tests/iter/titer12.nim b/tests/iter/titer12.nim index f7fc64da4..f264a0e82 100644 --- a/tests/iter/titer12.nim +++ b/tests/iter/titer12.nim @@ -1,4 +1,5 @@ discard """ +targets: "c js" output: ''' Selecting 2 1.0 diff --git a/tests/iter/titer13.nim b/tests/iter/titer13.nim index 0d4a399c5..086c40ca4 100644 --- a/tests/iter/titer13.nim +++ b/tests/iter/titer13.nim @@ -72,7 +72,7 @@ block: echo a block t5859: - proc flatIterator[T](s: openarray[T]): auto {.noSideEffect.}= + proc flatIterator[T](s: openArray[T]): auto {.noSideEffect.}= result = iterator(): auto = when (T is not seq|array): for item in s: diff --git a/tests/iter/titer2.nim b/tests/iter/titer2.nim index f60aed73a..975cc786c 100644 --- a/tests/iter/titer2.nim +++ b/tests/iter/titer2.nim @@ -17,7 +17,7 @@ type TSlotEnum = enum seEmpty, seFilled, seDeleted TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - TTable* {.final.}[A, B] = object + TTable*[A, B] {.final.} = object data: TKeyValuePairSeq[A, B] counter: int diff --git a/tests/iter/titer3.nim b/tests/iter/titer3.nim index 9dcfd7be5..defd56c98 100644 --- a/tests/iter/titer3.nim +++ b/tests/iter/titer3.nim @@ -26,7 +26,7 @@ var x = [[1, 2, 3], [4, 5, 6]] for y in iter1(x[0]): write(stdout, $y) writeLine(stdout, "") -# ensure closure and inline iterators have the same behaviour wrt +# ensure closure and inline iterators have the same behaviour regarding # parameter passing iterator clo(a: int): int {.closure.} = diff --git a/tests/iter/titer_issues.nim b/tests/iter/titer_issues.nim index 872ebe2b7..c82b3902d 100644 --- a/tests/iter/titer_issues.nim +++ b/tests/iter/titer_issues.nim @@ -1,4 +1,5 @@ discard """ + target: "c js" output: ''' 0 1 @@ -27,6 +28,21 @@ end 9014 9016 9018 +@[1, 2] +@[1, 2, 3] +1 +nested finally +outer finally +nested finally +outer finally +nested finally +outer finally +nested finally +outer finally +In defer +trying +exception caught +finally block ''' """ @@ -133,7 +149,7 @@ block t3837_chained: block t3221_complex: - iterator permutations[T](ys: openarray[T]): seq[T] = + iterator permutations[T](ys: openArray[T]): seq[T] = var d = 1 c = newSeq[int](ys.len) @@ -191,7 +207,7 @@ block t3499_keepstate: break # bug #3499 last snippet fixed - # bug 705 last snippet fixed + # bug #705 last snippet fixed @@ -225,8 +241,8 @@ block t2023_objiter: block: - # issue #13739 - iterator myIter(arg: openarray[int]): int = + # bug #13739 + iterator myIter(arg: openArray[int]): int = var tmp = 0 let len = arg.len while tmp < len: @@ -240,3 +256,156 @@ block: echo x someProc() + +block: + # bug #12576 + iterator ff(sq: varargs[seq[int]]): int = + for x in sq: + echo x + + for x in ff(@[1, 2], @[1, 2, 3]): + echo x + + +# bug #19575 + +iterator bb() {.closure.} = + while true: + try: discard + except: break + finally: break + +var a = bb + +iterator cc() {.closure.} = + while true: + try: discard + except: + if true: + break + finally: + if true: + break + +var a2 = cc + +# bug #16876 +block: + iterator a(num: int): int {.closure.} = + if num == 1: + yield num + else: + for i in a(num - 1): + yield i + + for i in a(5): + echo i + +block: + # bug #19911 (return in nested try) + + # try yield -> try + iterator p1: int {.closure.} = + try: + yield 0 + try: + return + finally: + echo "nested finally" + echo "shouldn't run" + finally: + echo "outer finally" + echo "shouldn't run" + + for _ in p1(): + discard + + # try -> try yield + iterator p2: int {.closure.} = + try: + try: + yield 0 + return + finally: + echo "nested finally" + echo "shouldn't run" + finally: + echo "outer finally" + echo "shouldn't run" + + for _ in p2(): + discard + + # try yield -> try yield + iterator p3: int {.closure.} = + try: + yield 0 + try: + yield 0 + return + finally: + echo "nested finally" + echo "shouldn't run" + finally: + echo "outer finally" + echo "shouldn't run" + + for _ in p3(): + discard + + # try -> try + iterator p4: int {.closure.} = + try: + try: + return + finally: + echo "nested finally" + echo "shouldn't run" + finally: + echo "outer finally" + echo "shouldn't run" + + for _ in p4(): + discard + +# bug #18824 +iterator poc_iterator: int {.closure.} = + block bug18824: + try: + break bug18824 + finally: + echo "In defer" + +for _ in poc_iterator(): + discard + +# bug #20624 +iterator tryFinally() {.closure.} = + block route: + try: + echo "trying" + raise + except: + echo "exception caught" + break route + finally: + echo "finally block" + +var x = tryFinally +x() + +block: # bug #24033 + type Query = ref object + + iterator pairs(query: Query): (int, (string, float32)) = + var output: (int, (string, float32)) = (0, ("foo", 3.14)) + for id in @[0, 1, 2]: + output[0] = id + yield output + + var collections: seq[(int, string, string)] + + for id, (str, num) in Query(): + collections.add (id, str, $num) + + doAssert collections[1] == (1, "foo", "3.14") diff --git a/tests/iter/titervaropenarray.nim b/tests/iter/titervaropenarray.nim index 4469fdcf5..b2fe71ceb 100644 --- a/tests/iter/titervaropenarray.nim +++ b/tests/iter/titervaropenarray.nim @@ -1,6 +1,6 @@ discard """ output: "123" - targets: "C" + targets: "c cpp" """ # Try to break the transformation pass: iterator iterAndZero(a: var openArray[int]): int = diff --git a/tests/iter/tmoditer.nim b/tests/iter/tmoditer.nim index b92a416fb..99e5b642d 100644 --- a/tests/iter/tmoditer.nim +++ b/tests/iter/tmoditer.nim @@ -43,7 +43,7 @@ proc `=copy`(dst: var NonCopyable, src: NonCopyable) {.error.} proc `=sink`(dst: var NonCopyable, src: NonCopyable) = dst.x = src.x -iterator lentItems[T](a: openarray[T]): lent T = +iterator lentItems[T](a: openArray[T]): lent T = for i in 0..a.high: yield a[i] diff --git a/tests/iter/tpermutations.nim b/tests/iter/tpermutations.nim index c5067ba31..30a66460f 100644 --- a/tests/iter/tpermutations.nim +++ b/tests/iter/tpermutations.nim @@ -12,7 +12,7 @@ perm: 6778800.0 det: 0.0 import sequtils, sugar -iterator permutations*[T](ys: openarray[T]): tuple[perm: seq[T], sign: int] = +iterator permutations*[T](ys: openArray[T]): tuple[perm: seq[T], sign: int] = var d = 1 c = newSeq[int](ys.len) diff --git a/tests/iter/tshallowcopy_closures.nim b/tests/iter/tshallowcopy_closures.nim index 279e7d950..06b04a788 100644 --- a/tests/iter/tshallowcopy_closures.nim +++ b/tests/iter/tshallowcopy_closures.nim @@ -1,4 +1,5 @@ discard """ + matrix: "--mm:refc" ccodecheck: "!@('{' \\s* 'NI HEX3Astate;' \\s* '}')" output: ''' a1 10 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) |