mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-28 15:55:14 +00:00
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.
46 lines
798 B
Nim
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()
|