diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 4710d7c0d6..d133f2fee9 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -775,9 +775,17 @@ proc replaceHookMagic*(c: PContext, n: PNode, kind: TTypeAttachedOp): PNode = result[0] = newSymNode(op) analyseIfAddressTakenInCall(c, result, false) of attachedSink: - result = c.semAsgnOpr(c, n, nkSinkAsgn) + result = n + let t = n[1].typ.skipTypes({tyAlias, tyVar, tySink}) + let op = getAttachedOp(c.graph, t, kind) + if op != nil: + result[0] = newSymNode(op) of attachedAsgn: - result = c.semAsgnOpr(c, n, nkAsgn) + result = n + let t = n[1].typ.skipTypes({tyAlias, tyVar, tySink}) + let op = getAttachedOp(c.graph, t, kind) + if op != nil: + result[0] = newSymNode(op) of attachedDeepCopy: result = n let t = n[1].typ.skipTypes({tyAlias, tyVar, tySink}) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index bf2ff85a06..88d7512373 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -615,9 +615,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mAsgn: case n[0].sym.name.s of "=", "=copy": - result = semAsgnOpr(c, n, nkAsgn) + result = replaceHookMagic(c, n, attachedAsgn) of "=sink": - result = semAsgnOpr(c, n, nkSinkAsgn) + result = replaceHookMagic(c, n, attachedSink) else: result = semShallowCopy(c, n, flags) of mIsPartOf: result = semIsPartOf(c, n, flags) diff --git a/tests/arc/tnodestroyexplicithook2.nim b/tests/arc/tnodestroyexplicithook2.nim new file mode 100644 index 0000000000..a05eee0e31 --- /dev/null +++ b/tests/arc/tnodestroyexplicithook2.nim @@ -0,0 +1,45 @@ +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()