summary refs log tree commit diff stats
path: root/tests/destructor
diff options
context:
space:
mode:
authorcooldome <cdome@bk.ru>2019-05-04 22:34:37 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-05-04 22:34:37 +0200
commitd3db189eb42c1c44d8be1a1fc847ed8db428638f (patch)
tree6156800598db9699a093056f890e83c5271f4ddc /tests/destructor
parent9c3e23e0751881b16fab813fd3c2edc1b98b7f68 (diff)
downloadNim-d3db189eb42c1c44d8be1a1fc847ed8db428638f.tar.gz
Destructor lifting fixes #11149 (#11163)
* fixes #11149

* add test
Diffstat (limited to 'tests/destructor')
-rw-r--r--tests/destructor/topt.nim61
1 files changed, 61 insertions, 0 deletions
diff --git a/tests/destructor/topt.nim b/tests/destructor/topt.nim
new file mode 100644
index 000000000..829500f8a
--- /dev/null
+++ b/tests/destructor/topt.nim
@@ -0,0 +1,61 @@
+
+discard """
+  output: '''5
+vseq destroy
+'''
+"""
+type
+  opt*[T] = object
+    case exists: bool
+      of true: val: T
+      of false: discard
+
+proc some*[T](val: sink T): opt[T] {.inline.} =
+  ## Returns an ``opt`` that has the value.
+  ## nil is considered as none for reference types
+  result.exists = true
+  result.val = val
+
+proc none*(T: typedesc): opt[T] {.inline.} =
+  ## Returns an ``opt`` for this type that has no value.
+  # the default is the none type
+  discard
+
+proc none*[T]: opt[T] {.inline.} =
+  ## Alias for ``none(T)``.
+  none(T)
+
+proc unsafeGet*[T](self: opt[T]): lent T {.inline.} =
+  ## Returns the value of a ``some``. Behavior is undefined for ``none``.
+  self.val
+
+type
+  VSeq*[T] = object
+    len: int 
+    data: ptr UncheckedArray[T]
+
+proc `=destroy`*[T](m: var VSeq[T]) {.inline.} =
+  if m.data != nil:
+    echo "vseq destroy"
+    dealloc(m.data)
+    m.data = nil
+
+proc `=`*[T](m: var VSeq[T], m2: VSeq[T]) {.error.}
+
+proc `=sink`*[T](m: var VSeq[T], m2: VSeq[T]) {.inline.} =
+  if m.data != m2.data:
+    `=destroy`(m)
+  m.len = m2.len
+  m.data = m2.data
+
+proc newVSeq*[T](len: int): VSeq[T] =
+  ## Only support sequence creation from scalar size because creation from
+  ## vetorized size can't reproduce the original scalar size
+  result.len = len
+  if len > 0:
+    result.data = cast[ptr UncheckedArray[T]](alloc(sizeof(T) * len))
+
+let x = some newVSeq[float](5)
+echo x.unsafeGet.len
+let y = none(VSeq[float])
+