diff options
Diffstat (limited to 'tests/vm')
61 files changed, 1845 insertions, 179 deletions
diff --git a/tests/vm/mscriptcompiletime.nim b/tests/vm/mscriptcompiletime.nim new file mode 100644 index 000000000..ed7e7c029 --- /dev/null +++ b/tests/vm/mscriptcompiletime.nim @@ -0,0 +1,7 @@ +# bug.nim +var bar* {.compileTime.} = 1 + +proc dummy = discard + +static: + inc bar \ No newline at end of file diff --git a/tests/vm/t11637.nim b/tests/vm/t11637.nim new file mode 100644 index 000000000..c061c6641 --- /dev/null +++ b/tests/vm/t11637.nim @@ -0,0 +1,52 @@ +type Foo = ref object + val: int + +proc `+`(a, b: Foo): Foo = + Foo(val: a.val + b.val) + +proc `*`(a: Foo, b: int): Foo = + Foo(val: a.val * b) + +proc `+=`(a: var Foo, b: Foo) = + a = Foo( + val: a.val + b.val + ) + +proc foobar(a, b, c: Foo): tuple[bar, baz, buzz: Foo] = + + let foo = a + b + c + result.bar = foo * 2 + + result.baz = foo * 3 + result.buzz = result.baz + + result.buzz += a * 10000 + result.baz += b + result.buzz += b + + +block: # Compile-Time + let + a {.compileTime.} = Foo(val: 1) + b {.compileTime.} = Foo(val: 2) + c {.compileTime.} = Foo(val: 3) + r {.compileTime.} = foobar(a, b, c) + + static: + doAssert r.bar.val == 12 + doAssert r.baz.val == 20 + doAssert r.buzz.val == 10020 + +#################################### + +block: # Run-time + let + a = Foo(val: 1) + b = Foo(val: 2) + c = Foo(val: 3) + r = foobar(a, b, c) + + # Expected values + doAssert r.bar.val == 12 + doAssert r.baz.val == 20 + doAssert r.buzz.val == 10020 diff --git a/tests/vm/t17039.nim b/tests/vm/t17039.nim new file mode 100644 index 000000000..f92c93f30 --- /dev/null +++ b/tests/vm/t17039.nim @@ -0,0 +1,10 @@ +type + Obj1 = object + case kind: bool + of false: + field: seq[int] + else: discard + +static: + var obj1 = Obj1() + obj1.field.add(@[]) diff --git a/tests/vm/t17121.nim b/tests/vm/t17121.nim new file mode 100644 index 000000000..bf2d6423f --- /dev/null +++ b/tests/vm/t17121.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "cannot 'importc' variable at compile time; c_printf" +""" + +proc c_printf*(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>", varargs, discardable.} = + ## foo bar + runnableExamples: discard +static: + let a = c_printf("abc\n") diff --git a/tests/vm/t18103.nim b/tests/vm/t18103.nim new file mode 100644 index 000000000..8622ab290 --- /dev/null +++ b/tests/vm/t18103.nim @@ -0,0 +1,35 @@ +discard """ + targets: "c cpp" + matrix: "--mm:refc; --mm:arc" +""" + +import base64, complex, sequtils, math, sugar + +type + + FP = float + T = object + index: int + arg: FP + val: Complex[FP] + M = object + alpha, beta: FP + +func a(s: openArray[T], model: M): seq[T] = + let f = (tn: int) => model.alpha + FP(tn) * model.beta; + return mapIt s: + block: + let s = it.val * rect(1.0, - f(it.index)) + T(index: it.index, arg: phase(s), val: s) + +proc b(): float64 = + var s = toSeq(0..10).mapIt(T(index: it, arg: 1.0, val: complex.complex(1.0))) + discard a(s, M(alpha: 1, beta: 1)) + return 1.0 + +func cc(str: cstring, offset: ptr[cdouble]): cint {.exportc.} = + offset[] = b() + return 0 + +static: + echo b() diff --git a/tests/vm/t19075.nim b/tests/vm/t19075.nim new file mode 100644 index 000000000..89ca9cb19 --- /dev/null +++ b/tests/vm/t19075.nim @@ -0,0 +1,19 @@ +discard """ + timeout: 10 + joinable: false +""" + +# bug #19075 +const size = 50_000 + +const stuff = block: + var a: array[size, int] + a + +const zeugs = block: + var zeugs: array[size, int] + for i in 0..<size: + zeugs[i] = stuff[i] + zeugs + +doAssert zeugs[0] == 0 \ No newline at end of file diff --git a/tests/vm/t19199.nim b/tests/vm/t19199.nim new file mode 100644 index 000000000..6ae48cb54 --- /dev/null +++ b/tests/vm/t19199.nim @@ -0,0 +1,6 @@ +# bug #19199 +proc mikasa(x: float) = doAssert x == 42 + +static: + mikasa 42.uint.float +mikasa 42.uint.float diff --git a/tests/vm/t20746.nim b/tests/vm/t20746.nim new file mode 100644 index 000000000..bfad269ef --- /dev/null +++ b/tests/vm/t20746.nim @@ -0,0 +1,13 @@ +discard """ + timeout: 10 + joinable: false + output: "fine" +""" + +func addString(): string = + let x = newString(1000000) + for i in 0..<1000000: + discard x[i] + +const translationTable = addString() +echo "fine" diff --git a/tests/vm/t21704.nim b/tests/vm/t21704.nim new file mode 100644 index 000000000..27f4f5b06 --- /dev/null +++ b/tests/vm/t21704.nim @@ -0,0 +1,69 @@ +discard """ +matrix: "--hints:off" +nimout: ''' +Found 2 tests to run. +Found 3 benches to compile. + + --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow + + --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow + + --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow +''' +""" +# bug #21704 +import std/strformat + +const testDesc: seq[string] = @[ + "tests/t_hash_sha256_vs_openssl.nim", + "tests/t_cipher_chacha20.nim" +] +const benchDesc = [ + "bench_sha256", + "bench_hash_to_curve", + "bench_ethereum_bls_signatures" +] + +proc setupTestCommand(flags, path: string): string = + return "nim c -r " & + flags & + &" --nimcache:nimcache/{path} " & # Commenting this out also solves the issue + path + +proc testBatch(commands: var string, flags, path: string) = + commands &= setupTestCommand(flags, path) & '\n' + +proc setupBench(benchName: string): string = + var runFlags = if false: " -r " + else: " " # taking this branch is needed to trigger the bug + + echo runFlags # Somehow runflags isn't reset in corner cases + runFlags &= " --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow " + echo runFlags + + return "nim c " & + runFlags & + &" benchmarks/{benchName}.nim" + +proc buildBenchBatch(commands: var string, benchName: string) = + let command = setupBench(benchName) + commands &= command & '\n' + +proc addTestSet(cmdFile: var string) = + echo "Found " & $testDesc.len & " tests to run." + + for path in testDesc: + var flags = "" # This is important + cmdFile.testBatch(flags, path) + +proc addBenchSet(cmdFile: var string) = + echo "Found " & $benchDesc.len & " benches to compile." + for bd in benchDesc: + cmdFile.buildBenchBatch(bd) + +proc task_bug() = + var cmdFile: string + cmdFile.addTestSet() # Comment this out and there is no bug + cmdFile.addBenchSet() + +static: task_bug() diff --git a/tests/vm/t9622.nim b/tests/vm/t9622.nim new file mode 100644 index 000000000..fada8fe59 --- /dev/null +++ b/tests/vm/t9622.nim @@ -0,0 +1,30 @@ +discard """ + targets: "c cpp" + matrix: "--mm:refc; --mm:arc" +""" + +type + GlobNodeKind = enum + LiteralIdent, + Group + + GlobNode = object + case kind: GlobNodeKind + of LiteralIdent: + value: string + of Group: + values: seq[string] + + PathSegment = object + children: seq[GlobNode] + + GlobPattern = seq[PathSegment] + +proc parseImpl(): GlobPattern = + if result.len == 0: + result.add PathSegment() + result[^1].children.add GlobNode(kind: LiteralIdent) + +block: + const pattern = parseImpl() + doAssert $pattern == """@[(children: @[(kind: LiteralIdent, value: "")])]""" diff --git a/tests/vm/tableinstatic.nim b/tests/vm/tableinstatic.nim index 4080a5286..934c3a8dd 100644 --- a/tests/vm/tableinstatic.nim +++ b/tests/vm/tableinstatic.nim @@ -35,4 +35,4 @@ static: otherTable["hallo"] = "123" otherTable["welt"] = "456" - assert otherTable == {"hallo": "123", "welt": "456"}.newTable + doAssert otherTable == {"hallo": "123", "welt": "456"}.newTable diff --git a/tests/vm/tcastint.nim b/tests/vm/tcastint.nim index acff0d2b1..c306e4a31 100644 --- a/tests/vm/tcastint.nim +++ b/tests/vm/tcastint.nim @@ -1,9 +1,5 @@ -discard """ - output: "OK" -""" - import macros - +from stdtest/testutils import disableVM type Dollar = distinct int XCoord = distinct int32 @@ -15,6 +11,12 @@ proc `==`(x, y: XCoord): bool {.borrow.} proc dummy[T](x: T): T = x +template roundTrip(a, T) = + let a2 = a # sideeffect safe + let b = cast[T](a2) + let c = cast[type(a2)](b) + doAssert c == a2 + proc test() = let U8 = 0b1011_0010'u8 let I8 = 0b1011_0010'i8 @@ -102,17 +104,21 @@ proc test() = doAssert(cast[int](digit) == raw) doAssert(cast[Digit](raw) == digit) - when defined nimvm: - doAssert(not compiles(cast[float](I64A))) - doAssert(not compiles(cast[float32](I64A))) - - doAssert(not compiles(cast[char](I64A))) - doAssert(not compiles(cast[uint16](I64A))) - doAssert(not compiles(cast[uint32](I64A))) + block: + roundTrip(I64A, float) + roundTrip(I8, uint16) + roundTrip(I8, uint32) + roundTrip(I8, uint64) + doAssert cast[uint16](I8) == 65458'u16 + doAssert cast[uint32](I8) == 4294967218'u32 + doAssert cast[uint64](I8) == 18446744073709551538'u64 + doAssert cast[uint32](I64A) == 2571663889'u32 + doAssert cast[uint16](I64A) == 31249 + doAssert cast[char](I64A).ord == 17 + doAssert compiles(cast[float32](I64A)) - doAssert(not compiles(cast[uint16](I8))) - doAssert(not compiles(cast[uint32](I8))) - doAssert(not compiles(cast[uint64](I8))) + disableVM: # xxx Error: VM does not support 'cast' from tyInt64 to tyFloat32 + doAssert cast[uint32](cast[float32](I64A)) == 2571663889'u32 const prerecordedResults = [ # cast to char @@ -292,16 +298,12 @@ proc test_float32_castB() = # any surprising content. doAssert cast[uint64](c) == 3270918144'u64 -test() -test_float_cast() -test_float32_cast() -free_integer_casting() -test_float32_castB() -static: +template main() = test() test_float_cast() test_float32_cast() free_integer_casting() test_float32_castB() -echo "OK" +static: main() +main() diff --git a/tests/vm/tclosureiterator.nim b/tests/vm/tclosureiterator.nim new file mode 100644 index 000000000..c909392d5 --- /dev/null +++ b/tests/vm/tclosureiterator.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "Closure iterators are not supported by VM!" +""" + +iterator iter*(): int {.closure.} = + yield 3 + +static: + var x = iter diff --git a/tests/vm/tcnstseq.nim b/tests/vm/tcnstseq.nim new file mode 100644 index 000000000..5679a6e37 --- /dev/null +++ b/tests/vm/tcnstseq.nim @@ -0,0 +1,68 @@ +discard """ +output: ''' +AngelikaAnneAnnaAnkaAnja +AngelikaAnneAnnaAnkaAnja +AngelikaAnneAnnaAnkaAnja +onetwothree +onetwothree +onetwothree +one1two2three3 +''' +""" +# Test the new implicit conversion from sequences to arrays in a constant +# context. + +import strutils + + +block t1: + const + myWords = "Angelika Anne Anna Anka Anja".split() + + for x in items(myWords): + write(stdout, x) #OUT AngelikaAnneAnnaAnkaAnja + echo "" + + +block t2: + const + myWords = @["Angelika", "Anne", "Anna", "Anka", "Anja"] + + for i in 0 .. high(myWords): + write(stdout, myWords[i]) #OUT AngelikaAnneAnnaAnkaAnja + echo "" + + +block t3: + for w in items(["Angelika", "Anne", "Anna", "Anka", "Anja"]): + write(stdout, w) #OUT AngelikaAnneAnnaAnkaAnja + echo "" + + +block t2656: + iterator it1(args: seq[string]): string = + for s in args: yield s + iterator it2(args: seq[string]): string {.closure.} = + for s in args: yield s + iterator it3(args: openArray[string]): string {.closure.} = + for s in args: yield s + iterator it4(args: openArray[(string, string)]): string {.closure.} = + for s1, s2 in items(args): yield s1 & s2 + + block: + const myConstSeq = @["one", "two", "three"] + for s in it1(myConstSeq): + stdout.write s + echo "" + for s in it2(myConstSeq): + stdout.write s + echo "" + for s in it3(myConstSeq): + stdout.write s + echo "" + + block: + const myConstSeq = @[("one", "1"), ("two", "2"), ("three", "3")] + for s in it4(myConstSeq): + stdout.write s + echo "" diff --git a/tests/vm/tcompilesetting.nim b/tests/vm/tcompilesetting.nim index 98565ab94..d6c08e70f 100644 --- a/tests/vm/tcompilesetting.nim +++ b/tests/vm/tcompilesetting.nim @@ -1,20 +1,18 @@ discard """ -cmd: "nim c --nimcache:build/myNimCache --nimblePath:myNimblePath $file" +cmd: "nim c --nimcache:build/myNimCache --nimblePath:myNimblePath --gc:arc $file" joinable: false """ -import strutils +import std/[strutils,compilesettings] +from std/os import fileExists, `/` -import std / compilesettings +template main = + doAssert querySetting(nimcacheDir) == nimcacheDir.querySetting + doAssert "myNimCache" in nimcacheDir.querySetting + doAssert "myNimblePath" in nimblePaths.querySettingSeq[0] + doAssert querySetting(backend) == "c" + doAssert fileExists(libPath.querySetting / "system.nim") + doAssert querySetting(mm) == "arc" -const - nc = querySetting(nimcacheDir) - np = querySettingSeq(nimblePaths) - -static: - echo nc - echo np - -doAssert "myNimCache" in nc -doAssert "myNimblePath" in np[0] -doAssert querySetting(backend) == "c" +static: main() +main() diff --git a/tests/vm/tcompiletimetable.nim b/tests/vm/tcompiletimetable.nim index ece2ddfe9..1db490f1a 100644 --- a/tests/vm/tcompiletimetable.nim +++ b/tests/vm/tcompiletimetable.nim @@ -1,12 +1,16 @@ discard """ - nimout: '''2 + nimout: ''' +2 3 4:2 Got Hi Got Hey +''' + output:''' a b -c''' +c +''' """ # bug #404 diff --git a/tests/vm/tconst.nim b/tests/vm/tconst.nim new file mode 100644 index 000000000..5cfe7533e --- /dev/null +++ b/tests/vm/tconst.nim @@ -0,0 +1,58 @@ +discard """ + targets: "c cpp js" +""" + +import std/strutils + +template forceConst(a: untyped): untyped = + ## Force evaluation at CT, but `static(a)` is simpler + const ret = a + ret + +proc isNimVm(): bool = + when nimvm: result = true + else: result = false + +block: + doAssert forceConst(isNimVm()) + doAssert not isNimVm() + doAssert forceConst(isNimVm()) == static(isNimVm()) + doAssert forceConst(isNimVm()) == isNimVm().static + +template main() = + # xxx merge more const related tests here + const ct = CompileTime + # refs https://github.com/timotheecour/Nim/issues/718, apparently `CompileTime` + # isn't cached, which seems surprising. + block: + const + a = """ + Version $1| + Compiled at: $2, $3 + """ % [NimVersion & spaces(44-len(NimVersion)), CompileDate, ct] + let b = $a + doAssert ct in b, $(b, ct) + doAssert NimVersion in b + + block: # Test for fix on broken const unpacking + template mytemp() = + const + (x, increment) = (4, true) + a = 100 + discard (x, increment, a) + mytemp() + + block: # bug #12334 + block: + const b: cstring = "foo" + var c = b + doAssert c == "foo" + block: + const a = "foo" + const b: cstring = a + var c = b + doAssert c == "foo" + + +static: main() +main() diff --git a/tests/vm/tconstarrayresem.nim b/tests/vm/tconstarrayresem.nim new file mode 100644 index 000000000..6701cfe4d --- /dev/null +++ b/tests/vm/tconstarrayresem.nim @@ -0,0 +1,29 @@ +# issue #23010 + +type + Result[T, E] = object + case oResult: bool + of false: + discard + of true: + vResult: T + + Opt[T] = Result[T, void] + +template ok[T, E](R: type Result[T, E], x: untyped): R = + R(oResult: true, vResult: x) + +template c[T](v: T): Opt[T] = Opt[T].ok(v) + +type + FixedBytes[N: static[int]] = distinct array[N, byte] + + H = object + d: FixedBytes[2] + +const b = default(H) +template g(): untyped = + const t = default(H) + b + +discard c(g()) diff --git a/tests/vm/tconsteval.nim b/tests/vm/tconsteval.nim deleted file mode 100644 index 2e0fcb888..000000000 --- a/tests/vm/tconsteval.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ -action: compile -""" - -import strutils - -const - HelpText = """ -+-----------------------------------------------------------------+ -| Maintenance program for Nim | -| Version $1| -| (c) 2012 Andreas Rumpf | -+-----------------------------------------------------------------+ -Compiled at: $2, $3 - -Usage: - koch [options] command [options for command] -Options: - --force, -f, -B, -b forces rebuild - --help, -h shows this help and quits -Possible Commands: - boot [options] bootstraps with given command line options - clean cleans Nim project; removes generated files - web generates the website - csource [options] builds the C sources for installation - zip builds the installation ZIP package - inno builds the Inno Setup installer -""" % [NimVersion & spaces(44-len(NimVersion)), - CompileDate, CompileTime] - -echo HelpText diff --git a/tests/vm/tconstobj.nim b/tests/vm/tconstobj.nim index ac7148b59..7dc20a0ba 100644 --- a/tests/vm/tconstobj.nim +++ b/tests/vm/tconstobj.nim @@ -3,6 +3,7 @@ discard """ (name: "hello") (-1, 0) (FirstName: "James", LastName: "Franco") +[1, 2, 3] ''' """ @@ -70,3 +71,25 @@ static: # issue #11861 var ifb2: InheritedFromBase initBase(ifb2) doAssert(ifb2.txt == "Initialized string from base") + + +static: # issue #15662 + proc a(T: typedesc) = echo T.type + a((int, int)) + +# bug #16069 +type + E = enum + val1, val2 + Obj = object + case k: E + of val1: + x: array[3, int] + of val2: + y: uint32 + +const + foo = [1, 2, 3] + arr = Obj(k: val1, x: foo) + +echo arr.x diff --git a/tests/vm/tconstresem.nim b/tests/vm/tconstresem.nim new file mode 100644 index 000000000..4526cb891 --- /dev/null +++ b/tests/vm/tconstresem.nim @@ -0,0 +1,10 @@ +block: # issue #19849 + type + Vec2[T] = object + x, y: T + Vec2i = Vec2[int] + template getX(p: Vec2i): int = p.x + let x = getX: + const t = Vec2i(x: 1, y: 2) + t + doAssert x == 1 diff --git a/tests/vm/tconstscope1.nim b/tests/vm/tconstscope1.nim new file mode 100644 index 000000000..41c45a28f --- /dev/null +++ b/tests/vm/tconstscope1.nim @@ -0,0 +1,5 @@ +# issue #5395 + +const a = (var b = 3; b) +echo b #[tt.Error + ^ undeclared identifier: 'b']# diff --git a/tests/vm/tconstscope2.nim b/tests/vm/tconstscope2.nim new file mode 100644 index 000000000..d858e96c2 --- /dev/null +++ b/tests/vm/tconstscope2.nim @@ -0,0 +1,5 @@ +const + a = (var x = 3; x) + # should we allow this? + b = x #[tt.Error + ^ undeclared identifier: 'x']# diff --git a/tests/vm/tconsttable.nim b/tests/vm/tconsttable.nim index 64a74a59d..152a33cba 100644 --- a/tests/vm/tconsttable.nim +++ b/tests/vm/tconsttable.nim @@ -17,3 +17,18 @@ x = "ah" echo foo[x] x = "possible." echo foo[x] + +block: # bug #19840 + const testBytes = [byte 0xD8, 0x08, 0xDF, 0x45, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x61] + var tempStr = "__________________" + + tempStr.prepareMutation + copyMem(addr tempStr[0], addr testBytes[0], testBytes.len) + +block: # bug #22389 + func foo(): ptr UncheckedArray[byte] = + const bar = [77.byte] + cast[ptr UncheckedArray[byte]](addr bar[0]) + + doAssert foo()[0] == 77 + diff --git a/tests/vm/tconvaddr.nim b/tests/vm/tconvaddr.nim new file mode 100644 index 000000000..9762a9e59 --- /dev/null +++ b/tests/vm/tconvaddr.nim @@ -0,0 +1,49 @@ +block: # issue #24097 + type Foo = distinct int + proc foo(x: var Foo) = + int(x) += 1 + proc bar(x: var int) = + x += 1 + static: + var x = Foo(1) + int(x) = int(x) + 1 + doAssert x.int == 2 + int(x) += 1 + doAssert x.int == 3 + foo(x) + doAssert x.int == 4 + bar(int(x)) # need vmgen flags propagated for this + doAssert x.int == 5 + type Bar = object + x: Foo + static: + var obj = Bar(x: Foo(1)) + int(obj.x) = int(obj.x) + 1 + doAssert obj.x.int == 2 + int(obj.x) += 1 + doAssert obj.x.int == 3 + foo(obj.x) + doAssert obj.x.int == 4 + bar(int(obj.x)) # need vmgen flags propagated for this + doAssert obj.x.int == 5 + static: + var arr = @[Foo(1)] + int(arr[0]) = int(arr[0]) + 1 + doAssert arr[0].int == 2 + int(arr[0]) += 1 + doAssert arr[0].int == 3 + foo(arr[0]) + doAssert arr[0].int == 4 + bar(int(arr[0])) # need vmgen flags propagated for this + doAssert arr[0].int == 5 + proc testResult(): Foo = + result = Foo(1) + int(result) = int(result) + 1 + doAssert result.int == 2 + int(result) += 1 + doAssert result.int == 3 + foo(result) + doAssert result.int == 4 + bar(int(result)) # need vmgen flags propagated for this + doAssert result.int == 5 + doAssert testResult().int == 5 diff --git a/tests/vm/tfibconst.nim b/tests/vm/tfibconst.nim new file mode 100644 index 000000000..cca6dd84f --- /dev/null +++ b/tests/vm/tfibconst.nim @@ -0,0 +1,43 @@ +discard """ + nimout: ''' +Fibonacci sequence: 0, 1, 1, 2, 3 +Sequence continues: 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610 +''' +""" + + +import strformat + +var fib_n {.compileTime.}: int +var fib_prev {.compileTime.}: int +var fib_prev_prev {.compileTime.}: int + +proc next_fib(): int {.compileTime.} = + let fib = if fib_n < 2: + fib_n + else: + fib_prev_prev + fib_prev + inc(fib_n) + fib_prev_prev = fib_prev + fib_prev = fib + fib + +const f0 = next_fib() +const f1 = next_fib() +const f2 = next_fib() +const f3 = next_fib() +const f4 = next_fib() + +static: + echo fmt"Fibonacci sequence: {f0}, {f1}, {f2}, {f3}, {f4}" + +const fib_continues = block: + var result = fmt"Sequence continues: " + for i in 0..10: + if i > 0: + add(result, ", ") + add(result, $next_fib()) + result + +static: + echo fib_continues \ No newline at end of file diff --git a/tests/vm/tfile_rw.nim b/tests/vm/tfile_rw.nim index 8d7a2ca95..439886e49 100644 --- a/tests/vm/tfile_rw.nim +++ b/tests/vm/tfile_rw.nim @@ -1,7 +1,3 @@ -discard """ - output: '''ok''' -""" - # test file read write in vm import os, strutils @@ -24,4 +20,3 @@ static: removeFile(filename) -echo "ok" \ No newline at end of file diff --git a/tests/vm/tgenericcompiletimeproc.nim b/tests/vm/tgenericcompiletimeproc.nim new file mode 100644 index 000000000..08099ebbe --- /dev/null +++ b/tests/vm/tgenericcompiletimeproc.nim @@ -0,0 +1,36 @@ +block: # issue #10753 + proc foo(x: int): int {.compileTime.} = x + const a = foo(123) + doAssert foo(123) == a + + proc bar[T](x: T): T {.compileTime.} = x + const b = bar(123) + doAssert bar(123) == b + const c = bar("abc") + doAssert bar("abc") == c + +block: # issue #22021 + proc foo(x: static int): int {.compileTime.} = x + 1 + doAssert foo(123) == 124 + +block: # issue #19365 + proc f[T](x: static T): T {.compileTime.} = x + x + doAssert f(123) == 246 + doAssert f(1.0) == 2.0 + +block: + # don't fold compile time procs in typeof + proc fail[T](x: T): T {.compileTime.} = + doAssert false + x + doAssert typeof(fail(123)) is typeof(123) + proc p(x: int): int = x + + type Foo = typeof(p(fail(123))) + +block: # issue #24150, related regression + proc w(T: type): T {.compileTime.} = default(ptr T)[] + template y(v: auto): auto = typeof(v) is int + discard compiles(y(w int)) + proc s(): int {.compileTime.} = discard + discard s() diff --git a/tests/vm/tissues.nim b/tests/vm/tissues.nim index 063559d2e..f0ae6c296 100644 --- a/tests/vm/tissues.nim +++ b/tests/vm/tissues.nim @@ -1,6 +1,6 @@ import macros -block t9043: # issue #9043 +block t9043: # bug #9043 proc foo[N: static[int]](dims: array[N, int]): string = const N1 = N const N2 = dims.len @@ -25,4 +25,52 @@ block t4952: static: let tree = newTree(nnkExprColonExpr) let t = (n: tree) - assert: t.n.kind == tree.kind + doAssert: t.n.kind == tree.kind + + +# bug #19909 +type + SinglyLinkedList[T] = ref object + SinglyLinkedListObj[T] = ref object + + +proc addMoved[T](a, b: var SinglyLinkedList[T]) = + if a.addr != b.addr: discard + +proc addMoved[T](a, b: var SinglyLinkedListObj[T]) = + if a.addr != b.addr: discard + +proc main = + var a: SinglyLinkedList[int]; new a + var b: SinglyLinkedList[int]; new b + a.addMoved b + + var a0: SinglyLinkedListObj[int] + var b0: SinglyLinkedListObj[int] + a0.addMoved b0 + +static: main() + + +# bug #18641 + +type A = object + ha1: int +static: + var a = A() + var a2 = a.addr + a2.ha1 = 11 + doAssert a2.ha1 == 11 + a.ha1 = 12 + doAssert a.ha1 == 12 + doAssert a2.ha1 == 12 # ok +static: + proc fn() = + var a = A() + var a2 = a.addr + a2.ha1 = 11 + doAssert a2.ha1 == 11 + a.ha1 = 12 + doAssert a.ha1 == 12 + doAssert a2.ha1 == 12 # fails + fn() diff --git a/tests/vm/tmisc_vm.nim b/tests/vm/tmisc_vm.nim index 6eeecb869..1ad830b5f 100644 --- a/tests/vm/tmisc_vm.nim +++ b/tests/vm/tmisc_vm.nim @@ -1,8 +1,12 @@ discard """ - output: '''[127, 127, 0, 255] -[127, 127, 0, 255] - + targets: "c js" + output: ''' +[127, 127, 0, 255][127, 127, 0, 255] (data: 1) +(2, 1) +(2, 1) +(2, 1) +(f0: 5) ''' nimout: '''caught Exception @@ -18,8 +22,22 @@ foo4 (a: 0, b: 0) (a: 0, b: 0) (a: 0, b: 0) +z1 m: (lo: 12) +z2 a: (lo: 3) +x1 a: (lo: 3) +x2 a: (lo: 6) +x3 a: (lo: 0) +z3 a: (lo: 3) +x1 a: (lo: 3) +x2 a: (lo: 6) +x3 a: (lo: 0) +(2, 1) +(2, 1) +(2, 1) +(f0: 5) ''' """ +import std/sets #bug #1009 type @@ -96,8 +114,6 @@ static: simpleTryFinally() # bug #10981 -import sets - proc main = for i in 0..<15: var someSets = @[initHashSet[int]()] @@ -251,3 +267,193 @@ static: echo x2[] let x3 = new(ref MyObject) # cannot generate VM code for ref MyObject echo x3[] + +# bug #19464 +type + Wrapper = object + inner: int + +proc assign(r: var Wrapper, a: Wrapper) = + r = a + +proc myEcho(a: Wrapper) = + var tmp = a + assign(tmp, Wrapper(inner: 0)) # this shouldn't modify `a` + doAssert a.inner == 1 + +static: + var result: Wrapper + assign(result, Wrapper(inner: 1)) + myEcho(result) + +when true: + # bug #15974 + type Foo = object + f0: int + + proc fn(a: var Foo) = + var s: Foo + a = Foo(f0: 2) + s = a + doAssert s.f0 == 2 + a = Foo(f0: 3) + doAssert s.f0 == 2 + + proc test2()= + var a = Foo(f0: 1) + fn(a) + + static: test2() + test2() + +# bug #12551 +type + StUint = object + lo: uint64 + +func `+=`(x: var Stuint, y: Stuint) = + x.lo += y.lo + +func `-`(x, y: Stuint): Stuint = + result.lo = x.lo - y.lo + +func `+`(x, y: Stuint): Stuint = + result.lo = x.lo + y.lo + +func `-=`(x: var Stuint, y: Stuint) = + x = x - y + +func `<`(x, y: Stuint): bool= + x.lo < y.lo + +func `==`(x, y: Stuint): bool = + x.lo == y.lo + +func `<=`(x, y: Stuint): bool = + x.lo <= y.lo + +proc div3n2n(r: var Stuint, b: Stuint) = + var d: Stuint + r = d + r += b + +func div2n1n(r: var Stuint, b: Stuint) = + div3n2n(r, b) + +func divmodBZ(x, y: Stuint, r: var Stuint)= + div2n1n(r, y) + r.lo = 3 + +func `mod`(x, y: Stuint): Stuint = + divmodBZ(x, y, result) + +func doublemod_internal(a, m: Stuint): Stuint = + result = a + if a >= m - a: + result -= m + result += a + +func mulmod_internal(a, b, m: Stuint): Stuint = + var (a, b) = (a, b) + swap(a, b) + debugEcho "x1 a: ", a + a = doublemod_internal(a, m) + debugEcho "x2 a: ", a + a = doublemod_internal(a, m) + debugEcho "x3 a: ", a + +func powmod_internal(a, m: Stuint): Stuint = + var a = a + debugEcho "z1 m: ", m + debugEcho "z2 a: ", a + result = mulmod_internal(result, a, m) + debugEcho "z3 a: ", a + a = mulmod_internal(a, a, m) + +func powmod*(a, m: Stuint) = + discard powmod_internal(a mod m, m) + +static: + var x = Stuint(lo: high(uint64)) + var y = Stuint(lo: 12) + + powmod(x, y) + +# bug #16780 +when true: + template swap*[T](a, b: var T) = + var a2 = addr(a) + var b2 = addr(b) + var aOld = a2[] + a2[] = b2[] + b2[] = aOld + + proc rather = + block: + var a = 1 + var b = 2 + swap(a, b) + echo (a,b) + + block: + type Foo = ref object + x: int + var a = Foo(x:1) + var b = Foo(x:2) + swap(a, b) + echo (a.x, b.x) + + block: + type Foo = object + x: int + var a = Foo(x:1) + var b = Foo(x:2) + swap(a, b) + echo (a.x,b.x) + + static: rather() + rather() + +# bug #16020 +when true: + block: + type Foo = object + f0: int + proc main= + var f = Foo(f0: 3) + var f2 = f.addr + f2[].f0 += 1 + f2.f0 += 1 + echo f + static: main() + main() + +import tables, strutils + +# bug #14553 +const PpcPatterns = @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")] + +static: + var + needSecondIdentifier = initTable[uint32, seq[(string, string)]]() + + for (name, pattern) in PpcPatterns: + let + firstPart = 0'u32 + lastPart = "test" + + needSecondIdentifier.mgetOrPut(firstPart, @[]).add((name, pattern)) + + doAssert needSecondIdentifier[0] == @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")] + +# bug #17864 +macro transform*(fn: typed) = + quote do: + `fn` + +var map: Table[string, HashSet[string]] +proc publish*(): void {.transform.} = + map["k"] = init_hash_set[string]() + map["k"].incl "d" + +publish() diff --git a/tests/vm/tnewseqofcap.nim b/tests/vm/tnewseqofcap.nim new file mode 100644 index 000000000..a7dc07aa6 --- /dev/null +++ b/tests/vm/tnewseqofcap.nim @@ -0,0 +1,14 @@ +const + foo = @["aaa", "bbb", "ccc"] + +proc myTuple: tuple[n: int, bar: seq[string]] = + result.n = 42 + result.bar = newSeqOfCap[string](foo.len) + for f in foo: + result.bar.add(f) + +# It works if you change the below `const` to `let` +const + (n, bar) = myTuple() + +doAssert bar == @["aaa", "bbb", "ccc"] \ No newline at end of file diff --git a/tests/vm/tnilclosurecall.nim b/tests/vm/tnilclosurecall.nim new file mode 100644 index 000000000..449865b9c --- /dev/null +++ b/tests/vm/tnilclosurecall.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "attempt to call nil closure" + line: 8 +""" + +static: + let x: proc () = nil + x() diff --git a/tests/vm/tnilclosurecallstacktrace.nim b/tests/vm/tnilclosurecallstacktrace.nim new file mode 100644 index 000000000..879060e8e --- /dev/null +++ b/tests/vm/tnilclosurecallstacktrace.nim @@ -0,0 +1,23 @@ +discard """ + action: reject + nimout: ''' +stack trace: (most recent call last) +tnilclosurecallstacktrace.nim(23, 6) tnilclosurecallstacktrace +tnilclosurecallstacktrace.nim(20, 6) baz +tnilclosurecallstacktrace.nim(17, 6) bar +tnilclosurecallstacktrace.nim(14, 4) foo +tnilclosurecallstacktrace.nim(14, 4) Error: attempt to call nil closure +''' +""" + +proc foo(x: proc ()) = + x() + +proc bar(x: proc ()) = + foo(x) + +proc baz(x: proc ()) = + bar(x) + +static: + baz(nil) diff --git a/tests/vm/tnocompiletimefunc.nim b/tests/vm/tnocompiletimefunc.nim new file mode 100644 index 000000000..a95648c0f --- /dev/null +++ b/tests/vm/tnocompiletimefunc.nim @@ -0,0 +1,14 @@ +discard """ + errormsg: "request to generate code for .compileTime proc: foo" +""" + +# ensure compileTime funcs can't be called from runtime + +func foo(a: int): int {.compileTime.} = + a * a + +proc doAThing(): int = + for i in 0..2: + result += foo(i) + +echo doAThing() diff --git a/tests/vm/tnocompiletimefunclambda.nim b/tests/vm/tnocompiletimefunclambda.nim new file mode 100644 index 000000000..d134eea40 --- /dev/null +++ b/tests/vm/tnocompiletimefunclambda.nim @@ -0,0 +1,6 @@ +discard """ + errormsg: "request to generate code for .compileTime proc: :anonymous" +""" + +let a = func(a: varargs[int]) {.compileTime, closure.} = + discard a[0] \ No newline at end of file diff --git a/tests/vm/tnoreturn.nim b/tests/vm/tnoreturn.nim new file mode 100644 index 000000000..d4f8601a9 --- /dev/null +++ b/tests/vm/tnoreturn.nim @@ -0,0 +1,32 @@ +block: # issue #22216 + type + Result[T, E] = object + case oVal: bool + of false: + eVal: E + of true: + vVal: T + + func raiseResultDefect(m: string) {.noreturn, noinline.} = + raise (ref Defect)(msg: m) + + template withAssertOk(self: Result, body: untyped): untyped = + case self.oVal + of false: + raiseResultDefect("Trying to access value with err Result") + else: + body + + func value[T, E](self: Result[T, E]): T {.inline.} = + withAssertOk(self): + self.vVal + + const + x = Result[int, string](oVal: true, vVal: 123) + z = x.value() + + let + xx = Result[int, string](oVal: true, vVal: 123) + zz = x.value() + + doAssert z == zz diff --git a/tests/vm/topenarrays.nim b/tests/vm/topenarrays.nim new file mode 100644 index 000000000..375d2523d --- /dev/null +++ b/tests/vm/topenarrays.nim @@ -0,0 +1,89 @@ +proc mutate(a: var openarray[int]) = + var i = 0 + for x in a.mitems: + x = i + inc i + +proc mutate(a: var openarray[char]) = + var i = 1 + for ch in a.mitems: + ch = 'a' + + +static: + var a = [10, 20, 30] + assert a.toOpenArray(1, 2).len == 2 + + mutate(a) + assert a.toOpenArray(0, 2) == [0, 1, 2] + assert a.toOpenArray(0, 0) == [0] + assert a.toOpenArray(1, 2) == [1, 2] + assert "Hello".toOpenArray(1, 4) == "ello" + var str = "Hello" + str.toOpenArray(2, 4).mutate() + assert str.toOpenArray(0, 4).len == 5 + assert str.toOpenArray(0, 0).len == 1 + assert str.toOpenArray(0, 0).high == 0 + assert str == "Heaaa" + assert str.toOpenArray(0, 4) == "Heaaa" + + var arr: array[3..4, int] = [1, 2] + assert arr.toOpenArray(3, 4) == [1, 2] + assert arr.toOpenArray(3, 4).len == 2 + assert arr.toOpenArray(3, 3).high == 0 + + assert arr.toOpenArray(3, 4).toOpenArray(0, 0) == [1] + + +proc doThing(s: static openArray[int]) = discard + +doThing([10, 20, 30].toOpenArray(0, 0)) + +# bug #19969 +proc f(): array[1, byte] = + var a: array[1, byte] + result[0..0] = a.toOpenArray(0, 0) + +doAssert static(f()) == [byte(0)] + + +# bug #15952 +proc main1[T](a: openArray[T]) = discard +proc main2[T](a: var openArray[T]) = discard + +proc main = + var a = [1,2,3,4,5] + main1(a.toOpenArray(1,3)) + main2(a.toOpenArray(1,3)) +static: main() +main() + +# bug #16306 +{.experimental: "views".} +proc test(x: openArray[int]): tuple[id: int] = + let y: openArray[int] = toOpenArray(x, 0, 2) + result = (y[0],) +template fn= + doAssert test([0,1,2,3,4,5]).id == 0 +fn() # ok +static: fn() + + +block: # bug #22095 + type + StUint = object + limbs: array[4, uint64] + + func shlAddMod(a: var openArray[uint64]) = + a[0] = 10 + + func divRem(r: var openArray[uint64]) = + shlAddMod(r.toOpenArray(0, 3)) + + func fn(): StUint = + divRem(result.limbs) + + const + z = fn() + + doAssert z.limbs[0] == 10 diff --git a/tests/vm/toverflowopcaddimmint.nim b/tests/vm/toverflowopcaddimmint.nim index c36b9ed9b..4ff614e5b 100644 --- a/tests/vm/toverflowopcaddimmint.nim +++ b/tests/vm/toverflowopcaddimmint.nim @@ -7,5 +7,5 @@ static: var x = int64.high discard x + 1 - assert false + doAssert false p() diff --git a/tests/vm/toverflowopcaddint.nim b/tests/vm/toverflowopcaddint.nim index 6d96afc78..d494245b1 100644 --- a/tests/vm/toverflowopcaddint.nim +++ b/tests/vm/toverflowopcaddint.nim @@ -8,5 +8,5 @@ static: x = int64.high y = 1 discard x + y - assert false + doAssert false p() diff --git a/tests/vm/toverflowopcmulint.nim b/tests/vm/toverflowopcmulint.nim index 5607c59a7..936eea6c2 100644 --- a/tests/vm/toverflowopcmulint.nim +++ b/tests/vm/toverflowopcmulint.nim @@ -7,5 +7,5 @@ static: var x = 1'i64 shl 62 discard x * 2 - assert false + doAssert false p() diff --git a/tests/vm/toverflowopcsubimmint.nim b/tests/vm/toverflowopcsubimmint.nim index 09d6f745b..08356590c 100644 --- a/tests/vm/toverflowopcsubimmint.nim +++ b/tests/vm/toverflowopcsubimmint.nim @@ -6,5 +6,5 @@ static: proc p = var x = int64.low discard x - 1 - assert false + doAssert false p() diff --git a/tests/vm/toverflowopcsubint.nim b/tests/vm/toverflowopcsubint.nim index 8d114f200..74e34c6a4 100644 --- a/tests/vm/toverflowopcsubint.nim +++ b/tests/vm/toverflowopcsubint.nim @@ -8,5 +8,5 @@ static: x = int64.low y = 1 discard x - y - assert false + doAssert false p() diff --git a/tests/vm/tquadplus.nim b/tests/vm/tquadplus.nim index 552e8fef7..acf20cd96 100644 --- a/tests/vm/tquadplus.nim +++ b/tests/vm/tquadplus.nim @@ -1,8 +1,5 @@ # bug #1023 -discard """ - output: "1 == 1" -""" type Quadruple = tuple[a, b, c, d: int] @@ -14,4 +11,4 @@ const B = (a: 0, b: -2, c: 1, d: 0) C = A + B -echo C.d, " == ", (A+B).d +doAssert $C.d & " == " & $(A+B).d == "1 == 1" diff --git a/tests/vm/treset.nim b/tests/vm/treset.nim index ff8bc5b83..32fbc7f04 100644 --- a/tests/vm/treset.nim +++ b/tests/vm/treset.nim @@ -1,6 +1,3 @@ -discard """ - output: '''0''' -""" static: type Obj = object field: int @@ -48,6 +45,6 @@ proc main = var x = 4 x = default(int) - echo x + doAssert x == 0 main() diff --git a/tests/vm/triangle_array.nim b/tests/vm/triangle_array.nim index 054c66f22..0704239c6 100644 --- a/tests/vm/triangle_array.nim +++ b/tests/vm/triangle_array.nim @@ -1,7 +1,3 @@ -discard """ - output: "56" -""" - # bug #1781 proc initCombinations: array[11, array[11, int]] = @@ -14,4 +10,4 @@ proc initCombinations: array[11, array[11, int]] = result[6][6 .. 10] = [52,53,54,55,56] const combinations = initCombinations() -echo combinations[6][10] +doAssert combinations[6][10] == 56 diff --git a/tests/vm/tscriptcompiletime.nims b/tests/vm/tscriptcompiletime.nims new file mode 100644 index 000000000..daec54bf7 --- /dev/null +++ b/tests/vm/tscriptcompiletime.nims @@ -0,0 +1,9 @@ +discard """ + cmd: "nim e $file" +""" + +import mscriptcompiletime + +macro foo = + doAssert bar == 2 +foo() diff --git a/tests/vm/tsignaturehash.nim b/tests/vm/tsignaturehash.nim index 42e0a1571..972ec6fb0 100644 --- a/tests/vm/tsignaturehash.nim +++ b/tests/vm/tsignaturehash.nim @@ -1,7 +1,7 @@ # test sym digest is computable at compile time import macros, algorithm -import md5 +import ../../dist/checksums/src/checksums/md5 macro testmacro(s: typed{nkSym}): string = let s = getMD5(signaturehash(s) & " - " & symBodyHash(s)) diff --git a/tests/vm/tstring_openarray.nim b/tests/vm/tstring_openarray.nim index 1b8a1304c..9318344f8 100644 --- a/tests/vm/tstring_openarray.nim +++ b/tests/vm/tstring_openarray.nim @@ -12,16 +12,16 @@ proc set_all[T](s: var openArray[T]; val: T) = for i in 0..<s.len: s[i] = val -proc test() = - var a0 = "hello_world" - var a1 = [1,2,3,4,5,6,7,8,9] - var a2 = @[1,2,3,4,5,6,7,8,9] - a0.set_all('i') - a1.set_all(4) - a2.set_all(4) - doAssert a0 == "iiiiiiiiiii" - doAssert a1 == [4,4,4,4,4,4,4,4,4] - doAssert a2 == @[4,4,4,4,4,4,4,4,4] +proc main() = + var a0 = "hello_world" + var a1 = [1,2,3,4,5,6,7,8,9] + var a2 = @[1,2,3,4,5,6,7,8,9] + a0.set_all('i') + a1.set_all(4) + a2.set_all(4) + doAssert a0 == "iiiiiiiiiii" + doAssert a1 == [4,4,4,4,4,4,4,4,4] + doAssert a2 == @[4,4,4,4,4,4,4,4,4] const constval0 = "hello".map(proc(x: char): char = x) const constval1 = [1,2,3,4].map(proc(x: int): int = x) @@ -29,6 +29,5 @@ const constval1 = [1,2,3,4].map(proc(x: int): int = x) doAssert("hello".map(proc(x: char): char = x) == constval0) doAssert([1,2,3,4].map(proc(x: int): int = x) == constval1) -test() -static: - test() +static: main() +main() diff --git a/tests/vm/tstringnil.nim b/tests/vm/tstringnil.nim index df408910e..d5dd4f4c9 100644 --- a/tests/vm/tstringnil.nim +++ b/tests/vm/tstringnil.nim @@ -47,4 +47,4 @@ macro suite(suiteName, suiteDesc, suiteBloc: untyped): typed = # Test above suite basics, "Description of such": test(t5, ""): - assert false + doAssert false diff --git a/tests/vm/tswap.nim b/tests/vm/tswap.nim index 4243b5a71..bdbe5528c 100644 --- a/tests/vm/tswap.nim +++ b/tests/vm/tswap.nim @@ -3,7 +3,9 @@ nimout: ''' x.data = @[10] y = @[11] x.data = @[11] -y = @[10]''' +y = @[10] +@[3, 2, 1] +''' """ # bug #2946 @@ -22,3 +24,11 @@ proc testSwap(): int {.compiletime.} = result = 99 const something = testSwap() + +# bug #15463 +block: + static: + var s = @[1, 2, 3] + swap(s[0], s[2]) + + echo s diff --git a/tests/vm/ttouintconv.nim b/tests/vm/ttouintconv.nim index ff2187a36..8c43a3adb 100644 --- a/tests/vm/ttouintconv.nim +++ b/tests/vm/ttouintconv.nim @@ -75,3 +75,10 @@ macro foo2() = foo() foo2() + +block: + const neg5VM = block: + let x = -5'i8 + uint64(x) + let y = -5'i8 + doAssert uint64(y) == neg5VM diff --git a/tests/vm/ttypedesc.nim b/tests/vm/ttypedesc.nim new file mode 100644 index 000000000..d799e5adb --- /dev/null +++ b/tests/vm/ttypedesc.nim @@ -0,0 +1,31 @@ +block: # issue #15760 + type + Banana = object + SpecialBanana = object + + proc getName(_: type Banana): string = "Banana" + proc getName(_: type SpecialBanana): string = "SpecialBanana" + + proc x[T](): string = + const n = getName(T) # this one works + result = n + + proc y(T: type): string = + const n = getName(T) # this one failed to compile + result = n + + doAssert x[SpecialBanana]() == "SpecialBanana" + doAssert y(SpecialBanana) == "SpecialBanana" + +import macros + +block: # issue #23112 + type Container = object + foo: string + + proc canBeImplicit(t: typedesc) {.compileTime.} = + let tDesc = getType(t) + doAssert tDesc.kind == nnkObjectTy + + static: + canBeImplicit(Container) diff --git a/tests/vm/tunsupportedintfloatcast.nim b/tests/vm/tunsupportedintfloatcast.nim new file mode 100644 index 000000000..d65f10d86 --- /dev/null +++ b/tests/vm/tunsupportedintfloatcast.nim @@ -0,0 +1,3 @@ +static: + echo cast[int32](12.0) #[tt.Error + ^ VM does not support 'cast' from tyFloat with size 8 to tyInt32 with size 4 due to different sizes]# diff --git a/tests/vm/tvarsection.nim b/tests/vm/tvarsection.nim index d1c4926a0..cd34bd02e 100644 --- a/tests/vm/tvarsection.nim +++ b/tests/vm/tvarsection.nim @@ -1,7 +1,3 @@ -discard """ - output: '''-1abc''' -""" - var a {.compileTime.} = 2 b = -1 @@ -9,7 +5,7 @@ var d = "abc" static: - assert a == 2 - assert c == 3 + doAssert a == 2 + doAssert c == 3 -echo b, d +doAssert ($b & $d) == "-1abc" diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index 20adb5b8f..6aeac5529 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -1,8 +1,7 @@ -# bug #4462 import macros import os -import strutils +# bug #4462 block: proc foo(t: typedesc) {.compileTime.} = assert sameType(getType(t), getType(int)) @@ -10,26 +9,26 @@ block: static: foo(int) -# #4412 +# bug #4412 block: proc default[T](t: typedesc[T]): T {.inline.} = discard static: var x = default(type(0)) -# #6379 +# bug #6379 import algorithm static: var numArray = [1, 2, 3, 4, -1] numArray.sort(cmp) - assert numArray == [-1, 1, 2, 3, 4] + doAssert numArray == [-1, 1, 2, 3, 4] var str = "cba" str.sort(cmp) - assert str == "abc" + doAssert str == "abc" -# #6086 +# bug #6086 import math, sequtils, sugar block: @@ -43,7 +42,7 @@ block: var a = f() const b = f() - assert a == b + doAssert a == b block: proc f(): seq[char] = @@ -51,7 +50,7 @@ block: var runTime = f() const compTime = f() - assert runTime == compTime + doAssert runTime == compTime # #6083 block: @@ -65,26 +64,28 @@ block: result[i] = tmp const fact1000 = abc() - assert fact1000 == @[1, 2] + doAssert fact1000 == @[1, 2] # Tests for VM ops block: static: # for joint test, the project path is different, so I disabled it: when false: - assert "vm" in getProjectPath() + doAssert "vm" in getProjectPath() let b = getEnv("UNSETENVVAR") - assert b == "" - assert existsEnv("UNSERENVVAR") == false + doAssert b == "" + doAssert existsEnv("UNSERENVVAR") == false putEnv("UNSETENVVAR", "VALUE") - assert getEnv("UNSETENVVAR") == "VALUE" - assert existsEnv("UNSETENVVAR") == true + doAssert getEnv("UNSETENVVAR") == "VALUE" + doAssert existsEnv("UNSETENVVAR") == true - assert fileExists("MISSINGFILE") == false - assert dirExists("MISSINGDIR") == false + doAssert fileExists("MISSINGFILE") == false + doAssert dirExists("MISSINGDIR") == false + doAssert fileExists(currentSourcePath()) + doAssert dirExists(currentSourcePath().parentDir) -# #7210 +# bug #7210 block: static: proc f(size: int): int = @@ -92,7 +93,7 @@ block: result = size doAssert f(4) == 4 -# #6689 +# bug #6689 block: static: proc foo(): int = 0 @@ -107,7 +108,7 @@ block: new(x) doAssert(not x.isNil) -# #7871 +# bug #7871 static: type Obj = object field: int @@ -117,11 +118,11 @@ static: o.field = 2 doAssert s[0].field == 0 -# #8125 +# bug #8125 static: let def_iter_var = ident("it") -# #8142 +# bug #8142 static: type Obj = object names: string @@ -137,7 +138,7 @@ static: o.pushName() doAssert o.names == "FOOBARFOOBAR" -# #8154 +# bug #8154 import parseutils static: @@ -150,7 +151,7 @@ static: static: doAssert foo().i == 1 -# #10333 +# bug #10333 block: const encoding: auto = [ @@ -161,7 +162,7 @@ block: ] doAssert encoding.len == 4 -# #10886 +# bug #10886 proc tor(): bool = result = true @@ -178,3 +179,618 @@ const static: doAssert ctor doAssert ctand + +block: # bug #13081 + type Kind = enum + k0, k1, k2, k3 + + type Foo = object + x0: float + case kind: Kind + of k0: discard + of k1: x1: int + of k2: x2: string + of k3: x3: string + + const j1 = Foo(x0: 1.2, kind: k1, x1: 12) + const j2 = Foo(x0: 1.3, kind: k2, x2: "abc") + const j3 = Foo(x0: 1.3, kind: k3, x3: "abc2") + static: + doAssert $j1 == "(x0: 1.2, kind: k1, x1: 12)" + doAssert $j2 == """(x0: 1.3, kind: k2, x2: "abc")""" + doAssert $j3 == """(x0: 1.3, kind: k3, x3: "abc2")""" + doAssert $j1 == "(x0: 1.2, kind: k1, x1: 12)" + doAssert $j2 == """(x0: 1.3, kind: k2, x2: "abc")""" + doAssert $j3 == """(x0: 1.3, kind: k3, x3: "abc2")""" + + doAssert j1.x1 == 12 + static: + doAssert j1.x1 == 12 + +block: # bug #15595 + proc fn0()=echo 0 + proc fn1()=discard + proc main= + var local = 0 + proc fn2()=echo local + var a0 = fn0 + var a1 = fn1 + var a2 = fn2 + var a3: proc() + var a4: proc() + doAssert a0 == fn0 # bugfix + doAssert a1 == fn1 # ditto + doAssert a2 == fn2 # ditto + + doAssert fn0 != fn1 + + doAssert a2 != nil + doAssert a3 == nil # bugfix + + doAssert a3 == a4 # bugfix + static: main() + main() + +block: # issue #20543 + type F = proc() + const myArray = block: + var r: array[1, F] + r[0] = nil + r + doAssert isNil(myArray[0]) + +# bug #15363 +import sequtils + +block: + func identity(a: bool): bool = a + + var a: seq[bool] = static: + newSeq[bool](0).mapIt(it) # segfaults + var b: seq[bool] = static: + newSeq[bool](0).filterIt(it) # does not segfault + var c: seq[bool] = static: + newSeq[bool](0).map(identity) # does not segfault + var d: seq[bool] = static: + newSeq[bool](0).map(proc (a: bool): bool = false) # segfaults + var e: seq[bool] = static: + newSeq[bool](0).filter(identity) # does not segfault + var f: seq[bool] = static: + newSeq[bool](0).filter(proc (a: bool): bool = false) # segfaults + + doAssert a == @[] + doAssert b == @[] + doAssert c == @[] + doAssert d == @[] + doAssert e == @[] + doAssert f == @[] + + +block: # bug #18310 + macro t() : untyped = + let + x = nnkTupleConstr.newTree(newLit(1)) + y = nnkTupleConstr.newTree(newLit(2)) + doAssert not (x == y) # not using != intentionally + doAssert not(cast[int](x) == cast[int](y)) + doAssert not(system.`==`(x, y)) + doAssert system.`==`(x, x) + t() + +block: # bug #10815 + type + Opcode = enum + iChar, iSet + + Inst = object + case code: Opcode + of iChar: + c: char + of iSet: + cs: set[char] + + Patt = seq[Inst] + + + proc `$`(p: Patt): string = + discard + + proc P(): Patt = + result.add Inst(code: iSet) + + const a = P() + doAssert $a == "" + +import tables + +block: # bug #8007 + type + CostKind = enum + Fixed, + Dynamic + + Cost = object + case kind*: CostKind + of Fixed: + cost*: int + of Dynamic: + handler*: proc(value: int): int {.nimcall.} + + proc foo(value: int): int {.nimcall.} = + sizeof(value) + + const a: array[2, Cost] =[ + Cost(kind: Fixed, cost: 999), + Cost(kind: Dynamic, handler: foo) + ] + + # OK with arrays & object variants + doAssert $a == "[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]" + + const b: Table[int, Cost] = { + 0: Cost(kind: Fixed, cost: 999), + 1: Cost(kind: Dynamic, handler: foo) + }.toTable + + # KO with Tables & object variants + # echo b # {0: (kind: Fixed, cost: 0), 1: (kind: Dynamic, handler: ...)} # <----- wrong behaviour + doAssert $b == "{0: (kind: Fixed, cost: 999), 1: (kind: Dynamic, handler: ...)}" + + const c: Table[int, int] = { + 0: 100, + 1: 999 + }.toTable + + # OK with Tables and primitive int + doAssert $c == "{0: 100, 1: 999}" + + # For some reason the following gives + # Error: invalid type for const: Cost + const d0 = Cost(kind: Fixed, cost: 999) + + # OK with seq & object variants + const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)] + doAssert $d == "@[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]" + +block: # bug #14340 + block: + proc opl3EnvelopeCalcSin0() = discard + type EnvelopeSinfunc = proc() {.nimcall.} # todo: fixme + # const EnvelopeCalcSin0 = opl3EnvelopeCalcSin0 # ok + const EnvelopeCalcSin0: EnvelopeSinfunc = opl3EnvelopeCalcSin0 # was bug + const envelopeSin = [EnvelopeCalcSin0] + var a = 0 + envelopeSin[a]() + + block: + type Mutator = proc() {.noSideEffect, gcsafe.} + proc mutator0() = discard + const mTable = [Mutator(mutator0)] + var i=0 + mTable[i]() + +block: # VM wrong register free causes errors in unrelated code + block: # bug #15597 + #[ + Error: unhandled exception: 'sym' is not accessible using discriminant 'kind' of type 'TNode' [FieldDefect] + in /Users/timothee/git_clone/nim/Nim_prs/compiler/vm.nim(1176) rawExecute + in opcIndCall + in let prc = if not isClosure: bb.sym else: bb[0].sym + ]# + proc bar2(head: string): string = "asdf" + proc zook(u1: int) = discard + + type PathEntry = object + kind: int + path: string + + iterator globOpt(): int = + var u1: int + + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + zook(u1) + + var entry = PathEntry() + entry.path = bar2("") + if false: + echo "here2" + + proc processAux(a: float) = discard + + template bar(iter: untyped): untyped = + var ret: float + for x in iter: break + ret + + proc main() = + processAux(bar(globOpt())) + static: main() + + block: # ditto + # D20201024T133245 + type Deque = object + proc initDeque2(initialSize: int = 4): Deque = Deque() + proc len2(a: Deque): int = 2 + proc baz(dir: string): bool = true + proc bar2(head: string): string = "asdf" + proc bar3(path: var string) = path = path + + type PathEntry = object + kind: int + path: string + + proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string = dir + + iterator globOpt(dir: string): int = + var stack = initDeque2() + doAssert baz("") + let z = stack.len2 + if stack.len2 >= 0: + var entry = PathEntry() + let current = if true: stack.len2 else: stack.len2 + entry.path = bar2("") + bar3(entry.path) + if false: + echo "here2" # comment here => you get same error as https://github.com/nim-lang/Nim/issues/15704 + + proc processAux(a: float) = discard + + template bar(iter: untyped): untyped = + var ret: float + for x in iter: break + ret + proc main() = + processAux(bar(globOpt(initGlobOpt(".")))) + static: main() + + block: # bug #15704 + #[ + Error: attempt to access a nil address kind: rkFloat + ]# + type Deque = object + proc initDeque2(initialSize: int = 4): Deque = Deque() + proc len2(a: Deque): int = 2 + + proc baz(dir: string): bool = true + proc bar2(head: string): string = "asdf" + proc bar3(path: var string) = path = path + + type PathEntry = object + kind: int + path: string + depth: int + + proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string = + dir + + iterator globOpt(dir: string): int = + var stack = initDeque2() + doAssert baz("") + let z = stack.len2 + var a5: int + if stack.len2 >= 0: + var entry = PathEntry() + if false: + echo "here" + let current = if true: stack.len2 else: stack.len2 + entry.depth = 1 + entry.path = bar2("") + bar3(entry.path) + proc processAux(a: float) = discard + template bar(iter: untyped): untyped = + var ret: float + for x in iter: + break + ret + const dir = "." + proc main() = + processAux(bar(globOpt(initGlobOpt(dir)))) + static: main() + +block: # bug #8015 + block: + type Foo = object + case b: bool + of false: v1: int + of true: v2: int + const t = [Foo(b: false, v1: 1), Foo(b: true, v2: 2)] + doAssert $t == "[(b: false, v1: 1), (b: true, v2: 2)]" + doAssert $t[0] == "(b: false, v1: 1)" # was failing + + block: + type + CostKind = enum + Fixed, + Dynamic + + Cost = object + case kind*: CostKind + of Fixed: + cost*: int + of Dynamic: + handler*: proc(): int {.nimcall.} + + proc foo1(): int {.nimcall.} = + 100 + + proc foo2(): int {.nimcall.} = + 200 + + # Change to `let` and it doesn't crash + const costTable = [ + 0: Cost(kind: Fixed, cost: 999), + 1: Cost(kind: Dynamic, handler: foo1), + 2: Cost(kind: Dynamic, handler: foo2) + ] + + doAssert $costTable[0] == "(kind: Fixed, cost: 999)" + doAssert costTable[1].handler() == 100 + doAssert costTable[2].handler() == 200 + + # Now trying to carry the table as an object field + type + Wrapper = object + table: array[3, Cost] + + proc procNewWrapper(): Wrapper = + result.table = costTable + + # Alternatively, change to `const` and it doesn't crash + let viaProc = procNewWrapper() + + doAssert viaProc.table[1].handler != nil + doAssert viaProc.table[2].handler != nil + doAssert $viaProc.table[0] == "(kind: Fixed, cost: 999)" + doAssert viaProc.table[1].handler() == 100 + doAssert viaProc.table[2].handler() == 200 + + +# bug #19198 + +block: + type + Foo[n: static int] = int + +block: + static: + let x = int 1 + doAssert $(x.type) == "int" # Foo + +block: + static: + let x = int 1 + let y = x + 1 + # Error: unhandled exception: value out of range: -8 notin 0 .. 65535 [RangeDefect] + doAssert y == 2 + + +type Atom* = object + bar: int + +proc main() = # bug #12994 + var s: seq[Atom] + var atom: Atom + var checked = 0 + for i in 0..<2: + atom.bar = 5 + s.add atom + atom.reset + if i == 0: + checked += 1 + doAssert $s == "@[(bar: 5)]" + else: + checked += 1 + doAssert $s == "@[(bar: 5), (bar: 5)]" + doAssert checked == 2 + +static: main() +main() + +# bug #19201 +proc foo(s: sink string) = doAssert s.len == 3 + +static: + foo("abc") + + +static: + for i in '1' .. '2': # bug #10938 + var s: set[char] + doAssert s == {} + incl(s, i) + + for _ in 0 ..< 3: # bug #13312 + var s: string + s.add("foo") + doAssert s == "foo" + + for i in 1 .. 5: # bug #13918 + var arr: array[3, int] + var val: int + doAssert arr == [0, 0, 0] and val == 0 + for j in 0 ..< len(arr): + arr[j] = i + val = i + +# bug #20985 +let a = block: + var groups: seq[seq[int]] + for i in 0 ..< 3: + var group: seq[int] + for j in 0 ..< 3: + group.add j + groups.add group + groups + +const b = block: + var groups: seq[seq[int]] + for i in 0 ..< 3: + var group: seq[int] + for j in 0 ..< 3: + group.add j + groups.add group + groups + +doAssert a == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]] +doAssert b == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]] + +macro m1(s: string): int = + var ProcID {.global, compileTime.}: int + inc(ProcID) + result = newLit(ProcID) + +proc macroGlobal = + doAssert m1("Macro argument") == 1 + doAssert m1("Macro argument") == 2 + doAssert m1("Macro argument") == 3 + +static: macroGlobal() +macroGlobal() + +block: # bug #10108 + template reject(x) = + static: doAssert(not compiles(x)) + + static: + let x: int = 2 + proc deliver_x(): int = x + var y2 = deliver_x() + discard y2 + reject: + const c5 = deliver_x() + +block: # bug #7590 + proc doInit[T]():auto= + var a: T + return a + + proc fun2[T](tup1:T)= + const tup0=doInit[T]() + + # var tup=tup0 #ok + const tup=tup0 #causes bug + + doAssert tup is tuple + doAssert tup[0] is tuple + for ai in tup.fields: + doAssert ai is tuple, "BUG2" + + # const c=(foo:(bar1: 0.0)) + const c=(foo:(bar1:"foo1")) + fun2(c) + +block: # bug #21708 + type + Tup = tuple[name: string] + + const X: array[2, Tup] = [(name: "foo",), (name: "bar",)] + + static: + let s = X[0] + doAssert s[0] == "foo" + +block: + proc swap[T](x: var T): T = + result = x + x = default(T) + + proc merge[T](a, b: var openArray[T]) = + a[0] = swap b[0] + + static: + var x = "abc" + var y = "356" + merge(x, y) + doAssert x == "3bc" + +block: # bug #22190 + type + EVMFork = enum + Berlin + Istanbul + Shanghai + + const + Vm2OpAllForks = + {EVMFork.low .. EVMFork.high} + + vm2OpExecBlockData = [(forks: Vm2OpAllForks)] + + proc mkOpTable(selected: EVMFork): bool = + selected notin vm2OpExecBlockData[0].forks + + const + tab = mkOpTable(Berlin) + + doAssert not tab + +block: # issue #22524 + const cnst = cstring(nil) + doAssert cnst.isNil + doAssert cnst == nil + let b = cnst + doAssert b.isNil + doAssert b == nil + + let a = static: cstring(nil) + doAssert a.isNil + + static: + var x: cstring + doAssert x.isNil + doAssert x == nil + doAssert x != "" + +block: # issue #15730 + const s: cstring = "" + doAssert s != nil + + static: + let s: cstring = "" + doAssert not s.isNil + doAssert s != nil + doAssert s == "" + +static: # more nil cstring issues + let x = cstring(nil) + doAssert x.len == 0 + +block: # bug #23925 + type Foo = enum A = -1 + proc foo = + doAssert cast[Foo](-1) == A + doAssert ord(A) == -1 + + static: foo() + foo() + + type E = enum + e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13 e14 e15 e16 e17 e18 e19 e20 + e21 e22 e23 e24 e25 e26 e27 e28 e29 e30 e31 e32 e33 e34 e35 e36 e37 e38 + e39 e40 e41 e42 e43 e44 e45 e46 e47 e48 e49 e50 e51 e52 e53 e54 e55 e56 + e57 e58 e59 e60 e61 e62 e63 e64 e65 e66 e67 e68 e69 e70 e71 e72 e73 e74 + e75 e76 e77 e78 e79 e80 e81 e82 e83 e84 e85 e86 e87 e88 e89 e90 e91 e92 + e93 e94 e95 e96 e97 e98 e99 e100 e101 e102 e103 e104 e105 e106 e107 e108 + e109 e110 e111 e112 e113 e114 e115 e116 e117 e118 e119 e120 e121 e122 + e123 e124 e125 e126 e127 e128 + proc bar = + doAssert cast[E](int(e128)) == e128 + + static: bar() + bar() + +static: # bug #21353 + var s: proc () = default(proc ()) + doAssert s == nil diff --git a/tests/vm/tvmops.nim b/tests/vm/tvmops.nim index 6442c49d6..3d8d5a9ac 100644 --- a/tests/vm/tvmops.nim +++ b/tests/vm/tvmops.nim @@ -1,3 +1,7 @@ +discard """ + targets: "c cpp js" +""" + #[ test for vmops.nim ]# @@ -5,16 +9,6 @@ import os import math import strutils -template forceConst(a: untyped): untyped = - ## Force evaluation at CT, useful for example here: - ## `callFoo(forceConst(getBar1()), getBar2())` - ## instead of: - ## block: - ## const a = getBar1() - ## `callFoo(a, getBar2())` - const ret = a - ret - static: # TODO: add more tests block: #getAppFilename, gorgeEx, gorge @@ -22,7 +16,7 @@ static: let ret = gorgeEx(nim & " --version") doAssert ret.exitCode == 0 doAssert ret.output.contains "Nim Compiler" - let ret2 = gorgeEx(nim & " --unexistant") + let ret2 = gorgeEx(nim & " --nonxistent") doAssert ret2.exitCode != 0 let output3 = gorge(nim & " --version") doAssert output3.contains "Nim Compiler" @@ -47,6 +41,6 @@ static: block: # Check against bugs like #9176 - doAssert getCurrentCompilerExe() == forceConst(getCurrentCompilerExe()) + doAssert getCurrentCompilerExe() == getCurrentCompilerExe().static if false: #pending #9176 - doAssert gorgeEx("unexistant") == forceConst(gorgeEx("unexistant")) + doAssert gorgeEx("nonxistent") == gorgeEx("nonxistent").static diff --git a/tests/vm/tvmopsDanger.nim b/tests/vm/tvmopsDanger.nim new file mode 100644 index 000000000..966feffe6 --- /dev/null +++ b/tests/vm/tvmopsDanger.nim @@ -0,0 +1,13 @@ +discard """ + cmd: "nim c --experimental:vmopsDanger -r $file" +""" +when defined(nimPreviewSlimSystem): + import std/assertions +import std/[times, os] + +const foo = getTime() +let bar = foo +doAssert bar > low(Time) + +static: # bug #23932 + doAssert getCurrentDir().len > 0 diff --git a/tests/vm/twrong_concat.nim b/tests/vm/twrong_concat.nim index 538ea2527..59a10bdb9 100644 --- a/tests/vm/twrong_concat.nim +++ b/tests/vm/twrong_concat.nim @@ -1,7 +1,3 @@ -discard """ - output: '''success''' -""" - # bug #3804 #import sequtils @@ -23,6 +19,4 @@ static: sameBug(objs) # sameBug(objs) echo objs[0].field - assert(objs[0].field == "hello") # fails, because (objs[0].field == "hello bug") - mutated! - -echo "success" + doAssert(objs[0].field == "hello") # fails, because (objs[0].field == "hello bug") - mutated! diff --git a/tests/vm/twrongarray.nim b/tests/vm/twrongarray.nim index c1514d0e9..7f24290e2 100644 --- a/tests/vm/twrongarray.nim +++ b/tests/vm/twrongarray.nim @@ -14,4 +14,4 @@ when false: proc two(dummy: int, size: int) = var x: array[size * 1, int] # compiles, but shouldn't? - #assert(x.len == size) # just for fun + # doAssert(x.len == size) # just for fun diff --git a/tests/vm/tyaytypedesc.nim b/tests/vm/tyaytypedesc.nim index a3ad9b707..8cb402bff 100644 --- a/tests/vm/tyaytypedesc.nim +++ b/tests/vm/tyaytypedesc.nim @@ -1,7 +1,3 @@ -discard """ - output: "ntWhitespace" -""" - # bug #3357 type NodeType* = enum @@ -10,7 +6,7 @@ type NodeType* = enum type TokenType* = enum ttWhitespace -proc enumTable*[A, B, C](a: openarray[tuple[key: A, val: B]], ret: typedesc[C]): C = +proc enumTable*[A, B, C](a: openArray[tuple[key: A, val: B]], ret: typedesc[C]): C = for item in a: result[item.key] = item.val @@ -18,4 +14,4 @@ const tokenTypeToNodeType = { ttWhitespace: ntWhitespace, }.enumTable(array[ttWhitespace..ttWhitespace, NodeType]) -echo tokenTypeToNodeType[ttWhitespace] +doAssert tokenTypeToNodeType[ttWhitespace] == ntWhitespace diff --git a/tests/vm/tzero_extend.nim b/tests/vm/tzero_extend.nim index 1fed5d419..418dbc486 100644 --- a/tests/vm/tzero_extend.nim +++ b/tests/vm/tzero_extend.nim @@ -5,10 +5,10 @@ proc get_values(): (seq[int8], seq[int16], seq[int32]) = let i8 = -3'i8 let i16 = -3'i16 let i32 = -3'i32 - doAssert i8.ze == 0xFD - doAssert i8.ze64 == 0xFD - doAssert i16.ze == 0xFFFD - doAssert i16.ze64 == 0xFFFD + doAssert int(cast[uint8](i8)) == 0xFD + doAssert int64(cast[uint8](i8)) == 0xFD + doAssert int(cast[uint16](i16)) == 0xFFFD + doAssert int64(cast[uint16](i16)) == 0xFFFD result[0] = @[]; result[1] = @[]; result[2] = @[] |