My impression, after reading SE-0366 was that consume
operator should be valid on parameters local to the function (although, when the proposal says "local" it doesn't explicitly say "to the function" which makes it ambiguous (but logically it should have been "local to function").
For some reason, when you try to consume
a let
variable in a nested function with Copyable
type, it happily compiles, but refuses to compile with var
. It also doesn't compile when the type is ~Copyable
.
class IntBox {
var value: Int
init(_ value: Int) { self.value = value }
}
struct IntOwner: ~Copyable {
var value: Int
deinit {
print("Int \(value) ceased to be")
}
}
func testConsumeLetVariable() {
let x = IntBox(5)
func consumeLetVariable() {
_ = consume x // No error or warning produced. Is this intended?
}
consumeLetVariable()
print(x)
}
func testConsumeVarVariable() {
var x = IntBox(5)
func consumeVarVariable() {
_ = consume x // Error as expected. Error message: 'consume' cannot be applied to escaping caputres
}
consumeVarVariable()
print(x)
}
func testConsumeNonCopyableLet() {
let x = IntOwner(value: 6)
func consumeNonCopyable() {
_ = consume x // Error as expected: Message: Noncopyable 'x' cannot be consumed when captured by an escaping closure
}
consumeNonCopyable()
print(x.value)
}
Is this intended? If it is - is it documented somewhere?
On a side note - if I replace my IntBox with plain Int, the variable can be used after consume, (even if not consumed inside of a nested function), with the following warning: 'consume' applied to bitwise-copyable type
Int has no effect
. (Happens only if x
is let
. When x
is var
, works as expected). What is going on? And where is it documented?