summary refs log tree commit diff stats
path: root/tests/destructor/tdestructor3.nim
blob: 3f5eb2cc15862c774e463908ecf2e466b4516f3e (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
discard """
  output: '''
assign
destroy
destroy
5
123
destroy Foo: 123
destroy Foo: 5
(x1: (val: ...))
destroy
---------------
app begin
(val: ...)
destroy
app end
'''
joinable: false
"""

# bug #2821

type T = object

proc `=`(lhs: var T, rhs: T) =
  echo "assign"

proc `=destroy`(v: var T) =
  echo "destroy"

proc use(x: T) = discard

proc usedToBeBlock =
  var v1 = T()
  var v2: T = v1
  discard addr(v2) # prevent cursorfication
  use v1

usedToBeBlock()

# bug #1632

type
  Foo = object of RootObj
    x: int

proc `=destroy`(a: var Foo) =
  echo "destroy Foo: " & $a.x

template toFooPtr(a: int{lit}): ptr Foo =
  var temp = Foo(x:a)
  temp.addr

proc test(a: ptr Foo) =
  echo a[].x

proc main =
  test(toFooPtr(5))
  test(toFooPtr(123))

main()

# bug #11517
type
  UniquePtr*[T] = object
    val: ptr T

proc `=destroy`*[T](p: var UniquePtr[T]) =
  mixin `=destroy`
  echo "destroy"
  if p.val != nil:
    `=destroy`(p.val[])
    dealloc(p.val)
    p.val = nil

proc `=`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.error.}

proc `=sink`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.inline.} =
  if dest.val != src.val:
    if dest.val != nil:
      `=destroy`(dest)
    dest.val = src.val

proc newUniquePtr*[T](val: sink T): UniquePtr[T] =
  result.val = create(T)
  result.val[] = val

#-------------------------------------------------------------

type
  MyObject = object of RootObj
    x1: UniquePtr[int]

  MyObject2 = object of MyObject

proc newObj2(x:int, y: float): MyObject2 =
  MyObject2(x1: newUniquePtr(x))

proc test =
  let obj2 = newObj2(1, 1.0)
  echo obj2

test()


#------------------------------------------------------------
# Issue #12883

type
  TopObject = object
    internal: UniquePtr[int]

proc deleteTop(p: ptr TopObject) =
  if p != nil:
    `=destroy`(p[]) # !!! this operation used to leak the integer
    deallocshared(p)

proc createTop(): ptr TopObject =
  result = cast[ptr TopObject](allocShared0(sizeof(TopObject)))
  result.internal = newUniquePtr(1)

proc test2() =
  let x = createTop()
  echo $x.internal
  deleteTop(x)

echo "---------------"
echo "app begin"
test2()
echo "app end"

# bug #14601

when true: # D20200607T202043
  type Foo2 = object
    x: int
    x2: array[10, int]

  type Vec = object
    vals: seq[Foo2]

  proc `=destroy`*(a: var Foo2) {.inline.} =
    discard

  proc initFoo2(x: int): Foo2 = Foo2(x: x)

  proc add2(v: var Vec, a: Foo2) = # ditto with `a: sink Foo2`
    v.vals.add a

  proc add3(v: var Vec, a: Foo2) = # ditto with `a: sink Foo2`
    v.vals = @[a]

  proc add4(v: var Vec, a: sink Foo2) = # ditto with `a: sink Foo2`
    v.vals.add a

  proc add5(v: var Vec, a: sink Foo2) = # ditto with `a: sink Foo2`
    v.vals = @[a]

  proc main2()=
    var a: Vec
    var b = Foo2(x: 10)
    a.add2 b # ok
    a.vals.add Foo2(x: 10) # ok
    a.add2 initFoo2(x = 10) # ok
    a.add2 Foo2(x: 10) # bug
    a.add3 initFoo2(x = 10) # ok
    a.add3 Foo2(x: 10) # bug
    a.add4 initFoo2(x = 10) # ok
    a.add4 Foo2(x: 10) # bug
    a.add5 initFoo2(x = 10) # ok
    a.add5 Foo2(x: 10) # bug
  main2()



#------------------------------------------------------------
# Issue #15825

type
  Union = string | int | char

proc run(a: sink Union) =
  discard

run("123")