Skip to content

Commit 4352fa2

Browse files
authored
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 #22207 I had a hard time finding the other place where generic destructors get replaced by attachedDestructors
1 parent 3617d2e commit 4352fa2

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

compiler/liftdestructors.nim

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ template asink*(t: PType): PSym = getAttachedOp(c.g, t, attachedSink)
4040

4141
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
4242
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
43-
info: TLineInfo; idgen: IdGenerator; isDistinct = false): PSym
43+
info: TLineInfo; idgen: IdGenerator): PSym
4444

4545
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo;
4646
idgen: IdGenerator)
@@ -1063,9 +1063,7 @@ proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType;
10631063
assert typ.kind == tyDistinct
10641064
let baseType = typ.elementType
10651065
if getAttachedOp(g, baseType, kind) == nil:
1066-
# TODO: fixme `isDistinct` is a fix for #23552; remove it after
1067-
# `-d:nimPreviewNonVarDestructor` becomes the default
1068-
discard produceSym(g, c, baseType, kind, info, idgen, isDistinct = true)
1066+
discard produceSym(g, c, baseType, kind, info, idgen)
10691067
result = getAttachedOp(g, baseType, kind)
10701068
setAttachedOp(g, idgen.module, typ, kind, result)
10711069

@@ -1104,7 +1102,7 @@ proc symDupPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttache
11041102
incl result.flags, sfGeneratedOp
11051103

11061104
proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp;
1107-
info: TLineInfo; idgen: IdGenerator; isDiscriminant = false; isDistinct = false): PSym =
1105+
info: TLineInfo; idgen: IdGenerator; isDiscriminant = false): PSym =
11081106
if kind == attachedDup:
11091107
return symDupPrototype(g, typ, owner, kind, info, idgen)
11101108

@@ -1115,7 +1113,7 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
11151113
idgen, result, info)
11161114

11171115
if kind == attachedDestructor and g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
1118-
((g.config.isDefined("nimPreviewNonVarDestructor") and not isDiscriminant) or (typ.kind in {tyRef, tyString, tySequence} and not isDistinct)):
1116+
((g.config.isDefined("nimPreviewNonVarDestructor") and not isDiscriminant) or (typ.kind in {tyRef, tyString, tySequence})):
11191117
dest.typ = typ
11201118
else:
11211119
dest.typ = makeVarType(typ.owner, typ, idgen)
@@ -1157,13 +1155,13 @@ proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) =
11571155
body.add newAsgnStmt(xx, yy)
11581156

11591157
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
1160-
info: TLineInfo; idgen: IdGenerator; isDistinct = false): PSym =
1158+
info: TLineInfo; idgen: IdGenerator): PSym =
11611159
if typ.kind == tyDistinct:
11621160
return produceSymDistinctType(g, c, typ, kind, info, idgen)
11631161

11641162
result = getAttachedOp(g, typ, kind)
11651163
if result == nil:
1166-
result = symPrototype(g, typ, typ.owner, kind, info, idgen, isDistinct = isDistinct)
1164+
result = symPrototype(g, typ, typ.owner, kind, info, idgen)
11671165

11681166
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType: typ, idgen: idgen,
11691167
fn: result)

compiler/sempass2.nim

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import
1111
ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
1212
wordrecg, options, guards, lineinfos, semfold, semdata,
1313
modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling,
14-
semstrictfuncs, suggestsymdb, pushpoppragmas
14+
semstrictfuncs, suggestsymdb, pushpoppragmas, lowerings
1515

1616
import std/[tables, intsets, strutils, sequtils]
1717

@@ -1081,6 +1081,13 @@ proc trackCall(tracked: PEffects; n: PNode) =
10811081
let op = getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind))
10821082
if op != nil:
10831083
n[0].sym = op
1084+
if TTypeAttachedOp(opKind) == attachedDestructor and
1085+
op.typ.len == 2 and op.typ.firstParamType.kind != tyVar:
1086+
if n[1].kind == nkSym and n[1].sym.kind == skParam and
1087+
n[1].typ.kind == tyVar:
1088+
n[1] = genDeref(n[1])
1089+
else:
1090+
n[1] = skipAddr(n[1])
10841091

10851092
if op != nil and op.kind == tyProc:
10861093
for i in 1..<min(n.safeLen, op.signatureLen):

tests/destructor/tdistinctseq.nim

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,26 @@ type DistinctSeq* = distinct seq[int]
66
# `=destroy`(cast[ptr DistinctSeq](0)[])
77
var x = @[].DistinctSeq
88
`=destroy`(x)
9+
10+
11+
import std/options
12+
13+
# bug #24801
14+
type
15+
B[T] = object
16+
case r: bool
17+
of false:
18+
v: ref int
19+
of true:
20+
x: T
21+
E = distinct seq[int]
22+
U = ref object of RootObj
23+
G = ref object of U
24+
25+
proc a(): E = default(E)
26+
method c(_: U): seq[E] {.base.} = discard
27+
proc p(): seq[E] = c(default(U))
28+
method c(_: G): seq[E] = discard E(newSeq[seq[int]](1)[0])
29+
method y(_: U) {.base.} =
30+
let s = default(B[tuple[f: B[int], w: B[int]]])
31+
discard some(s.x)

0 commit comments

Comments
 (0)