Files
Nim/tests/arc/tnodestroyexplicithook2.nim
metagn a35614e539 make explicit copy and hook calls keep their symbol (#25731)
fixes #25730

As mentioned in the issue this results in less optimized output, it
always generates the explicitly called hook as a proc rather than an
inline assignment. But maybe this is a reasonable trade since it only
happens on explicit `=sink`/`=copy` calls.

Any way to optimize it requires detecting either the type or the found
hook as a trivial assignment. I am not sure how to do these, the hook
isn't like destructors that propagate empty statements in
`liftdestructors` (which is what `isTrivial` checks for), it needs to
propagate simple assignments instead. And there is no logic for the
type, `tfHasAsgn` is misleading since it only checks if the destructor
is trivial, because there is no check for a trivial assignment.

Did not mark as backported but the only issue I can think of is the
performance issue above, otherwise it would be more correct if anything.
2026-04-12 07:05:48 +02:00

46 lines
798 B
Nim

discard """
output: '''
246
246
'''
"""
# issue #25730
type
Inner[T] = object
x: T
Foo[T] = object
inner: Inner[T]
Bar[T] = object
foo: Foo[T]
proc `=sink`[T](a: var Inner[T], b: Inner[T]) {.nodestroy.} =
a.x = b.x * 2
proc `=copy`[T](a: var Inner[T], b: Inner[T]) {.nodestroy.} =
a.x = b.x * 2
when true:
proc `=sink`[T](a: var Bar[T], b: Bar[T]) {.nodestroy.} =
`=sink`(a.foo, b.foo)
proc `=copy`[T](a: var Bar[T], b: Bar[T]) {.nodestroy.} =
`=copy`(a.foo, b.foo)
proc useSink() =
let a = Bar[int](foo: Foo[int](inner: Inner[int](x: 123)))
var b: Bar[int]
`=sink`(b, a)
echo b.foo.inner.x
useSink()
proc useCopy() =
let a = Bar[int](foo: Foo[int](inner: Inner[int](x: 123)))
var b: Bar[int]
`=copy`(b, a)
echo b.foo.inner.x
useCopy()