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()