i was an early adopter of _move(_:)
because (like many others i’m sure) i remember the swift 4.x days when the compiler was not so good at optimizing copies, so when _move(_:)
was announced i was thrilled and if you are anything like me i started spraying it everywhere.
in hindsight this was not so smart because with _move(_:)
and no take
/borrow
, it is really easy to fool yourself into thinking you prevented a copy. because as @michelf said, if you _move(_:)
/_move
into a pass guaranteed function parameter, it just copies into a temporary, and most functions are pass guaranteed, so i really wish when i did this the compiler would emit a warning:
import Bar
func foo(buffer:__owned [Int])
{
var buffer:[Int] = _move buffer
buffer.append(0)
Bar.bar(_move buffer)
// ^~~~~~
// _move into __shared copies into a temporary;
// add parentheses to surpress this warning
}
and for a long time i didn’t know this was a thing because it’s not always obvious why the example before is dumb but the example below is smart usage of _move
:
import Bar
func foo(buffer:__owned [Int])
{
var buffer:[Int] = _move buffer
buffer.append(0)
var view:Bar = .init(_move buffer)
}
and i don’t really notice this because i use @inlinable
a lot too much and more often than not the footgun gets jammed because Bar.bar(_:)
is not from another module it is from the same module and the compiler can make it __owned
, and also the 5.6 compiler is a lot smarter than the 4.x compiler was.