diff --git a/compiler/sem/liftdestructors.nim b/compiler/sem/liftdestructors.nim index 793c24209bd..19c61287468 100644 --- a/compiler/sem/liftdestructors.nim +++ b/compiler/sem/liftdestructors.nim @@ -904,11 +904,13 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; result.ast[bodyPos].add newOpCall(a, getAttachedOp(g, typ, attachedDestructor), d[0]) result.ast[bodyPos].add newAsgnStmt(d, src) else: - var tk: TTypeKind - if g.config.selectedGC in {gcArc, gcOrc}: - tk = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, tyStatic, tyAlias, tySink}).kind - else: - tk = tyNone # no special casing for strings and seqs + let (tk, baseTyp) = + if g.config.selectedGC in {gcArc, gcOrc}: + let t = skipTypes(typ, {tyOrdinal, tyRange, tyInferred, tyGenericInst, + tyStatic, tyAlias, tySink}) + (t.kind, t) + else: + (tyNone, typ) # no special casing for strings and seqs case tk of tySequence: fillSeqOp(a, typ, result.ast[bodyPos], d, src) @@ -917,7 +919,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; else: fillBody(a, typ, result.ast[bodyPos], d, src) if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy} and - not isObjLackingTypeField(typ): + not isObjLackingTypeField(baseTyp): # bug #19205: Do not forget to also copy the hidden type field: genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src) diff --git a/tests/lang_objects/destructor/ttypeops_misc.nim b/tests/lang_objects/destructor/ttypeops_misc.nim new file mode 100644 index 00000000000..aa862a1deb2 --- /dev/null +++ b/tests/lang_objects/destructor/ttypeops_misc.nim @@ -0,0 +1,24 @@ +discard """ +""" + +block ensure_lifting_is_not_confused_by_type_wrappers: + ## previously this led to a code gen bug where a non-existent hidden type + ## field was being copied. the various wrappers alias/distinct weren't being + ## skipped when testing to see if the underlying type was an object. + type WithHooks = object + + proc `=destroy`(x: var WithHooks) = + # force `WithHooks` to require lifetime hooks + discard + + type + Object = object + x: WithHooks # make sure that `Object` gets a synthesized copy hook + Alias = Object + Distinct = distinct Alias + + proc test(y: Distinct) = + var x = y + discard (addr x) # prevent `x` being turned into a cursor + + test(default(Distinct))