mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-05 20:47:53 +00:00
fixes #22286 ref https://forum.nim-lang.org/t/10642 For backwards compatibilities, we might need to keep the changes under a preview compiler flag. Let's see how many packags it break. **TODO** in the following PRs - [ ] Turn the `var T` destructors warning into an error with `nimPreviewNonVarDestructor` --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
53 lines
1.4 KiB
Nim
53 lines
1.4 KiB
Nim
discard """
|
|
outputsub: "true"
|
|
disabled: "32bit"
|
|
"""
|
|
|
|
type
|
|
TFoo* = object
|
|
id: int
|
|
fn: proc() {.closure.}
|
|
var foo_counter = 0
|
|
var alive_foos = newseq[int](0)
|
|
|
|
when defined(gcDestructors):
|
|
proc `=destroy`(some: TFoo) =
|
|
alive_foos.del alive_foos.find(some.id)
|
|
# TODO: fixme: investigate why `=destroy` requires `some.fn` to be `gcsafe`
|
|
# the debugging info below came from `symPrototype` in the liftdestructors
|
|
# proc (){.closure, gcsafe.}, {tfThread, tfHasAsgn, tfCheckedForDestructor, tfExplicitCallConv}
|
|
# var proc (){.closure, gcsafe.}, {tfHasGCedMem}
|
|
# it worked by accident with var T destructors because in the sempass2
|
|
#
|
|
# let argtype = skipTypes(a.typ, abstractInst) # !!! it does't skip `tyVar`
|
|
# if argtype.kind == tyProc and notGcSafe(argtype) and not tracked.inEnforcedGcSafe:
|
|
# localError(tracked.config, n.info, $n & " is not GC safe")
|
|
{.cast(gcsafe).}:
|
|
`=destroy`(some.fn)
|
|
|
|
else:
|
|
proc free*(some: ref TFoo) =
|
|
#echo "Tfoo #", some.id, " freed"
|
|
alive_foos.del alive_foos.find(some.id)
|
|
|
|
proc newFoo*(): ref TFoo =
|
|
when defined(gcDestructors):
|
|
new result
|
|
else:
|
|
new result, free
|
|
|
|
result.id = foo_counter
|
|
alive_foos.add result.id
|
|
inc foo_counter
|
|
|
|
for i in 0 ..< 10:
|
|
discard newFoo()
|
|
|
|
for i in 0 ..< 10:
|
|
let f = newFoo()
|
|
f.fn = proc =
|
|
echo f.id
|
|
|
|
GC_fullcollect()
|
|
echo alive_foos.len <= 3
|