i am wondering about a few recently-filed issues & topics relating to variable lifetime rules and diagnostics.
the first is Compiler fails to prevent consuming parameter implicitly copied · Issue #83393 · swiftlang/swift · GitHub, which has this example from SE-377:
func foo(x: consuming String) -> (String, String) {
return (x, x)
}
the evolution document and issue both suggest that this pattern would implicitly copy the parameter x when constructing the return value, and so should produce a diagnostic. this appears to be the case in older compilers, but no longer seems true on the 6.2 branch (example of 6.1 vs 6.2).
is the behavior in the 6.2 compiler expected?
the other question is in regards to Compiler should produce error when consuming a variable captured by an `@escaping` closure · Issue #83282 · swiftlang/swift · GitHub, which alludes to this portion of SE-366:
The operand to
consumeis required to be a reference to a binding with static lifetime. The following kinds of declarations can currently be referenced as bindings with static lifetime:
- a local
letconstant in the immediately-enclosing function,- a local
varvariable in the immediately-enclosing function,- one of the immediately-enclosing function's parameters, or
- the
selfparameter in amutatingor__consumingmethod.A binding with static lifetime also must satisfy the following requirements:
- it cannot be captured by an
@escapingclosure or nested function,- it cannot have any property wrappers applied,
- it cannot have any accessors attached, such as
get,set,didSet,willSet,_read, or_modify,- it cannot be an
async let.
the question is whether, in an example like this:
func escape(_ c: @escaping () -> Void) {}
func test() {
let x = ""
escape { _ = x }
_ = consume x
}
should a diagnostic be produced? since x is captured in an escaping closure, it would seem to not satisfy the requirements for being a binding with static lifetime, and should therefore not be allowed to be consume'd. is that the correct interpretation here?