Skip to content

Allow =destroy on pointer types. (previously experimental feature) #7776

@mratsim

Description

@mratsim

The following used to work:

import opencl

{.experimental.}

type clResource = PCommandQueue | PKernel | PProgram | PMem | PContext

template release*(queue: PCommandQueue) = check releaseCommandQueue(queue)
template release*(kernel: PKernel) = check releaseKernel(kernel)
template release*(program: PProgram) = check releaseProgram(program)
template release*(buffer: PMem) = check releaseMemObject(buffer)
template release*(context: PContext) = check releaseContext(context)

proc `=destroy`*(clres: clResource) =
  release clres

The error now is:
Error: signature for '=destroy' must be proc[T: object](x: var T)

Looking at the previous code we had this:

Nim/compiler/semstmts.nim

Lines 1364 to 1387 in 8ce9e43

proc semOverride(c: PContext, s: PSym, n: PNode) =
case s.name.s.normalize
of "destroy", "=destroy":
if newDestructors:
let t = s.typ
var noError = false
if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
var obj = t.sons[1].sons[0]
while true:
incl(obj.flags, tfHasAsgn)
if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
else: break
if obj.kind in {tyObject, tyDistinct}:
if obj.destructor.isNil:
obj.destructor = s
else:
localError(n.info, errGenerated,
"cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
noError = true
if not noError and sfSystemModule notin s.owner.flags:
localError(n.info, errGenerated,
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
incl(s.flags, sfUsed)

And now:

Nim/compiler/semstmts.nim

Lines 1309 to 1331 in 6080178

proc semOverride(c: PContext, s: PSym, n: PNode) =
case s.name.s.normalize
of "=destroy":
let t = s.typ
var noError = false
if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar:
var obj = t.sons[1].sons[0]
while true:
incl(obj.flags, tfHasAsgn)
if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon
elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
else: break
if obj.kind in {tyObject, tyDistinct}:
if obj.destructor.isNil:
obj.destructor = s
else:
localError(n.info, errGenerated,
"cannot bind another '" & s.name.s & "' to: " & typeToString(obj))
noError = true
if not noError and sfSystemModule notin s.owner.flags:
localError(n.info, errGenerated,
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
incl(s.flags, sfUsed)

So it seems like the old experimental destructors were removed.

There is a plan to have destructors replace finalizer for ref objects. It would be also very useful to have destructors for ptr types especially for wrapping C libraries that gives an opaque type and the corresponding destroy/release proc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions