From 35ec9c31bd0bd413f1740feea90f3b97ad5d1b65 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:11:49 +0800 Subject: [PATCH] fixes refc with non-var destructor; cancel warnings (#23156) fixes https://forum.nim-lang.org/t/10807 --- compiler/semstmts.nim | 16 +++++++++++++--- lib/std/tasks.nim | 3 ++- lib/std/widestrs.nim | 3 ++- tests/iter/t22619.nim | 8 ++++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 14b7fc9315..ff29f21d09 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1966,6 +1966,11 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp; suppressV t.len == 2 and t.returnType == nil and t.firstParamType.kind == tyVar of attachedTrace: t.len == 3 and t.returnType == nil and t.firstParamType.kind == tyVar and t[2].kind == tyPointer + of attachedDestructor: + if c.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}: + t.len == 2 and t.returnType == nil + else: + t.len == 2 and t.returnType == nil and t.firstParamType.kind == tyVar else: t.len >= 2 and t.returnType == nil @@ -1977,7 +1982,8 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp; suppressV elif obj.kind == tyGenericInvocation: obj = obj.genericHead else: break if obj.kind in {tyObject, tyDistinct, tySequence, tyString}: - if (not suppressVarDestructorWarning) and op == attachedDestructor and t.firstParamType.kind == tyVar: + if (not suppressVarDestructorWarning) and op == attachedDestructor and t.firstParamType.kind == tyVar and + c.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}: message(c.config, n.info, warnDeprecated, "A custom '=destroy' hook which takes a 'var T' parameter is deprecated; it should take a 'T' parameter") obj = canonType(c, obj) let ao = getAttachedOp(c.graph, obj, op) @@ -1997,8 +2003,12 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp; suppressV localError(c.config, n.info, errGenerated, "signature for '=trace' must be proc[T: object](x: var T; env: pointer)") of attachedDestructor: - localError(c.config, n.info, errGenerated, - "signature for '=destroy' must be proc[T: object](x: var T) or proc[T: object](x: T)") + if c.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}: + localError(c.config, n.info, errGenerated, + "signature for '=destroy' must be proc[T: object](x: var T) or proc[T: object](x: T)") + else: + localError(c.config, n.info, errGenerated, + "signature for '=destroy' must be proc[T: object](x: var T)") else: localError(c.config, n.info, errGenerated, "signature for '" & s.name.s & "' must be proc[T: object](x: var T)") diff --git a/lib/std/tasks.nim b/lib/std/tasks.nim index 9eb7c97c4e..1892acd726 100644 --- a/lib/std/tasks.nim +++ b/lib/std/tasks.nim @@ -68,7 +68,8 @@ type proc `=copy`*(x: var Task, y: Task) {.error.} -when defined(nimAllowNonVarDestructor): +const arcLike = defined(gcArc) or defined(gcAtomicArc) or defined(gcOrc) +when defined(nimAllowNonVarDestructor) and arcLike: proc `=destroy`*(t: Task) {.inline, gcsafe.} = ## Frees the resources allocated for a `Task`. if t.args != nil: diff --git a/lib/std/widestrs.nim b/lib/std/widestrs.nim index 3ea4f520f2..2ddf80d14e 100644 --- a/lib/std/widestrs.nim +++ b/lib/std/widestrs.nim @@ -25,7 +25,8 @@ when not (defined(cpu16) or defined(cpu8)): bytes: int data: WideCString - when defined(nimAllowNonVarDestructor): + const arcLike = defined(gcArc) or defined(gcAtomicArc) or defined(gcOrc) + when defined(nimAllowNonVarDestructor) and arcLike: proc `=destroy`(a: WideCStringObj) = if a.data != nil: when compileOption("threads"): diff --git a/tests/iter/t22619.nim b/tests/iter/t22619.nim index 04e707633c..6a98391f30 100644 --- a/tests/iter/t22619.nim +++ b/tests/iter/t22619.nim @@ -52,8 +52,12 @@ block: var numDestroy = 0 - proc `=destroy`(x: Value) = - inc numDestroy + when defined(gcRefc): + proc `=destroy`(x: var Value) = + inc numDestroy + else: + proc `=destroy`(x: Value) = + inc numDestroy iterator iter(s: seq[Value]): int {.closure.} = # because it is used across yields, `s2` is lifted into the iterator's