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.