Definition of non-escaping closure in SE-0390

SE-0390 has the following text (emphasis mine):

For the purposes of the following discussion, a closure is considered nonescaping in the following cases:

  • if the closure literal appears as an argument to a function parameter of non-@escaping function type, or
  • if the closure literal is assigned to a local let variable, that does not itself get captured by an escaping closure.

These cases correspond to the cases where a closure is allowed to capture an inout parameter from its surrounding scope, before this proposal.

It caught my attention because item 2 contradicts @Slava_Pestov's explanation in this thread. At first I thought it might be a definition used only within this proposal. However, my experiment shows that a closure described in item 2 is considered as escaping in all releases I tried and isn't allowed to capture inout parameter:

func test(_ x: inout String) {
    let fn: () -> Void = {
        x = "2" // error: escaping closure captures 'inout' parameter 'x'
        print(x)
    }
    fn()
}

var x = "1"
test(&x)

Here is the result on godbolt. Am I missing something?

2 Likes

Nice catch! You’re not missing anything. The text in the proposal is incorrect and needs to be revised to match the implemented behavior.

5 Likes