From b9d3348dabe446bf15c4d91517bafa3d1ec80795 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Fri, 28 Feb 2025 01:33:35 +0800 Subject: [PATCH] sink tuples by values (#24731) A reduced case ```nim type AnObject = tuple a: string b: int c: int proc mutate(a: sink AnObject) = `=wasMoved`(a) echo 1 # echo "Value is: ", obj.value proc bar = mutate(("1.2", 0, 0)) bar() ``` (cherry picked from commit 7e8a650729e9434574c46350aece7609e5465253) --- compiler/ccgutils.nim | 6 +++++- tests/arc/tarcmisc.nim | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index d0efc20bd2..1b75906909 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -101,7 +101,11 @@ proc ccgIntroducedPtr*(conf: ConfigRef; s: PSym, retType: PType): bool = result = true # ordinary objects are always passed by reference, # otherwise casting doesn't work of tyTuple: - result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options) + if s.typ.kind == tySink: + # it's a sink, so we pass it by value + result = false + else: + result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options) else: result = false # first parameter and return type is 'lent T'? --> use pass by pointer diff --git a/tests/arc/tarcmisc.nim b/tests/arc/tarcmisc.nim index 6b8fc3b06f..12d67a999b 100644 --- a/tests/arc/tarcmisc.nim +++ b/tests/arc/tarcmisc.nim @@ -33,6 +33,7 @@ copying 123 42 @["", "d", ""] +mutate: 1 ok destroying variable: 20 destroying variable: 10 @@ -882,3 +883,18 @@ proc test_18070() = # bug #18070 doAssert msg == "", "expected empty string but got: " & $msg test_18070() + +type AnObject = tuple + a: string + b: int + c: int + +proc mutate(a: sink AnObject) = + `=wasMoved`(a) + echo "mutate: 1" + +# echo "Value is: ", obj.value +proc bar = + mutate(("1.2", 0, 0)) + +bar()