Files
Nim/tests/arc/tarcmisc.nim

837 lines
15 KiB
Nim

discard """
output: '''
Destructor for TestTestObj
=destroy called
123xyzabc
destroyed: false
destroyed: false
destroyed2: false
destroyed2: false
destroying variable: 2
destroying variable: 1
whiley ends :(
1
(x: "0")
(x: "1")
(x: "2")
(x: "3")
(x: "4")
(x: "5")
(x: "6")
(x: "7")
(x: "8")
(x: "9")
(x: "10")
0
new line before - @['a']
new line after - @['a']
finalizer
aaaaa
hello
true
copying
123
42
@["", "d", ""]
ok
destroying variable: 20
destroying variable: 10
closed
'''
cmd: "nim c --mm:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file"
"""
block: # bug #23627
type
TestObj = object of RootObj
Test2 = object of RootObj
foo: TestObj
TestTestObj = object of RootObj
shit: TestObj
proc `=destroy`(x: TestTestObj) =
echo "Destructor for TestTestObj"
let test = Test2(foo: TestObj())
proc testCaseT() =
let tt1 {.used.} = TestTestObj(shit: TestObj())
proc main() =
testCaseT()
main()
# bug #9401
type
MyObj = object
len: int
data: ptr UncheckedArray[float]
proc `=destroy`*(m: MyObj) =
echo "=destroy called"
if m.data != nil:
deallocShared(m.data)
type
MyObjDistinct = distinct MyObj
proc `=copy`*(m: var MyObj, m2: MyObj) =
if m.data == m2.data: return
if m.data != nil:
`=destroy`(m)
m.len = m2.len
if m.len > 0:
m.data = cast[ptr UncheckedArray[float]](allocShared(sizeof(float) * m.len))
copyMem(m.data, m2.data, sizeof(float) * m.len)
proc `=sink`*(m: var MyObj, m2: MyObj) =
if m.data != m2.data:
if m.data != nil:
`=destroy`(m)
m.len = m2.len
m.data = m2.data
proc newMyObj(len: int): MyObj =
result.len = len
result.data = cast[ptr UncheckedArray[float]](allocShared(sizeof(float) * len))
proc newMyObjDistinct(len: int): MyObjDistinct =
MyObjDistinct(newMyObj(len))
proc fooDistinct =
doAssert newMyObjDistinct(2).MyObj.len == 2
fooDistinct()
proc takeSink(x: sink string): bool = true
proc b(x: sink string): string =
if takeSink(x):
return x & "abc"
proc bbb(inp: string) =
let y = inp & "xyz"
echo b(y)
bbb("123")
# bug #13691
type Variable = ref object
value: int
proc `=destroy`(self: typeof(Variable()[])) =
echo "destroying variable: ",self.value
proc newVariable(value: int): Variable =
result = Variable()
result.value = value
#echo "creating variable: ",result.value
proc test(count: int) =
var v {.global.} = newVariable(10)
var count = count - 1
if count == 0: return
test(count)
echo "destroyed: ", v.isNil
test(3)
proc test2(count: int) =
block: #XXX: Fails with block currently
var v {.global.} = newVariable(20)
var count = count - 1
if count == 0: return
test2(count)
echo "destroyed2: ", v.isNil
test2(3)
proc whiley =
var a = newVariable(1)
while true:
var b = newVariable(2)
if true: raise newException(CatchableError, "test")
try:
whiley()
except CatchableError:
echo "whiley ends :("
#------------------------------------------------------------------------------
# issue #13810
import streams
type
A = ref AObj
AObj = object of RootObj
io: Stream
B = ref object of A
x: int
proc `=destroy`(x: AObj) =
close(x.io)
echo "closed"
var x = B(io: newStringStream("thestream"))
#------------------------------------------------------------------------------
# issue #14003
proc cryptCTR*(nonce: var openArray[char]) =
nonce[1] = 'A'
proc main() =
var nonce1 = "0123456701234567"
cryptCTR(nonce1)
doAssert(nonce1 == "0A23456701234567")
var nonce2 = "01234567"
cryptCTR(nonce2.toOpenArray(0, nonce2.len-1))
doAssert(nonce2 == "0A234567")
main()
# bug #14079
import std/algorithm
let
n = @["c", "b"]
q = @[("c", "2"), ("b", "1")]
doAssert n.sortedByIt(it) == @["b", "c"], "fine"
doAssert q.sortedByIt(it[0]) == @[("b", "1"), ("c", "2")], "fails under arc"
#------------------------------------------------------------------------------
# issue #14236
type
MyType = object
a: seq[int]
proc re(x: static[string]): static MyType =
MyType()
proc match(inp: string, rg: static MyType) =
doAssert rg.a.len == 0
match("ac", re"a(b|c)")
#------------------------------------------------------------------------------
# issue #14243
type
Game* = ref object
proc free*(game: Game) =
let a = 5
proc newGame*(): Game =
new(result, free)
var game*: Game
#------------------------------------------------------------------------------
# issue #14333
type
SimpleLoop = object
Lsg = object
loops: seq[ref SimpleLoop]
root: ref SimpleLoop
var lsg: Lsg
lsg.loops.add lsg.root
echo lsg.loops.len
# bug #14495
type
Gah = ref object
x: string
proc bug14495 =
var owners: seq[Gah]
for i in 0..10:
owners.add Gah(x: $i)
var x: seq[Gah]
for i in 0..10:
x.add owners[i]
for i in 0..100:
setLen(x, 0)
setLen(x, 10)
for i in 0..x.len-1:
if x[i] != nil:
echo x[i][]
for o in owners:
echo o[]
bug14495()
# bug #14396
type
Spinny = ref object
t: ref int
text: string
proc newSpinny*(): Spinny =
Spinny(t: new(int), text: "hello")
proc spinnyLoop(x: ref int, spinny: sink Spinny) =
echo x[]
proc start*(spinny: sink Spinny) =
spinnyLoop(spinny.t, spinny)
var spinner1 = newSpinny()
spinner1.start()
# bug #14345
type
SimpleLoopB = ref object
children: seq[SimpleLoopB]
parent: SimpleLoopB
proc addChildLoop(self: SimpleLoopB, loop: SimpleLoopB) =
self.children.add loop
proc setParent(self: SimpleLoopB, parent: SimpleLoopB) =
self.parent = parent
self.parent.addChildLoop(self)
var l = SimpleLoopB()
l.setParent(l)
# bug #14968
import times
let currentTime = now().utc
# bug #14994
import sequtils
var newLine = @['a']
let indent = newSeq[char]()
echo "new line before - ", newline
newline.insert(indent, 0)
echo "new line after - ", newline
# bug #15044
type
Test = ref object
proc test: Test =
# broken
new(result, proc(x: Test) =
echo "finalizer"
)
proc tdirectFinalizer =
discard test()
tdirectFinalizer()
# bug #14480
proc hello(): int =
result = 42
var leaves {.global.} = hello()
doAssert leaves == 42
# bug #15052
proc mutstrings =
var data = "hello"
for c in data.mitems():
c = 'a'
echo data
mutstrings()
# bug #15038
type
Machine = ref object
hello: string
var machineTypes: seq[tuple[factory: proc(): Machine]]
proc registerMachine(factory: proc(): Machine) =
var mCreator = proc(): Machine =
result = factory()
machineTypes.add((factory: mCreator))
proc facproc(): Machine =
result = Machine(hello: "hello")
registerMachine(facproc)
proc createMachine =
for machine in machineTypes:
echo machine.factory().hello
createMachine()
# bug #15122
import tables
type
BENodeKind = enum
tkBytes,
tkList,
tkDict
BENode = object
case kind: BENodeKind
of tkBytes: strVal: string
of tkList: listVal: seq[BENode]
of tkDict: dictVal: Table[string, BENode]
var data = {
"examples": {
"values": BENode(
kind: tkList,
listVal: @[BENode(kind: tkBytes, strVal: "test")]
)
}.toTable()
}.toTable()
# For ARC listVal is empty for some reason
doAssert data["examples"]["values"].listVal[0].strVal == "test"
###############################################################################
# bug #15405
import parsexml
const test_xml_str = "<A><B>value</B></A>"
var stream = newStringStream(test_xml_str)
var xml: XmlParser
open(xml, stream, "test")
var xml2 = deepCopy(xml)
proc text_parser(xml: var XmlParser) =
var test_passed = false
while true:
xml.next()
case xml.kind
of xmlElementStart:
if xml.elementName == "B":
xml.next()
if xml.kind == xmlCharData and xml.charData == "value":
test_passed = true
of xmlEof: break
else: discard
xml.close()
doAssert(test_passed)
text_parser(xml)
text_parser(xml2)
# bug #15599
type
PixelBuffer = ref object
proc newPixelBuffer(): PixelBuffer =
new(result) do (buffer: PixelBuffer):
echo "ok"
discard newPixelBuffer()
# bug #17199
proc passSeq(data: seq[string]) =
# used the system.& proc initially
let wat = data & "hello"
proc test2 =
let name = @["hello", "world"]
passSeq(name)
doAssert name == @["hello", "world"]
static: test2() # was buggy
test2()
proc merge(x: sink seq[string], y: sink string): seq[string] =
newSeq(result, x.len + 1)
for i in 0..x.len-1:
result[i] = move(x[i])
result[x.len] = move(y)
proc passSeq2(data: seq[string]) =
# used the system.& proc initially
let wat = merge(data, "hello")
proc test3 =
let name = @["hello", "world"]
passSeq2(name)
doAssert name == @["hello", "world"]
static: test3() # was buggy
test3()
# bug #17712
proc t17712 =
var ppv = new int
discard @[ppv]
var el: ref int
el = [ppv][0]
echo el != nil
t17712()
# bug #18030
type
Foo = object
n: int
proc `=copy`(dst: var Foo, src: Foo) =
echo "copying"
dst.n = src.n
proc `=sink`(dst: var Foo, src: Foo) =
echo "sinking"
dst.n = src.n
var a: Foo
proc putValue[T](n: T)
proc useForward =
putValue(123)
proc putValue[T](n: T) =
var b = Foo(n:n)
a = b
echo b.n
useForward()
# bug #17319
type
BrokenObject = ref object
brokenType: seq[int]
proc use(obj: BrokenObject) =
discard
method testMethod(self: BrokenObject) {.base.} =
iterator testMethodIter() {.closure.} =
use(self)
var nameIterVar = testMethodIter
nameIterVar()
let mikasa = BrokenObject()
mikasa.testMethod()
# bug #19205
type
InputSectionBase* = object of RootObj
relocations*: seq[int] # traced reference. string has a similar SIGSEGV.
InputSection* = object of InputSectionBase
proc fooz(sec: var InputSectionBase) =
if sec of InputSection: # this line SIGSEGV.
echo 42
var sec = create(InputSection)
sec[] = InputSection(relocations: newSeq[int]())
fooz sec[]
block:
type
Data = ref object
id: int
proc main =
var x = Data(id: 99)
var y = x
x[] = Data(id: 778)[]
doAssert y.id == 778
doAssert x[].id == 778
main()
block: # bug #19857
type
ValueKind = enum VNull, VFloat, VObject # need 3 elements. Cannot remove VNull or VObject
Value = object
case kind: ValueKind
of VFloat: fnum: float
of VObject: tab: Table[int, int] # OrderedTable[T, U] also makes it fail.
# "simpler" types also work though
else: discard # VNull can be like this, but VObject must be filled
# required. Pure proc works
FormulaNode = proc(c: OrderedTable[string, int]): Value
proc toF(v: Value): float =
doAssert v.kind == VFloat
case v.kind
of VFloat: result = v.fnum
else: discard
proc foo() =
let fuck = initOrderedTable[string, int]()
proc cb(fuck: OrderedTable[string, int]): Value =
# works:
#result = Value(kind: VFloat, fnum: fuck["field_that_does_not_exist"].float)
# broken:
discard "actuall runs!"
let t = fuck["field_that_does_not_exist"]
echo "never runs, but we crash after! ", t
doAssertRaises(KeyError):
let fn = FormulaNode(cb)
let v = fn(fuck)
#echo v
let res = v.toF()
foo()
import std/options
# bug #21592
type Event* = object
code*: string
type App* = ref object of RootObj
id*: string
method process*(self: App): Option[Event] {.base.} =
raise Exception.new_exception("not impl")
# bug #21617
type Test2 = ref object of RootObj
method bug(t: Test2): seq[float] {.base.} = discard
block: # bug #22664
type
ElementKind = enum String, Number
Element = object
case kind: ElementKind
of String:
str: string
of Number:
num: float
Calc = ref object
stack: seq[Element]
var calc = new Calc
calc.stack.add Element(kind: Number, num: 200.0)
doAssert $calc.stack == "@[(kind: Number, num: 200.0)]"
let calc2 = calc
calc2.stack = calc.stack # This nulls out the object in the stack
doAssert $calc.stack == "@[(kind: Number, num: 200.0)]"
doAssert $calc2.stack == "@[(kind: Number, num: 200.0)]"
block: # bug #19250
type
Bar[T] = object
err: proc(): string
Foo[T] = object
run: proc(): Bar[T]
proc bar[T](err: proc(): string): Bar[T] =
assert not err.isNil
Bar[T](err: err)
proc foo(): Foo[char] =
result.run = proc(): Bar[char] =
# works
# result = Bar[char](err: proc(): string = "x")
# not work
result = bar[char](proc(): string = "x")
proc bug[T](fs: Foo[T]): Foo[T] =
result.run = proc(): Bar[T] =
let res = fs.run()
# works
# var errors = @[res.err]
# not work
var errors: seq[proc(): string]
errors.add res.err
return bar[T] do () -> string:
for err in errors:
result.add res.err()
doAssert bug(foo()).run().err() == "x"
block: # bug #22259
type
ProcWrapper = tuple
p: proc() {.closure.}
proc f(wrapper: ProcWrapper) =
let s = @[wrapper.p]
let a = [wrapper.p]
proc main =
# let wrapper: ProcWrapper = ProcWrapper(p: proc {.closure.} = echo 10)
let wrapper: ProcWrapper = (p: proc {.closure.} = echo 10)
f(wrapper)
main()
block:
block: # bug #22923
block:
let
a: int = 100
b: int32 = 200'i32
let
x = arrayWith(a, 8) # compiles
y = arrayWith(b, 8) # internal error
z = arrayWith(14, 8) # integer literal also results in a crash
doAssert x == [100, 100, 100, 100, 100, 100, 100, 100]
doAssert $y == "[200, 200, 200, 200, 200, 200, 200, 200]"
doAssert z == [14, 14, 14, 14, 14, 14, 14, 14]
block:
let a: string = "nim"
doAssert arrayWith(a, 3) == ["nim", "nim", "nim"]
let b: char = 'c'
doAssert arrayWith(b, 3) == ['c', 'c', 'c']
let c: uint = 300'u
doAssert $arrayWith(c, 3) == "[300, 300, 300]"
block: # bug #23505
type
K = object
C = object
value: ptr K
proc init(T: type C): C =
let tmp = new K
C(value: addr tmp[])
discard init(C)
block: # bug #23524
type MyType = object
a: int
proc `=destroy`(typ: MyType) = discard
var t1 = MyType(a: 100)
var t2 = t1 # Should be a copy?
proc main() =
t2 = t1
doAssert t1.a == 100
doAssert t2.a == 100
main()
block: # bug #23907
type
Thingy = object
value: int
ExecProc[C] = proc(value: sink C): int {.nimcall.}
proc `=copy`(a: var Thingy, b: Thingy) {.error.}
var thingyDestroyCount = 0
proc `=destroy`(thingy: Thingy) =
assert(thingyDestroyCount <= 0)
thingyDestroyCount += 1
proc store(value: sink Thingy): int =
result = value.value
let callback: ExecProc[Thingy] = store
doAssert callback(Thingy(value: 123)) == 123
import std/strutils
block: # bug #23974
func g(e: seq[string]): lent seq[string] = result = e
proc k(f: string): seq[string] = f.split("/")
proc n() =
const r = "/d/"
let t =
if true:
k(r).g()
else:
k("/" & r).g()
echo t
n()
block: # bug #23973
func g(e: seq[string]): lent seq[string] = result = e
proc k(f: string): seq[string] = f.split("/")
proc n() =
const r = "/test/empty" # or "/test/empty/1"
let a = k(r).g()
let t =
if true:
k(r).g()
else:
k("/" & r).g() # or raiseAssert ""
doAssert t == a
n()
block: # bug #24141
func reverse(s: var openArray[char]) =
s[0] = 'f'
func rev(s: var string) =
s.reverse
proc main =
var abc = "abc"
abc.rev
doAssert abc == "fbc"
main()