diff options
-rw-r--r-- | compiler/ccgtypes.nim | 5 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/transf.nim | 2 | ||||
-rw-r--r-- | tests/arc/t14383.nim | 44 |
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) |