diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index ce84bc0dcb188..3e1f6afc71349 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -163,7 +163,8 @@ proc isLastReadImpl(n: PNode; c: var Con; scope: var Scope): bool = result = false proc isLastRead(n: PNode; c: var Con; s: var Scope): bool = - if not hasDestructor(c, n.typ): return true + # 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 let m = skipConvDfa(n) result = (m.kind == nkSym and sfSingleUsedTemp in m.sym.flags) or diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index aba1aa38c7020..350b4cc255520 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -1252,7 +1252,7 @@ proc inst(g: ModuleGraph; c: PContext; t: PType; kind: TTypeAttachedOp; idgen: I else: localError(g.config, info, "unresolved generic parameter") -proc isTrival(s: PSym): bool {.inline.} = +proc isTrival*(s: PSym): bool {.inline.} = s == nil or (s.ast != nil and s.ast[bodyPos].len == 0) proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo; diff --git a/tests/destructor/tsink.nim b/tests/destructor/tsink.nim new file mode 100644 index 0000000000000..82cbdfbe5da86 --- /dev/null +++ b/tests/destructor/tsink.nim @@ -0,0 +1,16 @@ +discard """ + matrix: "--mm:arc" +""" + +type AnObject = object of RootObj + value*: int + +proc mutate(shit: sink AnObject) = + shit.value = 1 + +proc foo = # bug #23359 + var bar = AnObject(value: 42) + mutate(bar) + doAssert bar.value == 42 + +foo()