Skip to content

Commit 85d086b

Browse files
committed
fixes #22305; Combination of generic destructor and closure fails in certain cases
1 parent 2d0b62a commit 85d086b

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

compiler/liftdestructors.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ proc requiresDestructor(c: TLiftCtx; t: PType): bool {.inline.} =
380380
proc instantiateGeneric(c: var TLiftCtx; op: PSym; t, typeInst: PType): PSym =
381381
if c.c != nil and typeInst != nil:
382382
result = c.c.instTypeBoundOp(c.c, op, typeInst, c.info, attachedAsgn, 1)
383+
elif typeInst != nil and getAttachedOp(c.g, typeInst, c.kind) != nil:
384+
# c.c == nil in lambdalifting
385+
# hooks are already insted
386+
result = getAttachedOp(c.g, typeInst, c.kind)
383387
else:
384388
localError(c.g.config, c.info,
385389
"cannot generate destructor for generic type: " & typeToString(t))

tests/generics/t22305.nim

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
discard """
2+
joinable: false
3+
"""
4+
5+
import asyncdispatch, options
6+
7+
proc recv*[T](tc: ptr Channel[T]): Future[T] {.async.} =
8+
discard
9+
10+
type SharedBuf = object
11+
12+
type WorkProc[A, B] = proc(a: A): Option[B] {.nimcall.}
13+
14+
proc worker[TArg](p: TArg) {.thread, nimcall.} =
15+
discard
16+
17+
proc readFilesThread() =
18+
type TArg[A, B] =
19+
tuple[r: ptr Channel[Option[A]], w: ptr Channel[Option[B]], p: WorkProc[A, B]]
20+
21+
var readThread: Thread[TArg[int, SharedBuf]]
22+
23+
proc readFilesAd() {.async.} =
24+
var readChan: Channel[Option[int]]
25+
26+
type TArg[A, B] =
27+
tuple[r: ptr Channel[Option[A]], w: ptr Channel[Option[B]], p: WorkProc[A, B]]
28+
29+
var readThread: Thread[TArg[int, SharedBuf]]
30+
let test = await (addr readChan).recv()
31+
32+
joinThread(readThread)
33+
34+
waitFor readFilesAd()
35+
36+
type
37+
SharedPtr[T] = object
38+
p: ptr T
39+
40+
proc `=destroy`[T](self: var SharedPtr[T]) =
41+
discard
42+
43+
type
44+
SomethingObj[T] = object
45+
Something[T] = SharedPtr[SomethingObj[T]]
46+
47+
proc useSomething() =
48+
# discard Something[int]() # When you uncomment this line, it will compile successfully.
49+
discard Something[float]()
50+
51+
proc fn() =
52+
let thing = Something[int]()
53+
proc closure() =
54+
discard thing
55+
closure()
56+
57+
fn()

0 commit comments

Comments
 (0)