tarcmisc.nim 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. discard """
  2. output: '''
  3. Destructor for TestTestObj
  4. =destroy called
  5. 123xyzabc
  6. destroyed: false
  7. destroyed: false
  8. destroyed2: false
  9. destroyed2: false
  10. destroying variable: 2
  11. destroying variable: 1
  12. whiley ends :(
  13. 1
  14. (x: "0")
  15. (x: "1")
  16. (x: "2")
  17. (x: "3")
  18. (x: "4")
  19. (x: "5")
  20. (x: "6")
  21. (x: "7")
  22. (x: "8")
  23. (x: "9")
  24. (x: "10")
  25. 0
  26. new line before - @['a']
  27. new line after - @['a']
  28. finalizer
  29. aaaaa
  30. hello
  31. true
  32. copying
  33. 123
  34. 42
  35. @["", "d", ""]
  36. mutate: 1
  37. ok
  38. destroying variable: 20
  39. destroying variable: 10
  40. closed
  41. '''
  42. cmd: "nim c --mm:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file"
  43. """
  44. block: # bug #23627
  45. type
  46. TestObj = object of RootObj
  47. Test2 = object of RootObj
  48. foo: TestObj
  49. TestTestObj = object of RootObj
  50. shit: TestObj
  51. proc `=destroy`(x: TestTestObj) =
  52. echo "Destructor for TestTestObj"
  53. let test = Test2(foo: TestObj())
  54. proc testCaseT() =
  55. let tt1 {.used.} = TestTestObj(shit: TestObj())
  56. proc main() =
  57. testCaseT()
  58. main()
  59. # bug #9401
  60. type
  61. MyObj = object
  62. len: int
  63. data: ptr UncheckedArray[float]
  64. proc `=destroy`*(m: MyObj) =
  65. echo "=destroy called"
  66. if m.data != nil:
  67. deallocShared(m.data)
  68. type
  69. MyObjDistinct = distinct MyObj
  70. proc `=copy`*(m: var MyObj, m2: MyObj) =
  71. if m.data == m2.data: return
  72. if m.data != nil:
  73. `=destroy`(m)
  74. m.len = m2.len
  75. if m.len > 0:
  76. m.data = cast[ptr UncheckedArray[float]](allocShared(sizeof(float) * m.len))
  77. copyMem(m.data, m2.data, sizeof(float) * m.len)
  78. proc `=sink`*(m: var MyObj, m2: MyObj) =
  79. if m.data != m2.data:
  80. if m.data != nil:
  81. `=destroy`(m)
  82. m.len = m2.len
  83. m.data = m2.data
  84. proc newMyObj(len: int): MyObj =
  85. result = MyObj()
  86. result.len = len
  87. result.data = cast[ptr UncheckedArray[float]](allocShared(sizeof(float) * len))
  88. proc newMyObjDistinct(len: int): MyObjDistinct =
  89. MyObjDistinct(newMyObj(len))
  90. proc fooDistinct =
  91. doAssert newMyObjDistinct(2).MyObj.len == 2
  92. fooDistinct()
  93. proc takeSink(x: sink string): bool = true
  94. proc b(x: sink string): string =
  95. if takeSink(x):
  96. return x & "abc"
  97. else:
  98. result = ""
  99. proc bbb(inp: string) =
  100. let y = inp & "xyz"
  101. echo b(y)
  102. bbb("123")
  103. # bug #13691
  104. type Variable = ref object
  105. value: int
  106. proc `=destroy`(self: typeof(Variable()[])) =
  107. echo "destroying variable: ",self.value
  108. proc newVariable(value: int): Variable =
  109. result = Variable()
  110. result.value = value
  111. #echo "creating variable: ",result.value
  112. proc test(count: int) =
  113. var v {.global.} = newVariable(10)
  114. var count = count - 1
  115. if count == 0: return
  116. test(count)
  117. echo "destroyed: ", v.isNil
  118. test(3)
  119. proc test2(count: int) =
  120. block: #XXX: Fails with block currently
  121. var v {.global.} = newVariable(20)
  122. var count = count - 1
  123. if count == 0: return
  124. test2(count)
  125. echo "destroyed2: ", v.isNil
  126. test2(3)
  127. proc whiley =
  128. var a = newVariable(1)
  129. while true:
  130. var b = newVariable(2)
  131. if true: raise newException(CatchableError, "test")
  132. try:
  133. whiley()
  134. except CatchableError:
  135. echo "whiley ends :("
  136. #------------------------------------------------------------------------------
  137. # issue #13810
  138. import streams
  139. type
  140. A = ref AObj
  141. AObj = object of RootObj
  142. io: Stream
  143. B = ref object of A
  144. x: int
  145. proc `=destroy`(x: AObj) =
  146. close(x.io)
  147. echo "closed"
  148. var x = B(io: newStringStream("thestream"))
  149. #------------------------------------------------------------------------------
  150. # issue #14003
  151. proc cryptCTR*(nonce: var openArray[char]) =
  152. nonce[1] = 'A'
  153. proc main() =
  154. var nonce1 = "0123456701234567"
  155. cryptCTR(nonce1)
  156. doAssert(nonce1 == "0A23456701234567")
  157. var nonce2 = "01234567"
  158. cryptCTR(nonce2.toOpenArray(0, nonce2.len-1))
  159. doAssert(nonce2 == "0A234567")
  160. main()
  161. # bug #14079
  162. import std/algorithm
  163. let
  164. n = @["c", "b"]
  165. q = @[("c", "2"), ("b", "1")]
  166. doAssert n.sortedByIt(it) == @["b", "c"], "fine"
  167. doAssert q.sortedByIt(it[0]) == @[("b", "1"), ("c", "2")], "fails under arc"
  168. #------------------------------------------------------------------------------
  169. # issue #14236
  170. type
  171. MyType = object
  172. a: seq[int]
  173. proc re(x: static[string]): static MyType =
  174. MyType()
  175. proc match(inp: string, rg: static MyType) =
  176. doAssert rg.a.len == 0
  177. match("ac", re"a(b|c)")
  178. #------------------------------------------------------------------------------
  179. # issue #14243
  180. type
  181. Game* = ref object
  182. proc free*(game: Game) =
  183. let a = 5
  184. proc newGame*(): Game =
  185. new(result, free)
  186. var game*: Game
  187. #------------------------------------------------------------------------------
  188. # issue #14333
  189. type
  190. SimpleLoop = object
  191. Lsg = object
  192. loops: seq[ref SimpleLoop]
  193. root: ref SimpleLoop
  194. var lsg: Lsg
  195. lsg.loops.add lsg.root
  196. echo lsg.loops.len
  197. # bug #14495
  198. type
  199. Gah = ref object
  200. x: string
  201. proc bug14495 =
  202. var owners: seq[Gah] = @[]
  203. for i in 0..10:
  204. owners.add Gah(x: $i)
  205. var x: seq[Gah] = @[]
  206. for i in 0..10:
  207. x.add owners[i]
  208. for i in 0..100:
  209. setLen(x, 0)
  210. setLen(x, 10)
  211. for i in 0..x.len-1:
  212. if x[i] != nil:
  213. echo x[i][]
  214. for o in owners:
  215. echo o[]
  216. bug14495()
  217. # bug #14396
  218. type
  219. Spinny = ref object
  220. t: ref int
  221. text: string
  222. proc newSpinny*(): Spinny =
  223. Spinny(t: new(int), text: "hello")
  224. proc spinnyLoop(x: ref int, spinny: sink Spinny) =
  225. echo x[]
  226. proc start*(spinny: sink Spinny) =
  227. spinnyLoop(spinny.t, spinny)
  228. var spinner1 = newSpinny()
  229. spinner1.start()
  230. # bug #14345
  231. type
  232. SimpleLoopB = ref object
  233. children: seq[SimpleLoopB]
  234. parent: SimpleLoopB
  235. proc addChildLoop(self: SimpleLoopB, loop: SimpleLoopB) =
  236. self.children.add loop
  237. proc setParent(self: SimpleLoopB, parent: SimpleLoopB) =
  238. self.parent = parent
  239. self.parent.addChildLoop(self)
  240. var l = SimpleLoopB()
  241. l.setParent(l)
  242. # bug #14968
  243. import times
  244. let currentTime = now().utc
  245. # bug #14994
  246. import sequtils
  247. var newLine = @['a']
  248. let indent = newSeq[char]()
  249. echo "new line before - ", newline
  250. newline.insert(indent, 0)
  251. echo "new line after - ", newline
  252. # bug #15044
  253. type
  254. Test = ref object
  255. proc test: Test =
  256. # broken
  257. new(result, proc(x: Test) =
  258. echo "finalizer"
  259. )
  260. proc tdirectFinalizer =
  261. discard test()
  262. tdirectFinalizer()
  263. # bug #14480
  264. proc hello(): int =
  265. result = 42
  266. var leaves {.global.} = hello()
  267. doAssert leaves == 42
  268. # bug #15052
  269. proc mutstrings =
  270. var data = "hello"
  271. for c in data.mitems():
  272. c = 'a'
  273. echo data
  274. mutstrings()
  275. # bug #15038
  276. type
  277. Machine = ref object
  278. hello: string
  279. var machineTypes: seq[tuple[factory: proc(): Machine]]
  280. proc registerMachine(factory: proc(): Machine) =
  281. var mCreator = proc(): Machine =
  282. result = factory()
  283. machineTypes.add((factory: mCreator))
  284. proc facproc(): Machine =
  285. result = Machine(hello: "hello")
  286. registerMachine(facproc)
  287. proc createMachine =
  288. for machine in machineTypes:
  289. echo machine.factory().hello
  290. createMachine()
  291. # bug #15122
  292. import tables
  293. type
  294. BENodeKind = enum
  295. tkBytes,
  296. tkList,
  297. tkDict
  298. BENode = object
  299. case kind: BENodeKind
  300. of tkBytes: strVal: string
  301. of tkList: listVal: seq[BENode]
  302. of tkDict: dictVal: Table[string, BENode]
  303. var data = {
  304. "examples": {
  305. "values": BENode(
  306. kind: tkList,
  307. listVal: @[BENode(kind: tkBytes, strVal: "test")]
  308. )
  309. }.toTable()
  310. }.toTable()
  311. # For ARC listVal is empty for some reason
  312. doAssert data["examples"]["values"].listVal[0].strVal == "test"
  313. ###############################################################################
  314. # bug #15405
  315. import parsexml
  316. const test_xml_str = "<A><B>value</B></A>"
  317. var stream = newStringStream(test_xml_str)
  318. var xml: XmlParser
  319. open(xml, stream, "test")
  320. var xml2 = deepCopy(xml)
  321. proc text_parser(xml: var XmlParser) =
  322. var test_passed = false
  323. while true:
  324. xml.next()
  325. case xml.kind
  326. of xmlElementStart:
  327. if xml.elementName == "B":
  328. xml.next()
  329. if xml.kind == xmlCharData and xml.charData == "value":
  330. test_passed = true
  331. of xmlEof: break
  332. else: discard
  333. xml.close()
  334. doAssert(test_passed)
  335. text_parser(xml)
  336. text_parser(xml2)
  337. # bug #15599
  338. type
  339. PixelBuffer = ref object
  340. proc newPixelBuffer(): PixelBuffer =
  341. new(result) do (buffer: PixelBuffer):
  342. echo "ok"
  343. discard newPixelBuffer()
  344. # bug #17199
  345. proc passSeq(data: seq[string]) =
  346. # used the system.& proc initially
  347. let wat = data & "hello"
  348. proc test2 =
  349. let name = @["hello", "world"]
  350. passSeq(name)
  351. doAssert name == @["hello", "world"]
  352. static: test2() # was buggy
  353. test2()
  354. proc merge(x: sink seq[string], y: sink string): seq[string] =
  355. newSeq(result, x.len + 1)
  356. for i in 0..x.len-1:
  357. result[i] = move(x[i])
  358. result[x.len] = move(y)
  359. proc passSeq2(data: seq[string]) =
  360. # used the system.& proc initially
  361. let wat = merge(data, "hello")
  362. proc test3 =
  363. let name = @["hello", "world"]
  364. passSeq2(name)
  365. doAssert name == @["hello", "world"]
  366. static: test3() # was buggy
  367. test3()
  368. # bug #17712
  369. proc t17712 =
  370. var ppv = new int
  371. discard @[ppv]
  372. var el: ref int
  373. el = [ppv][0]
  374. echo el != nil
  375. t17712()
  376. # bug #18030
  377. type
  378. Foo = object
  379. n: int
  380. proc `=copy`(dst: var Foo, src: Foo) =
  381. echo "copying"
  382. dst.n = src.n
  383. proc `=sink`(dst: var Foo, src: Foo) =
  384. echo "sinking"
  385. dst.n = src.n
  386. var a: Foo
  387. proc putValue[T](n: T)
  388. proc useForward =
  389. putValue(123)
  390. proc putValue[T](n: T) =
  391. var b = Foo(n:n)
  392. a = b
  393. echo b.n
  394. useForward()
  395. # bug #17319
  396. type
  397. BrokenObject = ref object
  398. brokenType: seq[int]
  399. proc use(obj: BrokenObject) =
  400. discard
  401. method testMethod(self: BrokenObject) {.base.} =
  402. iterator testMethodIter() {.closure.} =
  403. use(self)
  404. var nameIterVar = testMethodIter
  405. nameIterVar()
  406. let mikasa = BrokenObject()
  407. mikasa.testMethod()
  408. # bug #19205
  409. type
  410. InputSectionBase* = object of RootObj
  411. relocations*: seq[int] # traced reference. string has a similar SIGSEGV.
  412. InputSection* = object of InputSectionBase
  413. proc fooz(sec: var InputSectionBase) =
  414. if sec of InputSection: # this line SIGSEGV.
  415. echo 42
  416. var sec = create(InputSection)
  417. sec[] = InputSection(relocations: newSeq[int]())
  418. fooz sec[]
  419. block:
  420. type
  421. Data = ref object
  422. id: int
  423. proc main =
  424. var x = Data(id: 99)
  425. var y = x
  426. x[] = Data(id: 778)[]
  427. doAssert y.id == 778
  428. doAssert x[].id == 778
  429. main()
  430. block: # bug #19857
  431. type
  432. ValueKind = enum VNull, VFloat, VObject # need 3 elements. Cannot remove VNull or VObject
  433. Value = object
  434. case kind: ValueKind
  435. of VFloat: fnum: float
  436. of VObject: tab: Table[int, int] # OrderedTable[T, U] also makes it fail.
  437. # "simpler" types also work though
  438. else: discard # VNull can be like this, but VObject must be filled
  439. # required. Pure proc works
  440. FormulaNode = proc(c: OrderedTable[string, int]): Value
  441. proc toF(v: Value): float =
  442. doAssert v.kind == VFloat
  443. case v.kind
  444. of VFloat: result = v.fnum
  445. else: result = 0.0
  446. proc foo() =
  447. let fuck = initOrderedTable[string, int]()
  448. proc cb(fuck: OrderedTable[string, int]): Value =
  449. # works:
  450. #result = Value(kind: VFloat, fnum: fuck["field_that_does_not_exist"].float)
  451. # broken:
  452. result = Value()
  453. discard "actuall runs!"
  454. let t = fuck["field_that_does_not_exist"]
  455. echo "never runs, but we crash after! ", t
  456. doAssertRaises(KeyError):
  457. let fn = FormulaNode(cb)
  458. let v = fn(fuck)
  459. #echo v
  460. let res = v.toF()
  461. foo()
  462. import std/options
  463. # bug #21592
  464. type Event* = object
  465. code*: string
  466. type App* = ref object of RootObj
  467. id*: string
  468. method process*(self: App): Option[Event] {.base.} =
  469. raise Exception.new_exception("not impl")
  470. # bug #21617
  471. type Test2 = ref object of RootObj
  472. method bug(t: Test2): seq[float] {.base.} = result = @[]
  473. block: # bug #22664
  474. type
  475. ElementKind = enum String, Number
  476. Element = object
  477. case kind: ElementKind
  478. of String:
  479. str: string
  480. of Number:
  481. num: float
  482. Calc = ref object
  483. stack: seq[Element]
  484. var calc = new Calc
  485. calc.stack.add Element(kind: Number, num: 200.0)
  486. doAssert $calc.stack == "@[(kind: Number, num: 200.0)]"
  487. let calc2 = calc
  488. calc2.stack = calc.stack # This nulls out the object in the stack
  489. doAssert $calc.stack == "@[(kind: Number, num: 200.0)]"
  490. doAssert $calc2.stack == "@[(kind: Number, num: 200.0)]"
  491. block: # bug #19250
  492. type
  493. Bar[T] = object
  494. err: proc(): string
  495. Foo[T] = object
  496. run: proc(): Bar[T]
  497. proc bar[T](err: proc(): string): Bar[T] =
  498. assert not err.isNil
  499. Bar[T](err: err)
  500. proc foo(): Foo[char] =
  501. result = Foo[char]()
  502. result.run = proc(): Bar[char] =
  503. # works
  504. # result = Bar[char](err: proc(): string = "x")
  505. # not work
  506. result = bar[char](proc(): string = "x")
  507. proc bug[T](fs: Foo[T]): Foo[T] =
  508. result = Foo[T]()
  509. result.run = proc(): Bar[T] =
  510. let res = fs.run()
  511. # works
  512. # var errors = @[res.err]
  513. # not work
  514. var errors: seq[proc(): string] = @[]
  515. errors.add res.err
  516. return bar[T] do () -> string:
  517. result = ""
  518. for err in errors:
  519. result.add res.err()
  520. doAssert bug(foo()).run().err() == "x"
  521. block: # bug #22259
  522. type
  523. ProcWrapper = tuple
  524. p: proc() {.closure.}
  525. proc f(wrapper: ProcWrapper) =
  526. let s = @[wrapper.p]
  527. let a = [wrapper.p]
  528. proc main =
  529. # let wrapper: ProcWrapper = ProcWrapper(p: proc {.closure.} = echo 10)
  530. let wrapper: ProcWrapper = (p: proc {.closure.} = echo 10)
  531. f(wrapper)
  532. main()
  533. block:
  534. block: # bug #22923
  535. block:
  536. let
  537. a: int = 100
  538. b: int32 = 200'i32
  539. let
  540. x = arrayWith(a, 8) # compiles
  541. y = arrayWith(b, 8) # internal error
  542. z = arrayWith(14, 8) # integer literal also results in a crash
  543. doAssert x == [100, 100, 100, 100, 100, 100, 100, 100]
  544. doAssert $y == "[200, 200, 200, 200, 200, 200, 200, 200]"
  545. doAssert z == [14, 14, 14, 14, 14, 14, 14, 14]
  546. block:
  547. let a: string = "nim"
  548. doAssert arrayWith(a, 3) == ["nim", "nim", "nim"]
  549. let b: char = 'c'
  550. doAssert arrayWith(b, 3) == ['c', 'c', 'c']
  551. let c: uint = 300'u
  552. doAssert $arrayWith(c, 3) == "[300, 300, 300]"
  553. block: # bug #23505
  554. type
  555. K = object
  556. C = object
  557. value: ptr K
  558. proc init(T: type C): C =
  559. let tmp = new K
  560. C(value: addr tmp[])
  561. discard init(C)
  562. block: # bug #23524
  563. type MyType = object
  564. a: int
  565. proc `=destroy`(typ: MyType) = discard
  566. var t1 = MyType(a: 100)
  567. var t2 = t1 # Should be a copy?
  568. proc main() =
  569. t2 = t1
  570. doAssert t1.a == 100
  571. doAssert t2.a == 100
  572. main()
  573. block: # bug #23907
  574. type
  575. Thingy = object
  576. value: int
  577. ExecProc[C] = proc(value: sink C): int {.nimcall.}
  578. proc `=copy`(a: var Thingy, b: Thingy) {.error.}
  579. var thingyDestroyCount = 0
  580. proc `=destroy`(thingy: Thingy) =
  581. assert(thingyDestroyCount <= 0)
  582. thingyDestroyCount += 1
  583. proc store(value: sink Thingy): int =
  584. result = value.value
  585. let callback: ExecProc[Thingy] = store
  586. doAssert callback(Thingy(value: 123)) == 123
  587. import std/strutils
  588. block: # bug #23974
  589. func g(e: seq[string]): lent seq[string] = result = e
  590. proc k(f: string): seq[string] = f.split("/")
  591. proc n() =
  592. const r = "/d/"
  593. let t =
  594. if true:
  595. k(r).g()
  596. else:
  597. k("/" & r).g()
  598. echo t
  599. n()
  600. block: # bug #23973
  601. func g(e: seq[string]): lent seq[string] = result = e
  602. proc k(f: string): seq[string] = f.split("/")
  603. proc n() =
  604. const r = "/test/empty" # or "/test/empty/1"
  605. let a = k(r).g()
  606. let t =
  607. if true:
  608. k(r).g()
  609. else:
  610. k("/" & r).g() # or raiseAssert ""
  611. doAssert t == a
  612. n()
  613. block: # bug #24141
  614. func reverse(s: var openArray[char]) =
  615. s[0] = 'f'
  616. func rev(s: var string) =
  617. s.reverse
  618. proc main =
  619. var abc = "abc"
  620. abc.rev
  621. doAssert abc == "fbc"
  622. main()
  623. block:
  624. type
  625. FooObj = object
  626. data: int
  627. Foo = ref FooObj
  628. proc delete(self: FooObj) =
  629. discard
  630. var s = Foo()
  631. new(s, delete)
  632. block:
  633. type
  634. FooObj = object
  635. data: int
  636. i1, i2, i3, i4: float
  637. Foo = ref FooObj
  638. proc delete(self: FooObj) =
  639. discard
  640. var s = Foo()
  641. new(s, delete)
  642. proc test_18070() = # bug #18070
  643. try:
  644. try:
  645. raise newException(CatchableError, "something")
  646. except:
  647. raise newException(CatchableError, "something else")
  648. except:
  649. doAssert getCurrentExceptionMsg() == "something else"
  650. let msg = getCurrentExceptionMsg()
  651. doAssert msg == "", "expected empty string but got: " & $msg
  652. test_18070()
  653. type AnObject = tuple
  654. a: string
  655. b: int
  656. c: int
  657. proc mutate(a: sink AnObject) =
  658. `=wasMoved`(a)
  659. echo "mutate: 1"
  660. # echo "Value is: ", obj.value
  661. proc bar =
  662. mutate(("1.2", 0, 0))
  663. bar()