tarcmisc.nim 15 KB

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