Swiftlint: unused_capture_list false positive with explicit capturing of strong self in Swift 5.3

Created on 31 Jul 2020  路  5Comments  路  Source: realm/SwiftLint

New Issue Checklist

Describe the bug

A new feature in Swift 5.3 allows to explicitly capture strong self and then drop the self. prefix in the closure (see SE-0269). However, SwiftLint's unused_capture_list then treats the capture as unused, because self is not explicitly written out. It is still used implicitly though, so it should not produce an error.

See below for an example.

Complete output when running SwiftLint, including the stack trace and command used
$ swiftlint lint Example.swift --no-cache                   
Linting Swift files at paths Example.swift
Linting 'Example.swift' (1/1)
Example.swift:14:50: warning: Unused Capture List Violation: Unused reference self in a capture list should be removed. (unused_capture_list)
Done linting! Found 1 violation, 0 serious in 1 file.

Environment

  • SwiftLint version (run swiftlint version to be sure)?

    • 0.39.2

  • Installation method used (Homebrew, CocoaPods, building from source, etc)?

    • homebrew

  • Paste your configuration file:

    • none, unused_capture_list is enabled by default
  • Are you using nested configurations?
    If so, paste their relative paths and respective contents.

    • no
  • Which Xcode version are you using (check xcodebuild -version)?
Xcode 12.0
Build version 12A8169g
  • Do you have a sample that shows the issue?
URLSession.shared.dataTask(with: url) { [self] (data, _, _) in
    handle(data)
}
enhancement

Most helpful comment

Looks like this isn't handling all cases, if self is qualified with unowned it still triggers:

class A {
  func foo() {}

  func bar() {
    _ = { [unowned self] in // Unused reference self in a capture list should be removed. (SwiftLint: unused_capture_list)
       foo()
    }
  }
}

I'm having the same issue. I think that this issue should be reopened.

All 5 comments

Hmm, looks like the Swift compiler actually warns on unused captures, so I wonder if we should just remove the rule instead:

$ cat file.swift 
final class A {
    func b() {
        let x = { [weak self] in print("") }
        x()
    }
}

$ swift file.swift 
file.swift:3:25: warning: variable 'self' was written to, but never read
        let x = { [weak self] in print("") }

Looks like this isn't handling all cases, if self is qualified with unowned it still triggers:

class A {
  func foo() {}

  func bar() {
    _ = { [unowned self] in // Unused reference self in a capture list should be removed. (SwiftLint: unused_capture_list)
       foo()
    }
  }
}

Looks like this isn't handling all cases, if self is qualified with unowned it still triggers:

class A {
  func foo() {}

  func bar() {
    _ = { [unowned self] in // Unused reference self in a capture list should be removed. (SwiftLint: unused_capture_list)
       foo()
    }
  }
}

I'm having the same issue. I think that this issue should be reopened.

@jberkel @guykogus Opened a new issue with unowned

For anyone looking around like me, the unowned issue was opened here. It was fixed and merged but not yet released.

Was this page helpful?
0 / 5 - 0 ratings