From 4352fa2ef0cbba953d9a90b90873e8dd0364b72e Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Thu, 3 Apr 2025 00:46:29 +0800 Subject: [PATCH] fixes #24801; Invalid C codegen generated when destroying distinct seq types (#24835) fixes #24801 Because distinct `seq` types match `proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".}`. But the Nim compiler generates lifted seq types for corresponding distinct types. So we skip the address for distinct types. Related to https://github.com/nim-lang/Nim/pull/22207 I had a hard time finding the other place where generic destructors get replaced by attachedDestructors --- compiler/liftdestructors.nim | 14 ++++++-------- compiler/sempass2.nim | 9 ++++++++- tests/destructor/tdistinctseq.nim | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index c948916132..49c06ce1d5 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -40,7 +40,7 @@ template asink*(t: PType): PSym = getAttachedOp(c.g, t, attachedSink) proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; - info: TLineInfo; idgen: IdGenerator; isDistinct = false): PSym + info: TLineInfo; idgen: IdGenerator): PSym proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo; idgen: IdGenerator) @@ -1063,9 +1063,7 @@ proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType; assert typ.kind == tyDistinct let baseType = typ.elementType if getAttachedOp(g, baseType, kind) == nil: - # TODO: fixme `isDistinct` is a fix for #23552; remove it after - # `-d:nimPreviewNonVarDestructor` becomes the default - discard produceSym(g, c, baseType, kind, info, idgen, isDistinct = true) + discard produceSym(g, c, baseType, kind, info, idgen) result = getAttachedOp(g, baseType, kind) setAttachedOp(g, idgen.module, typ, kind, result) @@ -1104,7 +1102,7 @@ proc symDupPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttache incl result.flags, sfGeneratedOp proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp; - info: TLineInfo; idgen: IdGenerator; isDiscriminant = false; isDistinct = false): PSym = + info: TLineInfo; idgen: IdGenerator; isDiscriminant = false): PSym = if kind == attachedDup: return symDupPrototype(g, typ, owner, kind, info, idgen) @@ -1115,7 +1113,7 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp idgen, result, info) if kind == attachedDestructor and g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and - ((g.config.isDefined("nimPreviewNonVarDestructor") and not isDiscriminant) or (typ.kind in {tyRef, tyString, tySequence} and not isDistinct)): + ((g.config.isDefined("nimPreviewNonVarDestructor") and not isDiscriminant) or (typ.kind in {tyRef, tyString, tySequence})): dest.typ = typ else: dest.typ = makeVarType(typ.owner, typ, idgen) @@ -1157,13 +1155,13 @@ proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.add newAsgnStmt(xx, yy) proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; - info: TLineInfo; idgen: IdGenerator; isDistinct = false): PSym = + info: TLineInfo; idgen: IdGenerator): PSym = if typ.kind == tyDistinct: return produceSymDistinctType(g, c, typ, kind, info, idgen) result = getAttachedOp(g, typ, kind) if result == nil: - result = symPrototype(g, typ, typ.owner, kind, info, idgen, isDistinct = isDistinct) + result = symPrototype(g, typ, typ.owner, kind, info, idgen) var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType: typ, idgen: idgen, fn: result) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 0aa96bd6ea..f1fcd94c53 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -11,7 +11,7 @@ import ast, astalgo, msgs, renderer, magicsys, types, idents, trees, wordrecg, options, guards, lineinfos, semfold, semdata, modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling, - semstrictfuncs, suggestsymdb, pushpoppragmas + semstrictfuncs, suggestsymdb, pushpoppragmas, lowerings import std/[tables, intsets, strutils, sequtils] @@ -1081,6 +1081,13 @@ proc trackCall(tracked: PEffects; n: PNode) = let op = getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind)) if op != nil: n[0].sym = op + if TTypeAttachedOp(opKind) == attachedDestructor and + op.typ.len == 2 and op.typ.firstParamType.kind != tyVar: + if n[1].kind == nkSym and n[1].sym.kind == skParam and + n[1].typ.kind == tyVar: + n[1] = genDeref(n[1]) + else: + n[1] = skipAddr(n[1]) if op != nil and op.kind == tyProc: for i in 1..