diff options
Diffstat (limited to 'tests/ccgbugs')
54 files changed, 977 insertions, 196 deletions
diff --git a/tests/ccgbugs/m1/defs.nim b/tests/ccgbugs/m1/defs.nim new file mode 100644 index 000000000..ed78d8b72 --- /dev/null +++ b/tests/ccgbugs/m1/defs.nim @@ -0,0 +1,4 @@ +type MyObj* = object + field1*: int + s*: string + ch*: char diff --git a/tests/ccgbugs/m19445.c b/tests/ccgbugs/m19445.c new file mode 100644 index 000000000..74c23d4b4 --- /dev/null +++ b/tests/ccgbugs/m19445.c @@ -0,0 +1,3 @@ +#include "m19445.h" + +const Foo f = {10, 20, 30, 40}; \ No newline at end of file diff --git a/tests/ccgbugs/m2/defs.nim b/tests/ccgbugs/m2/defs.nim new file mode 100644 index 000000000..798d1fea8 --- /dev/null +++ b/tests/ccgbugs/m2/defs.nim @@ -0,0 +1,4 @@ +type MyObj* = object + s*: string + field1*: int + ch*: char diff --git a/tests/ccgbugs/mstatic_assert.nim b/tests/ccgbugs/mstatic_assert.nim new file mode 100644 index 000000000..dbf9c03d1 --- /dev/null +++ b/tests/ccgbugs/mstatic_assert.nim @@ -0,0 +1,6 @@ +{.emit:""" +NIM_STATIC_ASSERT(sizeof(bool) == 1, ""); +#warning "foo2" +NIM_STATIC_ASSERT(sizeof(bool) == 2, ""); +#warning "foo3" +""".} diff --git a/tests/ccgbugs/t10128.nim b/tests/ccgbugs/t10128.nim new file mode 100644 index 000000000..48970916f --- /dev/null +++ b/tests/ccgbugs/t10128.nim @@ -0,0 +1,18 @@ +# bug #10128 +let data = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" +var seq2 = newSeq[char](data.len) +for i in 0..<data.len: + seq2[i] = data[i] + +let c = '\128' + +# case 1 +doAssert data[c.int] == 'y' +doAssert seq2[c.int] == 'y' + +proc play(x: openArray[char]) = + doAssert x[c.int] == 'y' + +# case2 +play(data) +play(seq2) \ No newline at end of file diff --git a/tests/ccgbugs/t10964.nim b/tests/ccgbugs/t10964.nim new file mode 100644 index 000000000..c19db6997 --- /dev/null +++ b/tests/ccgbugs/t10964.nim @@ -0,0 +1,7 @@ +func test*(input: var openArray[int32], start: int = 0, fin: int = input.len - 1) = + discard + +var someSeq = @[1'i32] + +test(someSeq) +# bug with gcc 14 \ No newline at end of file diff --git a/tests/ccgbugs/t13062.nim b/tests/ccgbugs/t13062.nim new file mode 100644 index 000000000..cfda1da7c --- /dev/null +++ b/tests/ccgbugs/t13062.nim @@ -0,0 +1,33 @@ +discard """ + matrix: "--mm:refc; --mm:orc" + targets: "c cpp" +""" + +import atomics + +type + Pledge* {.exportc.} = object + p: PledgePtr + + PledgeKind {.exportc.} = enum + Single + Iteration + + PledgePtr {.exportc.} = ptr object + case kind: PledgeKind + of Single: + impl: PledgeImpl + of Iteration: + discard + + PledgeImpl {.exportc.} = object + fulfilled: Atomic[bool] + +var x: Pledge +when defined(cpp): + # TODO: fixme + discard "it doesn't work for refc/orc because of contrived `Atomic` in cpp" +elif defined(gcRefc): + doAssert x.repr == "[p = nil]" +else: # fixme # bug #20081 + doAssert x.repr == "Pledge(p: nil)" diff --git a/tests/ccgbugs/t13902.nim b/tests/ccgbugs/t13902.nim new file mode 100644 index 000000000..fd4f76d15 --- /dev/null +++ b/tests/ccgbugs/t13902.nim @@ -0,0 +1,12 @@ + +#issue #13902 +block: + type Slot = distinct uint64 + var s = Slot(1) + proc `$`(x: Slot): string {.borrow.} + proc `+=`(x: var Slot, y: uint64) {.borrow.} + # test was failing with either 0 or 2 echos but not with 1 echo + # echo "s = ", s + s += 1 + # echo "s = ", s + doAssert s.uint64 == 2, $s # was failing, showing 18419607611339964418 diff --git a/tests/ccgbugs/t15428.nim b/tests/ccgbugs/t15428.nim new file mode 100644 index 000000000..d9ae8ff16 --- /dev/null +++ b/tests/ccgbugs/t15428.nim @@ -0,0 +1,22 @@ +discard """ + cmd: "nim $target --mm:refc $file" + output: '''5 +5 +[1, 2, 3, 4, 5] +(data: [1, 2, 3, 4, 5]) +''' +""" + +proc take[T](f: openArray[T]) = + echo f.len +let f = @[0,1,2,3,4] +take(f.toOpenArray(0,4)) + +{.experimental: "views".} +type + Foo = object + data: openArray[int] +let f2 = Foo(data: [1,2,3,4,5]) +echo f2.data.len +echo f2.data +echo f2 \ No newline at end of file diff --git a/tests/ccgbugs/t16027.nim b/tests/ccgbugs/t16027.nim new file mode 100644 index 000000000..58f15eb6e --- /dev/null +++ b/tests/ccgbugs/t16027.nim @@ -0,0 +1,13 @@ +discard """ + ccodecheck: "__restrict__" + action: compile + joinable: false +""" + +# see bug #16027 +iterator myitems(s: seq[int]): int = + var data {.codegenDecl: "$# __restrict__ $#".} : ptr int = nil + yield 1 + +for i in @[1].myitems: + discard diff --git a/tests/ccgbugs/t16374.nim b/tests/ccgbugs/t16374.nim new file mode 100644 index 000000000..8ccfa4815 --- /dev/null +++ b/tests/ccgbugs/t16374.nim @@ -0,0 +1,38 @@ +discard """ + matrix: "--gc:refc; --gc:orc" +""" + +block: + iterator mvalues(t: var seq[seq[int]]): var seq[int] = + yield t[0] + + var t: seq[seq[int]] + + while false: + for v in t.mvalues: + discard + + proc ok = + while false: + for v in t.mvalues: + discard + + ok() + +block: + iterator mvalues(t: var seq[seq[int]]): lent seq[int] = + yield t[0] + + var t: seq[seq[int]] + + while false: + for v in t.mvalues: + discard + + proc ok = + while false: + for v in t.mvalues: + discard + + ok() + diff --git a/tests/ccgbugs/t19445.nim b/tests/ccgbugs/t19445.nim new file mode 100644 index 000000000..b6e8d028c --- /dev/null +++ b/tests/ccgbugs/t19445.nim @@ -0,0 +1,13 @@ +discard """ + matrix: "--nimcache:tests/ccgbugs/nimcache19445 --cincludes:nimcache19445 --header:m19445" + targets: "c" +""" + +# bug #19445 +type + Foo* {.exportc.} = object + a*, b*, c*, d*: int + +proc dummy(): Foo {.exportc.} = discard + +{.compile:"m19445.c".} \ No newline at end of file diff --git a/tests/ccgbugs/t20139.nim b/tests/ccgbugs/t20139.nim new file mode 100644 index 000000000..4592b994d --- /dev/null +++ b/tests/ccgbugs/t20139.nim @@ -0,0 +1,10 @@ +discard """ + joinable: false +""" + +# bug #20139 +import m1/defs as md1 +import m2/defs as md2 + +doAssert $(md1.MyObj(field1: 1)) == """(field1: 1, s: "", ch: '\x00')""" +doAssert $(md2.MyObj(field1: 1)) == """(s: "", field1: 1, ch: '\x00')""" diff --git a/tests/ccgbugs/t20141.nim b/tests/ccgbugs/t20141.nim new file mode 100644 index 000000000..60e130690 --- /dev/null +++ b/tests/ccgbugs/t20141.nim @@ -0,0 +1,27 @@ +discard """ + joinable: false +""" + +# bug #20141 +type + A = object + B = object + U = proc() + +proc m(h: var B) = discard + +template n[T, U](x: U): T = + static: doAssert true + cast[ptr T](addr x)[] + +proc k() = + var res: A + m(n[B, A](res)) + +proc w(mounter: U) = discard + +proc mount(proto: U) = discard +proc v() = mount k + +# This is required for failure +w(v) diff --git a/tests/ccgbugs/t20787.nim b/tests/ccgbugs/t20787.nim new file mode 100644 index 000000000..c2d848c2c --- /dev/null +++ b/tests/ccgbugs/t20787.nim @@ -0,0 +1,4 @@ +type + Obj = object + f: UncheckedArray[byte] +let o = new Obj \ No newline at end of file diff --git a/tests/ccgbugs/t21116.nim b/tests/ccgbugs/t21116.nim new file mode 100644 index 000000000..cc77de198 --- /dev/null +++ b/tests/ccgbugs/t21116.nim @@ -0,0 +1,10 @@ +discard """ + targets: "c cpp" + disabled: windows +""" +# bug #21116 +import std/os + +proc p(glob: string) = + for _ in walkFiles(glob): discard +p("dir/*") diff --git a/tests/ccgbugs/t21972.nim b/tests/ccgbugs/t21972.nim new file mode 100644 index 000000000..58d0cfc62 --- /dev/null +++ b/tests/ccgbugs/t21972.nim @@ -0,0 +1,33 @@ +discard """ + targets: "c cpp" + outputsub: "Error: unhandled exception: Err2 [IOError]" + exitcode: "1" +""" + +proc bar(x: var int) = + inc x + if x == 3: + raise newException(ValueError, "H0") + + elif x == 5: + raise newException(IOError, "H1") + + elif x > 7: + raise newException(IOError, "H2") + + +proc foo() = + var i = 0 + while true: + try: + bar(i) + echo i + + except ValueError: + debugEcho("ValueError") + + except IOError: + raise newException(IOError, "Err2") + +when isMainModule: + foo() \ No newline at end of file diff --git a/tests/ccgbugs/t21995.nim b/tests/ccgbugs/t21995.nim new file mode 100644 index 000000000..0ec88aa59 --- /dev/null +++ b/tests/ccgbugs/t21995.nim @@ -0,0 +1,9 @@ +discard """ + targets: "c cpp" + output: "Hi!" +""" + +try: + raise +except: + echo "Hi!" \ No newline at end of file diff --git a/tests/ccgbugs/t22462.nim b/tests/ccgbugs/t22462.nim new file mode 100644 index 000000000..9adfbb19b --- /dev/null +++ b/tests/ccgbugs/t22462.nim @@ -0,0 +1,20 @@ +discard """ + action: "run" + output: ''' +1 +1 +1 +''' + matrix: "--mm:refc" + targets: "c cpp" +""" + +type Object = object + someComplexType: seq[int] + index: Natural + +func newObject(): Object = result.index.inc + +for i in 1..3: + let o = newObject() + echo o.index diff --git a/tests/ccgbugs/t23796.nim b/tests/ccgbugs/t23796.nim new file mode 100644 index 000000000..421ec04d8 --- /dev/null +++ b/tests/ccgbugs/t23796.nim @@ -0,0 +1,25 @@ +discard """ + targets: "c cpp" +""" + +# bug #23796 + +{.emit: """ +#ifdef __cplusplus +extern "C" { +#endif + +void fooArr(float data[3]) {} +void fooIntArr(int id, float data[3]) {} + +#ifdef __cplusplus +} +#endif +""".} + +proc fooArr(data: var array[3, cfloat]) {.importc.} +proc fooIntArr(id: cint, data: var array[3, cfloat]) {.importc, nodecl.} + +var arr = [cfloat 1, 2, 3] +fooArr(arr) +fooIntArr(1, arr) diff --git a/tests/ccgbugs/t2procs.nim b/tests/ccgbugs/t2procs.nim new file mode 100644 index 000000000..d8b7a2815 --- /dev/null +++ b/tests/ccgbugs/t2procs.nim @@ -0,0 +1,18 @@ +discard """ + output: '''before +1 +before +2''' +""" + +proc fn[T1, T2](a: T1, b: T2) = + a(1) + b(2) + +fn( (proc(x: int) = + echo "before" # example block, can span multiple lines + echo x), + (proc (y: int) = + echo "before" + echo y) +) diff --git a/tests/ccgbugs/t5296.nim b/tests/ccgbugs/t5296.nim index 990b4bee2..8fbed35c4 100644 --- a/tests/ccgbugs/t5296.nim +++ b/tests/ccgbugs/t5296.nim @@ -1,6 +1,7 @@ discard """ cmd: "nim c -d:release $file" -output: 1 +output: '''1 +-1''' """ proc bug() : void = @@ -12,3 +13,9 @@ proc bug() : void = echo x bug() + +# bug #19051 +type GInt[T] = int + +var a = 1 +echo -a diff --git a/tests/ccgbugs/t6756.nim b/tests/ccgbugs/t6756.nim index 5170a99f4..5990eba58 100644 --- a/tests/ccgbugs/t6756.nim +++ b/tests/ccgbugs/t6756.nim @@ -10,7 +10,7 @@ type v: T template templ(o: A, op: untyped): untyped = - type T = type(o.v) + type T = typeof(o.v) var res: A[T] diff --git a/tests/ccgbugs/t8967.nim b/tests/ccgbugs/t8967.nim index e342b7eae..0301a2e4f 100644 --- a/tests/ccgbugs/t8967.nim +++ b/tests/ccgbugs/t8967.nim @@ -4,7 +4,11 @@ discard """ import marshal -let orig: set[char] = {'A'..'Z'} -let m = $$orig -let old = to[set[char]](m) -doAssert orig - old == {} +template main() = + let orig: set[char] = {'A'..'Z'} + let m = $$orig + let old = to[set[char]](m) + doAssert orig - old == {} + +static: main() +main() diff --git a/tests/ccgbugs/t9286.nim b/tests/ccgbugs/t9286.nim index 8a45a7bf6..2fec23307 100644 --- a/tests/ccgbugs/t9286.nim +++ b/tests/ccgbugs/t9286.nim @@ -7,7 +7,7 @@ type Foo = ref object i: int proc next(foo: Foo): Option[Foo] = - try: assert(foo.i == 0) + try: doAssert(foo.i == 0) except: return # 2º: none return some(foo) # 1º: some @@ -17,6 +17,6 @@ proc test = while isSome(opt) and foo.i < 10: inc(foo.i) opt = next(foo) # 2º None - assert foo.i == 1, $foo.i + doAssert foo.i == 1, $foo.i test() diff --git a/tests/ccgbugs/t9655.nim b/tests/ccgbugs/t9655.nim new file mode 100644 index 000000000..29fb903a4 --- /dev/null +++ b/tests/ccgbugs/t9655.nim @@ -0,0 +1,30 @@ +discard """ + action: "compile" +""" + +import std/[asynchttpserver, asyncdispatch] +import std/[strformat] + +proc main() = + let local = "123" + + proc serveIndex(req: Request) {.async, gcsafe.} = + await req.respond(Http200, &"{local}") + + proc serve404(req: Request) {.async, gcsafe.} = + echo req.url.path + await req.respond(Http404, "not found") + + proc serve(req: Request) {.async, gcsafe.} = + let handler = case req.url.path: + of "/": + serveIndex + else: + serve404 + await handler(req) + + let server = newAsyncHttpServer() + waitFor server.serve(Port(8080), serve, address = "127.0.0.1") + +when isMainModule: + main() diff --git a/tests/ccgbugs/targ_lefttoright.nim b/tests/ccgbugs/targ_lefttoright.nim new file mode 100644 index 000000000..a0adce157 --- /dev/null +++ b/tests/ccgbugs/targ_lefttoright.nim @@ -0,0 +1,71 @@ +discard """ + nimout: '''1,2 +2,3 +2,2 +1,2 +1,2 +2,2 +1,2 +''' + output: '''1,2 +2,3 +1,2 +2,2 +1,2 +1,2 +2,2 +1,2 +''' + cmd: "nim c --gc:orc $file" +""" + +template test = + proc say(a, b: int) = + echo a,",",b + + var a = 1 + say a, (a += 1; a) #1,2 + + var b = 1 + say (b += 1; b), (b += 1; b) #2,3 + + type C {.byRef.} = object + i: int + + proc say(a, b: C) = + echo a.i,",",b.i + + proc `+=`(x: var C, y: C) = x.i += y.i + + var c = C(i: 1) + when nimvm: #XXX: This would output 2,2 in the VM, which is wrong + discard + else: + say c, (c += C(i: 1); c) #1,2 + + proc sayVar(a: var int, b: int) = + echo a,",",b + + var d = 1 + sayVar d, (d += 1; d) #2,2 + + var e = 1 + say (addr e)[], (e += 1; e) #1,2 + + var f = 1 + say f, if false: f + else: f += 1; f #1,2 + + var g = 1 + say g + 1, if false: g + else: g += 1; g #2,2 + + proc `+=+`(x: var int, y: int): int = (inc(x, y); x) + + var h = 1 + say h, h +=+ 1 # 1,2 + +test + +static: + test diff --git a/tests/ccgbugs/tassign_nil_strings.nim b/tests/ccgbugs/tassign_nil_strings.nim index 07d2c2aeb..e32bfcade 100644 --- a/tests/ccgbugs/tassign_nil_strings.nim +++ b/tests/ccgbugs/tassign_nil_strings.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim $target --nilseqs:off $options $file" + matrix: "--mm:refc" output: "Hello" ccodecheck: "\\i@'a = ((NimStringDesc*) NIM_NIL)'" """ diff --git a/tests/ccgbugs/tbug21505.nim b/tests/ccgbugs/tbug21505.nim new file mode 100644 index 000000000..0c0811ec5 --- /dev/null +++ b/tests/ccgbugs/tbug21505.nim @@ -0,0 +1,39 @@ +discard """ + action: "compile" + targets: "cpp" + cmd: "nim cpp $file" +""" + +# see #21505: ensure compilation of imported C++ objects with explicit constructors while retaining default initialization through codegen changes due to #21279 + +{.emit:"""/*TYPESECTION*/ + +struct ExplObj +{ + explicit ExplObj(int bar = 0) {} +}; + +struct BareObj +{ + BareObj() {} +}; + +""".} + +type + ExplObj {.importcpp.} = object + BareObj {.importcpp.} = object + +type + Composer = object + explObj: ExplObj + bareObj: BareObj + +proc foo = + var composer1 {.used.}: Composer + let composer2 {.used.} = Composer() + +var composer1 {.used.}: Composer +let composer2 {.used.} = Composer() + +foo() \ No newline at end of file diff --git a/tests/ccgbugs/tccgen1.nim b/tests/ccgbugs/tccgen1.nim index 4917c9848..be571de08 100644 --- a/tests/ccgbugs/tccgen1.nim +++ b/tests/ccgbugs/tccgen1.nim @@ -7,7 +7,7 @@ type Features: seq[Feature] # Read-Only PNode* = ref Node - Node = object {.inheritable.} + Node {.inheritable.} = object attributes*: seq[PAttr] childNodes*: seq[PNode] FLocalName: string # Read-only diff --git a/tests/ccgbugs/tcgbug.nim b/tests/ccgbugs/tcgbug.nim index db9c116be..2eddc6fdd 100644 --- a/tests/ccgbugs/tcgbug.nim +++ b/tests/ccgbugs/tcgbug.nim @@ -4,6 +4,7 @@ success M1 M2 ok ''' +matrix: "--mm:refc;--mm:orc" """ type @@ -24,6 +25,7 @@ q(a) # bug #914 when defined(windows): + import std/widestrs var x = newWideCString("Hello") echo "success" @@ -91,3 +93,71 @@ proc test(c: Helper): string = c.formatted echo test(Helper(isKind: true, formatted: "ok")) + + +# bug #19613 + +type + Eth2Digest = object + data: array[42, byte] + + BlockId* = object + root*: Eth2Digest + + BlockSlotId* = object + bid*: BlockId + slot*: uint64 + +func init*(T: type BlockSlotId, bid: BlockId, slot: uint64): T = + #debugecho "init ", bid, " ", slot + BlockSlotId(bid: bid, slot: slot) + +proc bug19613 = + var x: BlockSlotId + x.bid.root.data[0] = 42 + + x = + if x.slot > 0: + BlockSlotId.init(x.bid, x.slot) + else: + BlockSlotId.init(x.bid, x.slot) + doAssert x.bid.root.data[0] == 42 + +bug19613() + +proc foo = # bug #23280 + let foo = @[1,2,3,4,5,6] + doAssert toOpenArray(foo, 0, 5).len == 6 + doAssert toOpenArray(foo, 0, 5).len mod 6 == 0 # this should output 0 + doAssert toOpenArray(foo, 0, 5).max mod 6 == 0 + let L = toOpenArray(foo, 0, 5).len + doAssert L mod 6 == 0 + +foo() + +block: # bug #9940 + {.emit:"""/*TYPESECTION*/ +typedef struct { int base; } S; +""".} + + type S {.importc: "S", completeStruct.} = object + base: cint + proc init(x:ptr S) = + x.base = 1 + + type + Foo = object + a: seq[float] + b: seq[float] + c: seq[float] + d: seq[float] + s: S + + proc newT(): Foo = + var t: Foo + t.s.addr.init + doAssert t.s.base == 1 + t + + var t = newT() + doAssert t.s.base == 1 diff --git a/tests/ccgbugs/tcodegenbug1.nim b/tests/ccgbugs/tcodegenbug1.nim index ebdc57144..d2ab97ede 100644 --- a/tests/ccgbugs/tcodegenbug1.nim +++ b/tests/ccgbugs/tcodegenbug1.nim @@ -1,9 +1,13 @@ discard """ + matrix: "--mm:refc" output: '''obj = (inner: (kind: Just, id: 7)) obj.inner.id = 7 id = 7 obj = (inner: (kind: Just, id: 7)) -2''' +2 +(a: "a", b: "b", c: "") +caught +(a: "a", b: "b", c: "")''' """ # bug #6960 @@ -129,12 +133,53 @@ import macros func myfunc(obj: MyObject): MyResult {.raises: [].} = template index: auto = case obj.kind: - of Float: $obj.index + of Float: $obj.index of Fixed: "Fixed" macro to_str(a: untyped): string = - result = newStrLitNode(a.repr) + result = newStrLitNode(a.repr) result.val[0] = index result.val[1] = to_str(obj.kind + Ola) let x = MyObject(someInt: 10, kind: Fixed) echo myfunc(x).val.len + +# bug #14126 + +type X = object + a, b, c: string + +proc f(): X = + result.a = "a" + result.b = "b" + raise (ref ValueError)() + +proc ohmanNoNRVO = + var x: X + x.a = "1" + x.b = "2" + x.c = "3" + + try: + x = f() + except: + discard + + echo x + # once NVRO is sorted out, x.c == "3" + doAssert x.c == "", "shouldn't modify x if f raises" + +ohmanNoNRVO() + +proc ohmanNoNRVO2(x: var X) = + x.a = "1" + x.c = "3" + x = f() + +var xgg: X +try: + ohmanNoNRVO2(xgg) +except: + echo "caught" +echo xgg +# once NVRO is sorted out, xgg.c == "3" +doAssert xgg.c == "", "this assert will fail" diff --git a/tests/ccgbugs/tcodegenbug_bool.nim b/tests/ccgbugs/tcodegenbug_bool.nim new file mode 100644 index 000000000..a0dbf4eb2 --- /dev/null +++ b/tests/ccgbugs/tcodegenbug_bool.nim @@ -0,0 +1,11 @@ +discard """ +""" + +# issue #13798 +{.emit:""" +#include <stdbool.h> +void fun(bool a){} +""".} + +proc fun(a: bool) {.importc.} +fun(true) diff --git a/tests/ccgbugs/tcompile_time_var_at_runtime.nim b/tests/ccgbugs/tcompile_time_var_at_runtime.nim new file mode 100644 index 000000000..c0de0390b --- /dev/null +++ b/tests/ccgbugs/tcompile_time_var_at_runtime.nim @@ -0,0 +1,11 @@ +discard """ + output: "1\n2\n2\n3" +""" +var a {.compileTime.} = 1 + +echo a +a = 2 +echo a +echo a +a = 3 +echo a \ No newline at end of file diff --git a/tests/ccgbugs/tctypes.nim b/tests/ccgbugs/tctypes.nim new file mode 100644 index 000000000..be6009115 --- /dev/null +++ b/tests/ccgbugs/tctypes.nim @@ -0,0 +1,43 @@ +discard """ + targets: "c cpp" + matrix: "--gc:refc; --gc:arc" +""" + +# bug #7308 +proc foo(x: seq[int32]) = + var y = newSeq[cint](1) + +proc bar = + var t = newSeq[int32](1) + foo(t) + +bar() + + +# bug #16246 + +proc testWeirdTypeAliases() = + var values = newSeq[cuint](8) + # var values: seq[cuint] does not produce codegen error + var drawCb = proc(): seq[uint32] = + result = newSeq[uint32](10) + +testWeirdTypeAliases() + +block: # bug #11797 + block: + type cdouble2 = cdouble + type Foo1 = seq[cdouble] + type Foo2 = seq[cdouble2] + static: doAssert Foo1 is Foo2 + var a1: Foo1 + var a2: Foo2 + doAssert a1 == @[] + doAssert a2 == @[] + + block: + proc foo[T: int|cint](fun: proc(): T) = discard + proc foo1(): cint = 1 + proc foo3(): int32 = 2 + foo(proc(): cint = foo1()) + foo(proc(): int32 = foo3()) diff --git a/tests/ccgbugs/tdeepcopy_addr_rval.nim b/tests/ccgbugs/tdeepcopy_addr_rval.nim index 07fb8f8ef..4a0b0deaa 100644 --- a/tests/ccgbugs/tdeepcopy_addr_rval.nim +++ b/tests/ccgbugs/tdeepcopy_addr_rval.nim @@ -1,4 +1,5 @@ discard """ + matrix: "--mm:refc; --mm:orc --deepcopy:on" output: "3" """ diff --git a/tests/ccgbugs/tderefblock.nim b/tests/ccgbugs/tderefblock.nim new file mode 100644 index 000000000..d3ba07667 --- /dev/null +++ b/tests/ccgbugs/tderefblock.nim @@ -0,0 +1,76 @@ +discard """ + matrix: "--mm:refc -d:release -d:danger;--mm:orc -d:useMalloc -d:release -d:danger" + output: "42" +""" + +# bug #20107 + +type Foo = object + a, b, c, d: uint64 + +proc c(i: uint64): Foo = + Foo(a: i, b: i, c: i, d: i) + +func x(f: Foo): lent Foo {.inline.} = + f + +proc m() = + let f = block: + let i = c(42) + x(i) + + echo $f.a + +m() + +block: # bug #21540 + type + Option = object + val: string + has: bool + + proc some(val: string): Option = + result.has = true + result.val = val + + # Remove lent and it works + proc get(self: Option): lent string = + result = self.val + + type + StringStream = ref object + data: string + pos: int + + proc readAll(s: StringStream): string = + result = newString(s.data.len) + copyMem(addr(result[0]), addr(s.data[0]), s.data.len) + + proc newStringStream(s: string = ""): StringStream = + new(result) + result.data = s + + proc parseJson(s: string): string = + let stream = newStringStream(s) + result = stream.readAll() + + proc main = + let initialFEN = block: + let initialFEN = some parseJson("startpos") + initialFEN.get + + doAssert initialFEN == "startpos" + + main() + +import std/[ + json, + options +] + +block: # bug #21540 + let cheek = block: + let initialFEN = some("""{"initialFen": "startpos"}""".parseJson{"initialFen"}.getStr) + initialFEN.get + + doAssert cheek == "startpos" diff --git a/tests/ccgbugs/tforward_decl_only.nim b/tests/ccgbugs/tforward_decl_only.nim index 74fbae303..b115dcbe7 100644 --- a/tests/ccgbugs/tforward_decl_only.nim +++ b/tests/ccgbugs/tforward_decl_only.nim @@ -1,7 +1,5 @@ discard """ -ccodecheck: "\\i !@('struct tyObject_MyRefObject'[0-z]+' {')" -ccodecheck: "\\i !@('mymoduleInit')" -ccodecheck: "\\i @('mymoduleDatInit')" +ccodecheck: "\\i !@('struct tyObject_MyRefObject'[0-z]+' _')" output: "hello" """ diff --git a/tests/ccgbugs/thtiobj.nim b/tests/ccgbugs/thtiobj.nim index 7a656905f..6db24dad0 100644 --- a/tests/ccgbugs/thtiobj.nim +++ b/tests/ccgbugs/thtiobj.nim @@ -1,4 +1,5 @@ discard """ + matrix: "--mm:refc" targets: "c cpp" """ diff --git a/tests/ccgbugs/tinefficient_const_table.nim b/tests/ccgbugs/tinefficient_const_table.nim deleted file mode 100644 index 7422d0676..000000000 --- a/tests/ccgbugs/tinefficient_const_table.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - output: '''a -long -list -of -words''' - cmd: r"nim c --hints:on $options -d:release $file" - ccodecheck: "! @'genericSeqAssign'" - target: "c" -""" - -# bug #4354 -import tables -import sets -import strutils - -#const FRUITS = ["banana", "apple", "grapes"] -#let FRUITS = ["banana", "apple", "grapes"].toSet -const FRUITS = {"banana":0, "apple":0, "grapes":0}.toTable - -proc main() = - let L = "a long list of words".split() - for word in L: - if word notin FRUITS: - echo(word) - -main() diff --git a/tests/ccgbugs/trecursive_closure.nim b/tests/ccgbugs/tissues.nim index 4b6514b90..a0c402cc0 100644 --- a/tests/ccgbugs/trecursive_closure.nim +++ b/tests/ccgbugs/tissues.nim @@ -16,3 +16,23 @@ f(nil) type A = object #of RootObj <-- Uncomment this to get no errors test: proc(i: A): bool var a: proc(i: A): bool # Or comment this line to get no errors + + +# bug #2703 +type + fooObj[T] = object of RootObj + bazObj[T] = object of fooObj[T] + x: T + +var troz: fooObj[string] +echo bazObj[string](troz).x + + +# bug #14880 +type step = object + exec: proc () + +const pipeline = @[step()] + +let crash = pipeline[0] + diff --git a/tests/ccgbugs/tlvalueconv.nim b/tests/ccgbugs/tlvalueconv.nim new file mode 100644 index 000000000..b2cb11eef --- /dev/null +++ b/tests/ccgbugs/tlvalueconv.nim @@ -0,0 +1,32 @@ +discard """ + matrix: "--gc:refc; --gc:arc" +""" + +# bug #14160 + +type + TPassContext = object of RootObj + PPassContext = ref TPassContext + + PCtx = ref object of TPassContext + a: int + + ModuleGraph = object + vm: RootRef + +proc main() = + var g = ModuleGraph(vm: new(Pctx)) + PCtx(g.vm) = nil #This generates invalid C code + doAssert g.vm == nil + +main() + +# bug #14325 + +proc main2() = + var g = ModuleGraph(vm: new(Pctx)) + PPassContext(PCtx(g.vm)) = nil #This compiles, but crashes at runtime with gc:arc + doAssert g.vm == nil + +main2() + diff --git a/tests/ccgbugs/tmangle.nim b/tests/ccgbugs/tmangle.nim new file mode 100644 index 000000000..0050cef92 --- /dev/null +++ b/tests/ccgbugs/tmangle.nim @@ -0,0 +1,16 @@ +block: + proc hello() = + let NAN_INFINITY = 12 + doAssert NAN_INFINITY == 12 + let INF = "2.0" + doAssert INF == "2.0" + let NAN = 2.3 + doAssert NAN == 2.3 + + hello() + +block: + proc hello(NAN: float) = + doAssert NAN == 2.0 + + hello(2.0) diff --git a/tests/ccgbugs/tmissingbracket.nim b/tests/ccgbugs/tmissingbracket.nim index 468e13366..2919efe0e 100644 --- a/tests/ccgbugs/tmissingbracket.nim +++ b/tests/ccgbugs/tmissingbracket.nim @@ -11,7 +11,7 @@ type className* : string TClassOfTobj = object of TClassOfTCustomObject nil - TCustomObject = ref object {.inheritable.} + TCustomObject {.inheritable.} = ref object class* : ptr TClassOfTCustomObject TObj = ref object of TCustomObject data: int diff --git a/tests/ccgbugs/tmissingderef.nim b/tests/ccgbugs/tmissingderef.nim index 26418800a..eb7da3023 100644 --- a/tests/ccgbugs/tmissingderef.nim +++ b/tests/ccgbugs/tmissingderef.nim @@ -1,6 +1,5 @@ discard """ output: '''[10, 0, 0, 0, 0, 0, 0, 0] - 255 1 1 0.5''' diff --git a/tests/ccgbugs/tmissinginit.nim b/tests/ccgbugs/tmissinginit.nim index 8806a2f21..9eb58221c 100644 --- a/tests/ccgbugs/tmissinginit.nim +++ b/tests/ccgbugs/tmissinginit.nim @@ -1,4 +1,5 @@ discard """ + matrix: "--mm:refc" output: '''0 0 0 diff --git a/tests/ccgbugs/tmissingvolatile.nim b/tests/ccgbugs/tmissingvolatile.nim index 60b1771dc..b877eff71 100644 --- a/tests/ccgbugs/tmissingvolatile.nim +++ b/tests/ccgbugs/tmissingvolatile.nim @@ -1,8 +1,8 @@ discard """ output: "1" - cmd: r"nim c --hints:on $options -d:release $file" + cmd: r"nim c --hints:on $options --mm:refc -d:release $file" ccodecheck: "'NI volatile state;'" - target: "C" + targets: "c" """ # bug #1539 diff --git a/tests/ccgbugs/tnoalias.nim b/tests/ccgbugs/tnoalias.nim new file mode 100644 index 000000000..2c3c2f0f4 --- /dev/null +++ b/tests/ccgbugs/tnoalias.nim @@ -0,0 +1,13 @@ +discard """ + ccodecheck: "\\i@'NI* NIM_NOALIAS field;' @'NIM_CHAR* NIM_NOALIAS x_p0,' @'void* NIM_NOALIAS q'" +""" + +type + BigNum = object + field {.noalias.}: ptr UncheckedArray[int] + +proc p(x {.noalias.}: openArray[char]) = + var q {.noalias.}: pointer = addr(x[0]) + +var bn: BigNum +p "abc" diff --git a/tests/ccgbugs/tprogmem.nim b/tests/ccgbugs/tprogmem.nim index 884ca158a..58a20583a 100644 --- a/tests/ccgbugs/tprogmem.nim +++ b/tests/ccgbugs/tprogmem.nim @@ -2,7 +2,7 @@ discard """ output: "5" cmd: r"nim c --hints:on $options -d:release $file" ccodecheck: "'/*PROGMEM*/ myLetVariable = {'" - target: "C" + targets: "c" """ var myLetVariable {.exportc, codegenDecl: "$# /*PROGMEM*/ $#".} = [1, 2, 3] diff --git a/tests/ccgbugs/tret_arg_init.nim b/tests/ccgbugs/tret_arg_init.nim index 5cd67de3e..e39e5a0de 100644 --- a/tests/ccgbugs/tret_arg_init.nim +++ b/tests/ccgbugs/tret_arg_init.nim @@ -1,6 +1,8 @@ discard """ output: ''' + + ''' """ diff --git a/tests/ccgbugs/tsamename3.nim b/tests/ccgbugs/tsamename3.nim new file mode 100644 index 000000000..ded18e9f8 --- /dev/null +++ b/tests/ccgbugs/tsamename3.nim @@ -0,0 +1,120 @@ +block: # bug #15526 + block: + type Foo = ref object + x1: int + let f1 = Foo(x1: 1) + block: + type Foo = ref object + x2: int + let f2 = Foo(x2: 2) + +block: # ditto + template fn() = + block: + type Foo = ref object + x1: int + let f1 = Foo(x1: 1) + doAssert f1.x1 == 1 + block: + type Foo = ref object + x2: int + let f2 = Foo(x2: 2) + doAssert f2.x2 == 2 + static: fn() + fn() + +block: # bug #17162 + template fn = + var ret: string + block: + type A = enum a0, a1, a2 + for ai in A: + ret.add $ai + block: + type A = enum b0, b1, b2, b3 + for ai in A: + ret.add $ai + doAssert ret == "a0a1a2b0b1b2b3" + + static: fn() # ok + fn() # was bug + +block: # ditto + proc fn = + var ret: string + block: + type A = enum a0, a1, a2 + for ai in A: + ret.add $ai + block: + type A = enum b0, b1, b2, b3 + for ai in A: + ret.add $ai + doAssert ret == "a0a1a2b0b1b2b3" + + static: fn() # ok + fn() # was bug + +block: # bug #5170 + block: + type Foo = object + x1: int + let f1 = Foo(x1: 1) + block: + type Foo = object + x2: int + let f2 = Foo(x2: 2) + +block: # ditto + block: + type Foo = object + bar: bool + var f1: Foo + + block: + type Foo = object + baz: int + var f2: Foo + doAssert f2.baz == 0 + + block: + template fn() = + block: + type Foo = object + x1: int + let f1 = Foo(x1: 1) + doAssert f1.x1 == 1 + block: + type Foo = object + x2: int + let f2 = Foo(x2: 2) + doAssert f2.x2 == 2 + static: fn() + fn() + +when true: # ditto, refs https://github.com/nim-lang/Nim/issues/5170#issuecomment-582712132 + type Foo1 = object # at top level + bar: bool + var f1: Foo1 + + block: + type Foo1 = object + baz: int + var f2: Foo1 + doAssert f2.baz == 0 + +block: # make sure `hashType` doesn't recurse infinitely + type + PFoo = ref object + a, b: PFoo + c: int + var a: PFoo + +block: # issue #22571 + macro foo(x: typed) = + result = x + + block: # or `proc main =` + foo: + type Foo = object + doAssert $Foo() == "()" diff --git a/tests/ccgbugs/tuple_canon.nim b/tests/ccgbugs/tuple_canon.nim index aa9605d4b..fbb971861 100644 --- a/tests/ccgbugs/tuple_canon.nim +++ b/tests/ccgbugs/tuple_canon.nim @@ -68,7 +68,7 @@ template odd*(i: int) : untyped = proc vidx(hg: HexGrid; col, row: int; i: HexVtxIndex) : Index = #NOTE: this variation compiles - #var offset : type(evenSharingOffsets[i]) + #var offset : typeof(evenSharingOffsets[i]) # #if odd(col): # offset = oddSharingOffsets[i] diff --git a/tests/ccgbugs/twrong_setconstr.nim b/tests/ccgbugs/twrong_setconstr.nim deleted file mode 100644 index 8be0b82b5..000000000 --- a/tests/ccgbugs/twrong_setconstr.nim +++ /dev/null @@ -1,146 +0,0 @@ -discard """ - output: "" -""" - -# bug #2880 - -type - TMsgKind* = enum - errUnknown, errIllFormedAstX, errInternal, errCannotOpenFile, errGenerated, - errXCompilerDoesNotSupportCpp, errStringLiteralExpected, - errIntLiteralExpected, errInvalidCharacterConstant, - errClosingTripleQuoteExpected, errClosingQuoteExpected, - errTabulatorsAreNotAllowed, errInvalidToken, errLineTooLong, - errInvalidNumber, errInvalidNumberOctalCode, errNumberOutOfRange, - errNnotAllowedInCharacter, errClosingBracketExpected, errMissingFinalQuote, - errIdentifierExpected, errNewlineExpected, errInvalidModuleName, - errOperatorExpected, errTokenExpected, errStringAfterIncludeExpected, - errRecursiveDependencyX, errOnOrOffExpected, errNoneSpeedOrSizeExpected, - errInvalidPragma, errUnknownPragma, errInvalidDirectiveX, - errAtPopWithoutPush, errEmptyAsm, errInvalidIndentation, - errExceptionExpected, errExceptionAlreadyHandled, - errYieldNotAllowedHere, errYieldNotAllowedInTryStmt, - errInvalidNumberOfYieldExpr, errCannotReturnExpr, errAttemptToRedefine, - errStmtInvalidAfterReturn, errStmtExpected, errInvalidLabel, - errInvalidCmdLineOption, errCmdLineArgExpected, errCmdLineNoArgExpected, - errInvalidVarSubstitution, errUnknownVar, errUnknownCcompiler, - errOnOrOffExpectedButXFound, errOnOffOrListExpectedButXFound, - errNoneBoehmRefcExpectedButXFound, - errNoneSpeedOrSizeExpectedButXFound, errGuiConsoleOrLibExpectedButXFound, - errUnknownOS, errUnknownCPU, errGenOutExpectedButXFound, - errArgsNeedRunOption, errInvalidMultipleAsgn, errColonOrEqualsExpected, - errExprExpected, errUndeclaredIdentifier, errUseQualifier, errTypeExpected, - errSystemNeeds, errExecutionOfProgramFailed, errNotOverloadable, - errInvalidArgForX, errStmtHasNoEffect, errXExpectsTypeOrValue, - errXExpectsArrayType, errIteratorCannotBeInstantiated, errExprXAmbiguous, - errConstantDivisionByZero, errOrdinalTypeExpected, - errOrdinalOrFloatTypeExpected, errOverOrUnderflow, - errCannotEvalXBecauseIncompletelyDefined, errChrExpectsRange0_255, - errDynlibRequiresExportc, errUndeclaredFieldX, errNilAccess, - errIndexOutOfBounds, errIndexTypesDoNotMatch, errBracketsInvalidForType, - errValueOutOfSetBounds, errFieldInitTwice, errFieldNotInit, - errExprXCannotBeCalled, errExprHasNoType, errExprXHasNoType, - errCastNotInSafeMode, errExprCannotBeCastedToX, errCommaOrParRiExpected, - errCurlyLeOrParLeExpected, errSectionExpected, errRangeExpected, - errMagicOnlyInSystem, errPowerOfTwoExpected, - errStringMayNotBeEmpty, errCallConvExpected, errProcOnlyOneCallConv, - errSymbolMustBeImported, errExprMustBeBool, errConstExprExpected, - errDuplicateCaseLabel, errRangeIsEmpty, errSelectorMustBeOfCertainTypes, - errSelectorMustBeOrdinal, errOrdXMustNotBeNegative, errLenXinvalid, - errWrongNumberOfVariables, errExprCannotBeRaised, errBreakOnlyInLoop, - errTypeXhasUnknownSize, errConstNeedsConstExpr, errConstNeedsValue, - errResultCannotBeOpenArray, errSizeTooBig, errSetTooBig, - errBaseTypeMustBeOrdinal, errInheritanceOnlyWithNonFinalObjects, - errInheritanceOnlyWithEnums, errIllegalRecursionInTypeX, - errCannotInstantiateX, errExprHasNoAddress, errXStackEscape, - errVarForOutParamNeeded, - errPureTypeMismatch, errTypeMismatch, errButExpected, errButExpectedX, - errAmbiguousCallXYZ, errWrongNumberOfArguments, - errXCannotBePassedToProcVar, - errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProc, errImplOfXNotAllowed, - errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValueX, - errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice, - errInvalidOrderInArrayConstructor, - errInvalidOrderInEnumX, errEnumXHasHoles, errExceptExpected, errInvalidTry, - errOptionExpected, errXisNoLabel, errNotAllCasesCovered, - errUnknownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable, - errNoPragmasAllowedForX, errNoGenericParamsAllowedForX, - errInvalidParamKindX, errDefaultArgumentInvalid, errNamedParamHasToBeIdent, - errNoReturnTypeForX, errConvNeedsOneArg, errInvalidPragmaX, - errXNotAllowedHere, errInvalidControlFlowX, - errXisNoType, errCircumNeedsPointer, errInvalidExpression, - errInvalidExpressionX, errEnumHasNoValueX, errNamedExprExpected, - errNamedExprNotAllowed, errXExpectsOneTypeParam, - errArrayExpectsTwoTypeParams, errInvalidVisibilityX, errInitHereNotAllowed, - errXCannotBeAssignedTo, errIteratorNotAllowed, errXNeedsReturnType, - errNoReturnTypeDeclared, - errInvalidCommandX, errXOnlyAtModuleScope, - errXNeedsParamObjectType, - errTemplateInstantiationTooNested, errInstantiationFrom, - errInvalidIndexValueForTuple, errCommandExpectsFilename, - errMainModuleMustBeSpecified, - errXExpected, - errTIsNotAConcreteType, - errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, - errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, - errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitly, - errOnlyACallOpCanBeDelegator, errUsingNoSymbol, - errMacroBodyDependsOnGenericTypes, - errDestructorNotGenericEnough, - errInlineIteratorsAsProcParams, - errXExpectsTwoArguments, - errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, - errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX, - errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument, - errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate, - errXhasSideEffects, errIteratorExpected, errLetNeedsInit, - errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX, - errXCannotBeClosure, errXMustBeCompileTime, - errCannotInferTypeOfTheLiteral, - errCannotInferReturnType, - errGenericLambdaNotAllowed, - errCompilerDoesntSupportTarget, - errUser, - warnCannotOpenFile, - warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit, - warnDeprecated, warnConfigDeprecated, - warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel, - warnUnknownSubstitutionX, warnLanguageXNotSupported, - warnFieldXNotSupported, warnCommentXIgnored, - warnNilStatement, warnTypelessParam, - warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode, - warnEachIdentIsTuple - warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2, - warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed, - warnUser, - hintSuccess, hintSuccessX, - hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, - hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, - hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, - hintConditionAlwaysTrue, hintName, hintPattern, - hintExecuting, hintLinking, hintDependency, - hintSource, hintStackTrace, hintGCStats, - hintUser - -const - warnMin = warnCannotOpenFile - hintMax = high(TMsgKind) - -type - TNoteKind = range[warnMin..hintMax] # "notes" are warnings or hints - TNoteKinds = set[TNoteKind] - -const - NotesVerbosityConst: array[0..0, TNoteKinds] = [ - {low(TNoteKind)..high(TNoteKind)} - {hintGCStats}] - fuckyou = NotesVerbosityConst[0] - -var - gNotesFromConst: TNoteKinds = NotesVerbosityConst[0] - gNotesFromConst2: TNoteKinds = fuckyou - -if hintGCStats in gNotesFromConst: - echo "hintGCStats in gNotesFromConst A" - -if hintGCStats in gNotesFromConst2: - echo "hintGCStats in gNotesFromConst B" diff --git a/tests/ccgbugs/twrong_tupleconv.nim b/tests/ccgbugs/twrong_tupleconv.nim index 7b1e58083..031712dac 100644 --- a/tests/ccgbugs/twrong_tupleconv.nim +++ b/tests/ccgbugs/twrong_tupleconv.nim @@ -1,3 +1,8 @@ +discard """ + targets: "c cpp" + matrix: "--gc:refc; --gc:arc" +""" + # bug #1833 iterator myitems*[T](a: var seq[T]): var T {.inline.} = ## iterates over each item of `a` so that you can modify the yielded value. @@ -6,7 +11,7 @@ iterator myitems*[T](a: var seq[T]): var T {.inline.} = while i < L: yield a[i] inc(i) - assert(len(a) == L, "the length of the seq changed while iterating over it") + doAssert(len(a) == L, "the length of the seq changed while iterating over it") # Works fine var xs = @[1,2,3] @@ -18,3 +23,13 @@ var ys = @[(1,"a"),(2,"b"),(3,"c")] for y in myitems(ys): inc y[0] +# bug #16331 +type T1 = tuple[a, b: int] + +proc p(b: bool): string = + var x: T1 = (10, 20) + x = if b: (x.b, x.a) else: (-x.b, -x.a) + $x + +assert p(false) == "(a: -20, b: -10)" +assert p(true) == "(a: 20, b: 10)" |