summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/liftdestructors.nim7
-rw-r--r--tests/destructor/tdestructor3.nim46
2 files changed, 51 insertions, 2 deletions
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index b05e13c0f..8f688d732 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -89,6 +89,11 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode) =
   else:
     illFormedAstLocal(n, c.g.config)
 
+proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
+  if t.len > 0 and t.sons[0] != nil:
+    fillBodyObjT(c, skipTypes(t.sons[0], abstractPtrs), body, x, y)
+  fillBodyObj(c, t.n, body, x, y)
+
 proc genAddr(g: ModuleGraph; x: PNode): PNode =
   if x.kind == nkHiddenDeref:
     checkSonsLen(x, 1, g.config)
@@ -482,7 +487,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
       defaultOp(c, t, body, x, y)
   of tyObject:
     if not considerUserDefinedOp(c, t, body, x, y):
-      fillBodyObj(c, t.n, body, x, y)
+      fillBodyObjT(c, t, body, x, y)
   of tyDistinct:
     if not considerUserDefinedOp(c, t, body, x, y):
       fillBody(c, t.sons[0].skipTypes(skipPtrs), body, x, y)
diff --git a/tests/destructor/tdestructor3.nim b/tests/destructor/tdestructor3.nim
index a1de284ae..4c251e0bf 100644
--- a/tests/destructor/tdestructor3.nim
+++ b/tests/destructor/tdestructor3.nim
@@ -5,7 +5,9 @@ destroy
 5
 123
 destroy Foo: 123
-destroy Foo: 5'''
+destroy Foo: 5
+(x1: (val: ...))
+destroy'''
 joinable: false
 """
 
@@ -49,3 +51,45 @@ proc main =
   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()