summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgtypes.nim5
-rw-r--r--compiler/liftdestructors.nim2
-rw-r--r--compiler/transf.nim2
-rw-r--r--tests/arc/t14383.nim44
4 files changed, 49 insertions, 4 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 798eaf7f9..e7e9d97d8 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -1330,7 +1330,7 @@ proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp): Rope =
 
 proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineInfo) =
   var typeName: Rope
-  if t.kind == tyObject:
+  if t.kind in {tyObject, tyDistinct}:
     if incompleteType(t):
       localError(m.config, info, "request for RTTI generation for incomplete object: " &
                  typeToString(t))
@@ -1353,7 +1353,8 @@ proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineIn
 
 proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
   let origType = t
-  var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
+  # distinct types can have their own destructors
+  var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses - {tyDistinct})
 
   let prefixTI = if m.hcrOn: "(" else: "(&"
 
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index 5ffa25e53..f79742389 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -361,7 +361,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
     result = true
 
 proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) =
-  let t = orig.skipTypes(abstractInst)
+  let t = orig.skipTypes(abstractInst - {tyDistinct})
   var op = t.destructor
 
   if op != nil and sfOverriden in op.flags:
diff --git a/compiler/transf.nim b/compiler/transf.nim
index daf223106..255f29546 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -524,6 +524,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
         result[0] = transform(c, n[1])
       else:
         result = transform(c, n[1])
+        result.typ = n.typ
     else:
       result = transformSons(c, n)
   of tyObject:
@@ -536,6 +537,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
       result[0] = transform(c, n[1])
     else:
       result = transform(c, n[1])
+      result.typ = n.typ
   of tyGenericParam, tyOrdinal:
     result = transform(c, n[1])
     # happens sometimes for generated assignments, etc.
diff --git a/tests/arc/t14383.nim b/tests/arc/t14383.nim
index 85f90d1c8..c5f0e08ac 100644
--- a/tests/arc/t14383.nim
+++ b/tests/arc/t14383.nim
@@ -125,4 +125,46 @@ proc main =
   let rankdef = avals
   echo avals.len, " ", rankdef.len
 
-main()
\ No newline at end of file
+main()
+
+
+#------------------------------------------------------------------------------
+# Issue #16722, ref on distinct type, wrong destructors called
+#------------------------------------------------------------------------------
+
+type
+  Obj = object of RootObj
+  ObjFinal = object
+  ObjRef = ref Obj
+  ObjFinalRef = ref ObjFinal
+  D = distinct Obj
+  DFinal = distinct ObjFinal
+  DRef = ref D
+  DFinalRef = ref DFinal
+
+proc `=destroy`(o: var Obj) =
+  doAssert false, "no Obj is constructed in this sample"
+
+proc `=destroy`(o: var ObjFinal) =
+  doAssert false, "no ObjFinal is constructed in this sample"
+
+var dDestroyed: int
+proc `=destroy`(d: var D) =
+  dDestroyed.inc
+
+proc `=destroy`(d: var DFinal) =
+  dDestroyed.inc
+
+func newD(): DRef =
+  DRef ObjRef()
+
+func newDFinal(): DFinalRef =
+  DFinalRef ObjFinalRef()
+
+proc testRefs() =
+  discard newD()
+  discard newDFinal()
+
+testRefs()
+
+doAssert(dDestroyed == 2)