About consume keyword

func foo(val: Int) {}
let x = 0
foo(consume x)

I would like to know whether foo still makes a copy?

1 Like

This exact code will probably compile to something like

set arg1 register to 0
call foo

Copy/consume doesn't really matter that much for types like Int.

what about any big struct value?

In that case it appears not, but keep in mind that for an arbitrary function it may still internally make a copy, e.g:

struct Huge {
    var fee: String
    var fi: String
    var fo: String
    var fum: String
}

func foo(_ val: Huge) {
    var c = copy val
    c.fee = "bar"
}

I am just curious. without consuming keyword for the parameter. would It make a copy even though I used consume on a value type.

No. To my knowledge all that does is cause it to release the value after the function call rather than at the end of the scope.

no, means it doesn't make a copy?

Using consume on an argument should always avoid the need to copy a value as part of passing that argument. However, "copy" is only meant in a high-level sense there: we won't retain any references that are part of the value or perform any similar value-management operations. It does not guarantee that we won't need to relocate the value in memory in order to make the call.

That said, we should be able to avoid relocating values in memory in situations like this, so if you have a test case where Swift is doing expensive relocations (e.g. on a very large but trivially-copyable struct), please file a bug.

7 Likes

The consume keyword should be documented somewhere. I've taken a look at Documentation and could not perform a quick search, because it seems that the Swift book lacks the search feature. It's great that the book exists, but how do we navigate it without a search?

There have been a lot of additions to the language recently, and the documentation effort is running a bit behind. For now, it's described in SE-0390.