From 099ee1ce4a308024781f6f39ddfcb876f4c3629c Mon Sep 17 00:00:00 2001 From: elijahr Date: Sun, 7 Dec 2025 05:59:42 -0600 Subject: [PATCH] Fixes #25341; Invalid C code for lifecycle hooks for distinct types based on generics (#25342) --- compiler/liftdestructors.nim | 6 ++++-- tests/destructor/t25341.nim | 7 +++++++ tests/destructor/t25341_aux/a.nim | 4 ++++ tests/destructor/t25341_aux/b.nim | 6 ++++++ tests/destructor/t25341_aux/module.nim | 14 ++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/destructor/t25341.nim create mode 100644 tests/destructor/t25341_aux/a.nim create mode 100644 tests/destructor/t25341_aux/b.nim create mode 100644 tests/destructor/t25341_aux/module.nim diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 92655cf49c..ef0920d180 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -1212,8 +1212,10 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; result.ast[bodyPos].add newAsgnStmt(d, src) else: var tk: TTypeKind + var skipped: PType = nil if g.config.selectedGC in {gcArc, gcOrc, gcHooks, gcAtomicArc}: - tk = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}).kind + skipped = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}) + tk = skipped.kind else: tk = tyNone # no special casing for strings and seqs case tk @@ -1223,7 +1225,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; fillStrOp(a, typ, result.ast[bodyPos], d, src) else: fillBody(a, typ, result.ast[bodyPos], d, src) - if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not isObjLackingTypeField(typ): + if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not isObjLackingTypeField(skipped): # bug #19205: Do not forget to also copy the hidden type field: genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src) diff --git a/tests/destructor/t25341.nim b/tests/destructor/t25341.nim new file mode 100644 index 0000000000..fbe77cb5df --- /dev/null +++ b/tests/destructor/t25341.nim @@ -0,0 +1,7 @@ +discard """ + cmd: "nim c --mm:orc $file" + output: "" +""" +import ./t25341_aux/a, ./t25341_aux/b +a() +b() diff --git a/tests/destructor/t25341_aux/a.nim b/tests/destructor/t25341_aux/a.nim new file mode 100644 index 0000000000..0107ba572f --- /dev/null +++ b/tests/destructor/t25341_aux/a.nim @@ -0,0 +1,4 @@ +import ./module + +proc a*() = + discard make1[4]().make2() diff --git a/tests/destructor/t25341_aux/b.nim b/tests/destructor/t25341_aux/b.nim new file mode 100644 index 0000000000..81b515e4f9 --- /dev/null +++ b/tests/destructor/t25341_aux/b.nim @@ -0,0 +1,6 @@ +import ./module + +var globalObj: Distinct2[4] + +proc b*() = + globalObj = make1[4]().make2() diff --git a/tests/destructor/t25341_aux/module.nim b/tests/destructor/t25341_aux/module.nim new file mode 100644 index 0000000000..a4fd85a6ca --- /dev/null +++ b/tests/destructor/t25341_aux/module.nim @@ -0,0 +1,14 @@ +type + BaseObject*[N: static int] = object + value*: int + + Distinct1*[N: static int] = distinct BaseObject[N] + Distinct2*[N: static int] = distinct BaseObject[N] + +proc `=copy`*[N: static int](dest: var Distinct2[N], src: Distinct2[N]) {.error: "no".} + +proc make1*[N: static int](): Distinct1[N] = + Distinct1[N](BaseObject[N](value: 0)) + +proc make2*[N: static int](u: sink Distinct1[N]): Distinct2[N] = + Distinct2[N](BaseObject[N](u))