swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.69k stars 10.39k forks source link

Should capturing a modified variable declared inside a loop be a warning when used in Sendable closure? #75882

Open johnno1962 opened 3 months ago

johnno1962 commented 3 months ago

Description

Hi Apple,

I have a piece of code which goes something like the following:

        while launchOptions?.isEmpty != true {
            var s = "value"

            s += "?" // Invalid warning reported here "'s' mutated after capture by sendable closure"

            DispatchQueue.global().async {
                print(s)
            }
        }

Reproduction

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        while launchOptions?.isEmpty != true {
            var s = "value"

            s += "?"

            DispatchQueue.global().async {
                print(s)
            }
        }

        return true
    }

EH.zip

Expected behavior

I would have thought the value "s" was captured when the closure is created and is not modified after that. This only occurs inside a loop and has been a warning that makes no sense to me going back to Xcode 15. It seems it is not taking into account that each new version of the variable "s" created inside the loop must be considered separately. If you try to ignore such a warning your program can crash so something is not quite as it should be.

Environment

swift-driver version: 1.113 Apple Swift version 6.0 (swiftlang-6.0.0.7.6 clang-1600.0.24.1) Target: arm64-apple-macosx14.0

Additional information

The actual code I was having problems with in context is https://github.com/johnno1962/InjectionNext/blob/main/App/InjectionNext/MonitorXcode.swift#L185

johnno1962 commented 3 months ago

@gottesmm, can you triage this for me please?