tcaseobj.nim 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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 `=copy`(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. {.cast(uncheckedAssign).}:
  147. x.kind1 = true
  148. x.y2 = @["1", "2"]
  149. {.cast(uncheckedAssign).}:
  150. x.kind2 = true
  151. x.z1 = "yes"
  152. {.cast(uncheckedAssign).}:
  153. x.kind2 = false
  154. x.z2 = @["1", "2"]
  155. {.cast(uncheckedAssign).}:
  156. x.kind2 = true
  157. x.z1 = "yes"
  158. x.kind2 = true # should be no effect
  159. doAssert(x.z1 == "yes")
  160. {.cast(uncheckedAssign).}:
  161. x.kind2 = false
  162. {.cast(uncheckedAssign).}:
  163. x.kind1 = x.kind2 # support self assignment with effect
  164. try:
  165. x.kind1 = x.flag # flag is not accesible
  166. except FieldDefect:
  167. echo "prevented"
  168. doAssert(x.x1 == "x1")
  169. doAssert(x.x2 == "x2")
  170. test_myobject()
  171. #------------------------------------------------
  172. # bug #14244
  173. type
  174. RocksDBResult*[T] = object
  175. case ok*: bool
  176. of true:
  177. value*: T
  178. else:
  179. error*: string
  180. proc init(): RocksDBResult[string] =
  181. {.cast(uncheckedAssign).}:
  182. result.ok = true
  183. result.value = "ok"
  184. echo init()
  185. #------------------------------------------------
  186. # bug #14312
  187. type MyObj = object
  188. case kind: bool
  189. of false: x0: int # would work with a type like seq[int]; value would be reset
  190. of true: x1: string
  191. var a = MyObj(kind: false, x0: 1234)
  192. {.cast(uncheckedAssign).}:
  193. a.kind = true
  194. doAssert(a.x1 == "")
  195. block:
  196. # bug #15532
  197. type Kind = enum
  198. k0, k1
  199. type Foo = object
  200. y: int
  201. case kind: Kind
  202. of k0: x0: int
  203. of k1: x1: int
  204. const j0 = Foo(y: 1, kind: k0, x0: 2)
  205. const j1 = Foo(y: 1, kind: k1, x1: 2)
  206. doAssert j0.y == 1
  207. doAssert j0.kind == k0
  208. doAssert j1.kind == k1
  209. doAssert j1.x1 == 2
  210. doAssert j0.x0 == 2
  211. # ------------------------------------
  212. # bug #20305
  213. type
  214. ContentNodeKind = enum
  215. P, Br, Text
  216. ContentNode = object
  217. case kind: ContentNodeKind
  218. of P: pChildren: seq[ContentNode]
  219. of Br: discard
  220. of Text: textStr: string
  221. proc bug20305 =
  222. var x = ContentNode(kind: P, pChildren: @[
  223. ContentNode(kind: P, pChildren: @[ContentNode(kind: Text, textStr: "brrr")])
  224. ])
  225. x.pChildren.add ContentNode(kind: Br)
  226. x.pChildren.del(0)
  227. {.cast(uncheckedAssign).}:
  228. x.pChildren[0].kind = P
  229. echo x.pChildren
  230. bug20305()
  231. # bug #21023
  232. block:
  233. block:
  234. type
  235. MGErrorKind = enum
  236. mgeUnexpected, mgeNotFound
  237. type Foo = object
  238. kind: MGErrorKind
  239. ex: Exception
  240. type Boo = object
  241. a: seq[int]
  242. type
  243. Result2 = object
  244. case o: bool
  245. of false:
  246. e: Foo
  247. of true:
  248. v: Boo
  249. proc startSessionSync(): Result2 =
  250. return Result2(o: true)
  251. proc mainSync =
  252. let ff = startSessionSync()
  253. doAssert ff.o == true
  254. mainSync()
  255. block:
  256. type
  257. MGErrorKind = enum
  258. mgeUnexpected, mgeNotFound
  259. type Foo = object
  260. kind: MGErrorKind
  261. ex: Exception
  262. type Boo = object
  263. a: seq[int]
  264. type
  265. Result2 = object
  266. case o: bool
  267. of false:
  268. e: Foo
  269. of true:
  270. v: Boo
  271. s: int
  272. proc startSessionSync(): Result2 =
  273. return Result2(o: true, s: 12)
  274. proc mainSync =
  275. let ff = startSessionSync()
  276. doAssert ff.s == 12
  277. mainSync()
  278. import std/sequtils
  279. # bug #23690
  280. type
  281. SomeObj* = object of RootObj
  282. Item* = object
  283. case kind*: 0..1
  284. of 0:
  285. a*: int
  286. b*: SomeObj
  287. of 1:
  288. c*: string
  289. ItemExt* = object
  290. a*: Item
  291. b*: string
  292. proc do1(x: int): seq[(string, Item)] =
  293. result = @[("zero", Item(kind: 1, c: "first"))]
  294. proc do2(x: int, e: ItemExt): seq[(string, ItemExt)] =
  295. do1(x).map(proc(v: (string, Item)): auto = (v[0], ItemExt(a: v[1], b: e.b)))
  296. doAssert $do2(0, ItemExt(a: Item(kind: 1, c: "second"), b: "third")) == """@[("zero", (a: (kind: 1, c: "first"), b: "third"))]"""