tcaseobj.nim 4.5 KB

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