From 834dcab66cfcbd943a17b1fe24c634e3f24cbebd Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 12 Mar 2025 22:02:29 +0800 Subject: [PATCH] fixes #24760; Noncopyable base type ignored --- compiler/injectdestructors.nim | 9 ++++++--- tests/arc/t24760.nim | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/arc/t24760.nim diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index ce9164058a..e493cf0a64 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -162,9 +162,12 @@ proc isLastReadImpl(n: PNode; c: var Con; scope: var Scope): bool = else: result = false -proc isLastRead(n: PNode; c: var Con; s: var Scope): bool = +template hasDestructorOrAsgn(c: var Con, typ: PType): bool = # bug #23354; an object type could have a non-trival assignements when it is passed to a sink parameter - if not hasDestructor(c, n.typ) and (n.typ.kind != tyObject or isTrival(getAttachedOp(c.graph, n.typ, attachedAsgn))): return true + hasDestructor(c, typ) or (typ.kind == tyObject and not isTrival(getAttachedOp(c.graph, typ, attachedAsgn))) + +proc isLastRead(n: PNode; c: var Con; s: var Scope): bool = + if not hasDestructorOrAsgn(c, n.typ): return true let m = skipConvDfa(n) result = (m.kind == nkSym and sfSingleUsedTemp in m.sym.flags) or @@ -449,7 +452,7 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode = result = newNodeIT(nkStmtListExpr, n.info, n.typ) let nTyp = n.typ.skipTypes(tyUserTypeClasses) let tmp = c.getTemp(s, nTyp, n.info) - if hasDestructor(c, nTyp): + if hasDestructorOrAsgn(c, nTyp): let typ = nTyp.skipTypes({tyGenericInst, tyAlias, tySink}) let op = getAttachedOp(c.graph, typ, attachedDup) if op != nil and tfHasOwned notin typ.flags: diff --git a/tests/arc/t24760.nim b/tests/arc/t24760.nim new file mode 100644 index 0000000000..4eb65a3774 --- /dev/null +++ b/tests/arc/t24760.nim @@ -0,0 +1,20 @@ +discard """ + matrix: "--mm:refc; --mm:orc" + errormsg: "=dup' is not available for type , which is inferred from unavailable '=copy'; requires a copy because it's not the last read of 'b'; another read is done here: t24760.nim(19, 8); routine: g" +""" + +type + A {.inheritable.} = object + B = object of A + +proc `=copy`(a: var A, x: A) {.error.} +#proc `=copy`(a: var B, x: B) {.error.} + +proc ffff(v: sink B) = + echo v + +proc g() = + var b: B + ffff(b) + ffff(b) +g() \ No newline at end of file