mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
512 lines
11 KiB
Nim
512 lines
11 KiB
Nim
# bug #4462
|
|
import macros
|
|
import os
|
|
|
|
block:
|
|
proc foo(t: typedesc) {.compileTime.} =
|
|
assert sameType(getType(t), getType(int))
|
|
|
|
static:
|
|
foo(int)
|
|
|
|
# #4412
|
|
block:
|
|
proc default[T](t: typedesc[T]): T {.inline.} = discard
|
|
|
|
static:
|
|
var x = default(type(0))
|
|
|
|
# #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"
|
|
|
|
# #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
|
|
|
|
# #7210
|
|
block:
|
|
static:
|
|
proc f(size: int): int =
|
|
var some = newStringOfCap(size)
|
|
result = size
|
|
doAssert f(4) == 4
|
|
|
|
# #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)
|
|
|
|
# #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
|
|
|
|
# #8125
|
|
static:
|
|
let def_iter_var = ident("it")
|
|
|
|
# #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"
|
|
|
|
# #8154
|
|
import parseutils
|
|
|
|
static:
|
|
type Obj = object
|
|
i: int
|
|
|
|
proc foo(): Obj =
|
|
discard parseInt("1", result.i, 0)
|
|
|
|
static:
|
|
doAssert foo().i == 1
|
|
|
|
# #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
|
|
|
|
# #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()
|
|
|
|
# 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 == @[]
|
|
|
|
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, locks: 0.}
|
|
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 gook(u1: int) = discard
|
|
|
|
type PathEntry = object
|
|
kind: int
|
|
path: string
|
|
|
|
iterator globOpt(): int =
|
|
var u1: int
|
|
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(u1)
|
|
gook(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
|