summary refs log tree commit diff stats
path: root/tests/arc/tcaseobj.nim
blob: 44daa5979ab601337a9d5d6b92905413f19cc2e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
discard """
  valgrind: true
  cmd: "nim c --gc:arc -d:useMalloc $file"
  output: '''myobj destroyed
myobj destroyed
myobj destroyed
A
B
begin
end
myobj destroyed
'''
"""

# bug #13102

type
  D = ref object
  R = object
    case o: bool
    of false:
      discard
    of true:
      field: D

iterator things(): R =
  when true:
    var
      unit = D()
    while true:
      yield R(o: true, field: unit)
  else:
    while true:
      var
        unit = D()
      yield R(o: true, field: unit)

proc main =
  var i = 0
  for item in things():
    discard item.field
    inc i
    if i == 2: break

main()

# bug #13149

type
  TMyObj = object
    p: pointer
    len: int

proc `=destroy`(o: var TMyObj) =
  if o.p != nil:
    dealloc o.p
    o.p = nil
    echo "myobj destroyed"

proc `=`(dst: var TMyObj, src: TMyObj) =
  `=destroy`(dst)
  dst.p = alloc(src.len)
  dst.len = src.len

proc `=sink`(dst: var TMyObj, src: TMyObj) =
  `=destroy`(dst)
  dst.p = src.p
  dst.len = src.len

type
  TObjKind = enum Z, A, B
  TCaseObj = object
    case kind: TObjKind
    of Z: discard
    of A:
      x1: int # this int plays important role
      x2: TMyObj
    of B:
      y: TMyObj

proc testSinks: TCaseObj =
  result = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5)))
  result = TCaseObj(kind: B, y: TMyObj(len: 3, p: alloc(3)))

proc use(x: TCaseObj) = discard

proc testCopies(i: int) =
  var a: array[2, TCaseObj]
  a[i] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5)))
  a[i+1] = a[i] # copy, cannot move
  use(a[i])

let x1 = testSinks()
testCopies(0)

# bug #12957

type
  PegKind* = enum
    pkCharChoice,
    pkSequence
  Peg* = object ## type that represents a PEG
    case kind: PegKind
    of pkCharChoice: charChoice: ref set[char]
    else: discard
    sons: seq[Peg]

proc charSet*(s: set[char]): Peg =
  ## constructs a PEG from a character set `s`
  result = Peg(kind: pkCharChoice)
  new(result.charChoice)
  result.charChoice[] = s

proc len(a: Peg): int {.inline.} = return a.sons.len
proc myadd(d: var Peg, s: Peg) {.inline.} = add(d.sons, s)

proc sequence*(a: openArray[Peg]): Peg =
  result = Peg(kind: pkSequence, sons: @[])
  when false:
    #works too:
    result.myadd(a[0])
    result.myadd(a[1])
  for x in items(a):
    # works:
    #result.sons.add(x)
    # fails:
    result.myadd x
  if result.len == 1:
    result = result.sons[0] # this must not move!

when true:
  # bug #12957

  proc p =
    echo "A"
    let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'}),
              charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})])
    echo "B"
  p()

  proc testSubObjAssignment =
    echo "begin"
    # There must be extactly one element in the array constructor!
    let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'})])
    echo "end"
  testSubObjAssignment()