tcaseobj.nim 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. discard """
  2. valgrind: true
  3. cmd: "nim c --gc:arc -d:useMalloc $file"
  4. output: '''myobj destroyed
  5. myobj destroyed
  6. myobj destroyed
  7. A
  8. B
  9. begin
  10. end
  11. prevented
  12. (ok: true, value: "ok")
  13. @[(kind: P, pChildren: @[])]
  14. myobj destroyed
  15. '''
  16. """
  17. # bug #13102
  18. type
  19. D = ref object
  20. R = object
  21. case o: bool
  22. of false:
  23. discard
  24. of true:
  25. field: D
  26. iterator things(): R =
  27. when true:
  28. var
  29. unit = D()
  30. while true:
  31. yield R(o: true, field: unit)
  32. else:
  33. while true:
  34. var
  35. unit = D()
  36. yield R(o: true, field: unit)
  37. proc main =
  38. var i = 0
  39. for item in things():
  40. discard item.field
  41. inc i
  42. if i == 2: break
  43. main()
  44. # bug #13149
  45. type
  46. TMyObj = object
  47. p: pointer
  48. len: int
  49. proc `=destroy`(o: var TMyObj) =
  50. if o.p != nil:
  51. dealloc o.p
  52. o.p = nil
  53. echo "myobj destroyed"
  54. proc `=`(dst: var TMyObj, src: TMyObj) =
  55. `=destroy`(dst)
  56. dst.p = alloc(src.len)
  57. dst.len = src.len
  58. proc `=sink`(dst: var TMyObj, src: TMyObj) =
  59. `=destroy`(dst)
  60. dst.p = src.p
  61. dst.len = src.len
  62. type
  63. TObjKind = enum Z, A, B
  64. TCaseObj = object
  65. case kind: TObjKind
  66. of Z: discard
  67. of A:
  68. x1: int # this int plays important role
  69. x2: TMyObj
  70. of B:
  71. y: TMyObj
  72. proc testSinks: TCaseObj =
  73. result = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5)))
  74. result = TCaseObj(kind: B, y: TMyObj(len: 3, p: alloc(3)))
  75. proc use(x: TCaseObj) = discard
  76. proc testCopies(i: int) =
  77. var a: array[2, TCaseObj]
  78. a[i] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5)))
  79. a[i+1] = a[i] # copy, cannot move
  80. use(a[i])
  81. let x1 = testSinks()
  82. testCopies(0)
  83. # bug #12957
  84. type
  85. PegKind* = enum
  86. pkCharChoice,
  87. pkSequence
  88. Peg* = object ## type that represents a PEG
  89. case kind: PegKind
  90. of pkCharChoice: charChoice: ref set[char]
  91. else: discard
  92. sons: seq[Peg]
  93. proc charSet*(s: set[char]): Peg =
  94. ## constructs a PEG from a character set `s`
  95. result = Peg(kind: pkCharChoice)
  96. new(result.charChoice)
  97. result.charChoice[] = s
  98. proc len(a: Peg): int {.inline.} = return a.sons.len
  99. proc myadd(d: var Peg, s: Peg) {.inline.} = add(d.sons, s)
  100. proc sequence*(a: openArray[Peg]): Peg =
  101. result = Peg(kind: pkSequence, sons: @[])
  102. when false:
  103. #works too:
  104. result.myadd(a[0])
  105. result.myadd(a[1])
  106. for x in items(a):
  107. # works:
  108. #result.sons.add(x)
  109. # fails:
  110. result.myadd x
  111. if result.len == 1:
  112. result = result.sons[0] # this must not move!
  113. when true:
  114. # bug #12957
  115. proc p =
  116. echo "A"
  117. let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'}),
  118. charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})])
  119. echo "B"
  120. p()
  121. proc testSubObjAssignment =
  122. echo "begin"
  123. # There must be extactly one element in the array constructor!
  124. let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'})])
  125. echo "end"
  126. testSubObjAssignment()
  127. #------------------------------------------------
  128. type
  129. MyObject = object
  130. x1: string
  131. case kind1: bool
  132. of false: y1: string
  133. of true:
  134. y2: seq[string]
  135. case kind2: bool
  136. of true: z1: string
  137. of false:
  138. z2: seq[string]
  139. flag: bool
  140. x2: string
  141. proc test_myobject =
  142. var x: MyObject
  143. x.x1 = "x1"
  144. x.x2 = "x2"
  145. x.y1 = "ljhkjhkjh"
  146. x.kind1 = true
  147. x.y2 = @["1", "2"]
  148. x.kind2 = true
  149. x.z1 = "yes"
  150. x.kind2 = false
  151. x.z2 = @["1", "2"]
  152. x.kind2 = true
  153. x.z1 = "yes"
  154. x.kind2 = true # should be no effect
  155. doAssert(x.z1 == "yes")
  156. x.kind2 = false
  157. x.kind1 = x.kind2 # support self assignment with effect
  158. try:
  159. x.kind1 = x.flag # flag is not accesible
  160. except FieldDefect:
  161. echo "prevented"
  162. doAssert(x.x1 == "x1")
  163. doAssert(x.x2 == "x2")
  164. test_myobject()
  165. #------------------------------------------------
  166. # bug #14244
  167. type
  168. RocksDBResult*[T] = object
  169. case ok*: bool
  170. of true:
  171. value*: T
  172. else:
  173. error*: string
  174. proc init(): RocksDBResult[string] =
  175. result.ok = true
  176. result.value = "ok"
  177. echo init()
  178. #------------------------------------------------
  179. # bug #14312
  180. type MyObj = object
  181. case kind: bool
  182. of false: x0: int # would work with a type like seq[int]; value would be reset
  183. of true: x1: string
  184. var a = MyObj(kind: false, x0: 1234)
  185. a.kind = true
  186. doAssert(a.x1 == "")
  187. block:
  188. # bug #15532
  189. type Kind = enum
  190. k0, k1
  191. type Foo = object
  192. y: int
  193. case kind: Kind
  194. of k0: x0: int
  195. of k1: x1: int
  196. const j0 = Foo(y: 1, kind: k0, x0: 2)
  197. const j1 = Foo(y: 1, kind: k1, x1: 2)
  198. doAssert j0.y == 1
  199. doAssert j0.kind == k0
  200. doAssert j1.kind == k1
  201. doAssert j1.x1 == 2
  202. doAssert j0.x0 == 2
  203. # ------------------------------------
  204. # bug #20305
  205. type
  206. ContentNodeKind = enum
  207. P, Br, Text
  208. ContentNode = object
  209. case kind: ContentNodeKind
  210. of P: pChildren: seq[ContentNode]
  211. of Br: discard
  212. of Text: textStr: string
  213. proc bug20305 =
  214. var x = ContentNode(kind: P, pChildren: @[
  215. ContentNode(kind: P, pChildren: @[ContentNode(kind: Text, textStr: "brrr")])
  216. ])
  217. x.pChildren.add ContentNode(kind: Br)
  218. x.pChildren.del(0)
  219. {.cast(uncheckedAssign).}:
  220. x.pChildren[0].kind = P
  221. echo x.pChildren
  222. bug20305()