Universal escaping attribute

Let's get more technical on the original proposal.
All non-function arguments can be treated as "escaping" as there is no way to express non-escaping behavior for them. But the introduction of the explicit @escaping attribute would imply that there should be @noescape as well.
What would @noescape mean for non-function arguments?
Escaping function type supports not very many operations on it: own it, lose it, pass it as an escaping or non-escaping argument, and call it. Making it non-escaping denies owning and passing it as an escaping argument. This also implies that the context is either not exists or is unowned by the callee.
So, a non-escaping argument should follow the following rules:

  • It's unowned. The lifetime during the invocation is guaranteed by the caller. This is opposed to the borrow/consume semantics.
  • It cannot be owned.
  • It cannot participate in operations that may allow it to escape.

And an escaping argument is just a regular argument just like all of them now.

But for non-escaping arguments to be any useful we should also provide a way to specify that functions operating on self do not allow self to escape. Something similar to the borrowing/consuming keywords in front of a function.

class Foo {
  private var _isGood = true
  nonescaping var isGood: Bool { _isGood }
}

func bar(foo: @noescape Foo) {
  if foo.isGood { // call is allowed because it's marked as `nonescaping`
    print("good")
  }
}
1 Like