nicklockwood / SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
MIT License
7.62k stars 623 forks source link

RedundantSelf Rule Removal Causes Compilation Error in SwiftFormat 0.50.6 - 0.54.0 #1732

Open filimo opened 2 weeks ago

filimo commented 2 weeks ago

After updating to SwiftFormat versions between 0.50.6 and 0.54.0, the redundantSelf rule incorrectly removes the explicit use of self in some contexts, which leads to compilation errors. The issue appears when using properties within closures or async contexts in actor classes.

Steps to Reproduce

  1. Define an actor with a property.
  2. Access the property within a method, using self explicitly.
  3. Run SwiftFormat version 0.50.6 to 0.54.0 on the codebase.
  4. Observe the removal of self and the subsequent compilation error.

Example

Before running SwiftFormat:

let logger = Logger()

actor TestActor {
    let test = ""

    private func cancel() {
        logger.info("\(String(describing: self.test))")
    }
}

After running SwiftFormat:

let logger = Logger()

actor TestActor {
    let test = ""

    private func cancel() {
        logger.info("\(String(describing: test))")
    }
}

Error:

Reference to property 'test' in closure requires explicit use of 'self' to make capture semantics explicit

Expected Behavior

SwiftFormat should recognize the context in which self is necessary for property access within closures or async methods and avoid removing it.

Actual Behavior

The redundantSelf rule removes the necessary self prefix, causing a compilation error.

Environment

nicklockwood commented 2 weeks ago

@filimo I'm guessing the argument to Logger.info() is an autoclosure or something? Unfortunately SwiftFormat can't detect this automatically so you have to manually exclude such cases using --selfrequired info

filimo commented 2 weeks ago

The --selfrequired logger.info provides a partial workaround, but the problem persists in contexts involving String(describing:).