Unneeded Escaping

The @escaping attribute should only be used when the closure actually escapes.

  • Identifier: unneeded_escaping
  • Enabled by default: No
  • Supports autocorrection: Yes
  • Kind: lint
  • Analyzer rule: No
  • Minimum Swift compiler version: 5.0.0
  • Default configuration:
    KeyValue
    severity warning

Non Triggering Examples

func outer(completion: @escaping () -> Void) { inner(completion: completion) }
func returning(_ work: @escaping () -> Void) -> () -> Void { return work }
func implicitlyReturning(g: @escaping () -> Void) -> () -> Void { g }
struct S {
    var closure: (() -> Void)?
    mutating func setClosure(_ newValue: @escaping () -> Void) {
        closure = newValue
    }
    mutating func setToSelf(_ newValue: @escaping () -> Void) {
        self.closure = newValue
    }
}
func closure(completion: @escaping () -> Void) {
    DispatchQueue.main.async { completion() }
}
func capture(completion: @escaping () -> Void) {
    let closure = { completion() }
    closure()
}
func reassignLocal(completion: @escaping () -> Void) -> () -> Void {
    var local = { print("initial") }
    local = completion
    return local
}
func global(completion: @escaping () -> Void) {
    Global.completion = completion
}
func chain(c: @escaping () -> Void) -> () -> Void {
    let c1 = c
    if condition {
        let c2 = c1
        return c2
    }
    let c3 = c1
    return c3
}

Triggering Examples

func forEach(action: @escaping (Int) -> Void) {
    for i in 0..<10 {
        action(i)
    }
}
func process(completion: @escaping () -> Void) {
    completion()
}
func apply(_ transform: @escaping (Int) -> Int) -> Int {
    return transform(5)
}
func optional(completion: (@escaping () -> Void)?) {
    completion?()
}
func multiple(first: @escaping () -> Void, second: @escaping () -> Void) {
    first()
    second()
}
subscript(transform: @escaping (Int) -> String) -> String {
    transform(42)
}
func assignToLocal(completion: @escaping () -> Void) {
    let local = completion
    local()
}
func reassignLocal(completion: @escaping () -> Void) {
    var local = { print("initial") }
    local = completion
    local()
}