import macros import os # bug #4462 block: proc foo(t: typedesc) {.compileTime.} = assert sameType(getType(t), getType(typedesc[int])) assert sameType(getType(t), getType(type int)) static: foo(int) # bug #4412 block: proc default[T](t: typedesc[T]): T {.inline.} = discard static: var x = default(type(0)) # bug #6379 import algorithm static: var numArray = [1, 2, 3, 4, -1] numArray.sort(cmp) doAssert numArray == [-1, 1, 2, 3, 4] var str = "cba" str.sort(cmp) doAssert str == "abc" # bug #6086 import math, sequtils, sugar block: proc f: int = toSeq(10..<10_000).filter( a => a == ($a).map( d => (d.ord-'0'.ord).int^4 ).sum ).sum var a = f() const b = f() doAssert a == b block: proc f(): seq[char] = result = "hello".map(proc(x: char): char = x) var runTime = f() const compTime = f() doAssert runTime == compTime # #6083 block: proc abc(): seq[int] = result = @[0] result.setLen(2) var tmp: int for i in 0 ..< 2: inc tmp result[i] = tmp const fact1000 = abc() doAssert fact1000 == @[1, 2] # Tests for VM ops block: static: # for joint test, the project path is different, so I disabled it: when false: doAssert "vm" in getProjectPath() let b = getEnv("UNSETENVVAR") doAssert b == "" doAssert existsEnv("UNSERENVVAR") == false putEnv("UNSETENVVAR", "VALUE") doAssert getEnv("UNSETENVVAR") == "VALUE" doAssert existsEnv("UNSETENVVAR") == true doAssert fileExists("MISSINGFILE") == false doAssert dirExists("MISSINGDIR") == false doAssert fileExists(currentSourcePath()) doAssert dirExists(currentSourcePath().parentDir) # bug #7210 block: static: proc f(size: int): int = var some = newStringOfCap(size) result = size doAssert f(4) == 4 # bug #6689 block: static: proc foo(): int = 0 var f: proc(): int doAssert f.isNil f = foo doAssert(not f.isNil) block: static: var x: ref ref int new(x) doAssert(not x.isNil) # bug #7871 static: type Obj = object field: int var s = newSeq[Obj](1) var o = Obj() s[0] = o o.field = 2 doAssert s[0].field == 0 # bug #8125 static: let def_iter_var = ident("it") # bug #8142 static: type Obj = object names: string proc pushName(o: var Obj) = var s = "" s.add("FOOBAR") o.names.add(s) var o = Obj() o.names = "" o.pushName() o.pushName() doAssert o.names == "FOOBARFOOBAR" # bug #8154 import parseutils static: type Obj = object i: int proc foo(): Obj = discard parseInt("1", result.i, 0) static: doAssert foo().i == 1 # bug #10333 block: const encoding: auto = [ ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], ["", "M", "MM", "MMM", "--", "-", "--", "---", "----", "--"], ] doAssert encoding.len == 4 # bug #10886 proc tor(): bool = result = true result = false or result proc tand(): bool = result = false result = true and result const ctor = tor() ctand = not tand() 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 == "" when defined osx: # xxx bug #13481 block: type CharSet {.union.} = object cs: set[char] vs: array[4, uint64] const a = Charset(cs: {'a'..'z'}) doAssert a.repr.len > 0 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() # 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) == "Foo" # 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