Help with approachable-concurrency sample code

The code below, from here: Swift 6.2 Released- Approachable Concurrency, won't compile for me.

// In '-default-isolation MainActor' mode struct Image { // The image cache is safe because it's protected // by the main actor. static var cachedImage: [URL: Image] = [:] static func create(from url: URL) async throws -> Image { if let image = cachedImage[url] { return image } let image = try await fetchImage(at: url) cachedImage[url] = image return image } // Fetch the data from the given URL and decode it. // This is performed on the concurrent thread pool to // keep the main actor free while decoding large images. @concurrent static func fetchImage(at url: URL) async throws -> Image { let (data, _) = try await URLSession.shared.data(from: url) return await decode(data: data) } } 

I get this error:

Static property 'cachedImage' is not concurrency-safe because it is nonisolated global shared mutable state 

Xcode 26 - Swift Compiler-Concurrency

Approachable Concurrency: Yes Default Actor Isolation: MainActor Strict Concurrency Checking: Minimal 

What am I doing wrong? Given that this an official example, from Apple, I must be doing something wrong.

Maybe check the swift language version in the compiler

In Xcode Swift 6, but swiftc -v on the command line says Swift 6.2.

If I compile the same code from the command line, that error is no longer there, which is good.

Thank you for nudging me in the right direction. :slight_smile:

As far as I know, this is always Complete if you set Swift 6 language mode (which also can be Swift 5, Swift 4.2, or Swift 4, all available in Swift 6.2 compiler). If Xcode allows yo to set both Swift 6 language mode and Minimal strict concurrency checking at the same time (without a warning), then this is a bug in Xcode.

1 Like

I am unable to reproduce your error in Xcode 26 (26.0.1 – Build 17A400) unless I change the “Default Actor Isolation” build setting to “nonisolated”. I wonder if the problem might stem from the confusing hierarchy of build settings (e.g., you can set this build setting to “MainActor” for the project, but still have it set to “nonisolated” for the target in question).

Maybe you can create a MRE project that manifests this problem and upload it somewhere and we can take a look at it.

According to the docs:

So, it appears to effectively ignore this build setting when “Language Version” build setting is “Swift 6”.

I might hesitate to call this a “bug”, per se, but at the very least the inline help for SWIFT_STRICT_CONCURRENCY should have some perfunctory disclaimer about Swift 5 vs Swift 6. (Frankly, I could have sworn that it did, but I don’t see it in either Xcode 26 or 16.4.)

1 Like

Yes, it appears to silently ignore this setting, this is why I called it a "bug". IMHO it should warn a user about incompatible setting, and if it does not, maybe it's an oversight (not a bug per se).

Thank you, @robert.ryan

Looks like this is something to do with the kind of hardware processor used: intel or apple-silicon.

Just tried on an apple-silicon machine, using both Xcode 26.0 and Xcode 26.1_beta_2; the same code compiles.

On an intel machine, however, using both Xcode 26.0 and Xcode 26.1_beta_2, the compilation fails.

PS: I can, however, compile it from the command line. :confused:

That is not my experience. I suspect there is some other variable at play.

For example, this MRE generates the error in Xcode 26 if “Default Actor Isolation” setting is “nonisolated”, but does not generate an error if set to “MainActor” (just as one would expect). I see the exact same behaviors regardless of hardware, whether Apple Silicon or Intel. In my example, my Intel machine is running macOS Sequoia 15.7.1, but my Apple Silicon is running macOS Tahoe 26.0.1. But both are running Xcode 26.0.1 (17A400). It would be interesting how my MRE behaves on your two computers.

I am not trying to dismiss your observations, as you obviously are experiencing some real issue, but I am unable to reproduce it. So:

  • It would also be interesting to see if my above MRE manifests the problem you describe on your Intel box. If so, that means that the problem is unique to your Intel Mac.
  • If not, I might again suggest that you create your own MRE that does manifest the problem, and upload it somewhere so we can try it out. Again, the goal is to identify what particular combination of settings are leading to the problem.

All of this having been said, there are some interesting edge cases:

  1. Might you have some other toolchain installed on your Intel box? Double check that you are using the standard toolchain for your Xcode version. (If you have never used multiple toolchains on your machine, ignore this observation; unfortunately Xcode has a weird UX that you see the toolchains UI only if you have multiple toolchains installed. Argh.)

  2. Are you 100% sure that you are changing the build settings for your target? For example, if the target in question has a override “Default Actor Isolation” setting of “nonisolated”, changing the project’s associated setting will not change this. (You can tell if the target has an override of a build setting by seeing whether it appears in bold or not. If you do have a target override build setting, you can select that build setting and press the delete button, at which point it will fall back to the project’s build settings. If you do this, the target build setting will no longer be in bold.)

  3. Does your project have more than one target/scheme, perhaps with different build settings?

    E.g., when I had rendition of the above MRE with two targets, one with a “Default Actor Isolation” build setting of “nonisolated” and another with “MainActor”, I would get the “Static property '…' is not concurrency-safe…” warning in the IDE, despite working on an Xcode scheme for the “MainActor” target. (Note, I get the warning in the IDE, but not in my compilation errors.)

    FWIW, Xcode has never entirely gracefully handled the scenario of multiple targets & schemes.

If you could share a MRE, that would help narrow the problem down to project-build-settings vs Xcode configuration (or what have you).

(P.S. I might also suggest also emptying your “Derived Data” folder and restarting Xcode (or even rebooting the machine). More than once I have had unexplained behaviors that were addressed by this ritual. It’s unlikely to be the solution in this case, but is the “go to” advice where Xcode is behaving unexpectedly.)

Thank you, @robert.ryan

Multiple targets, yes; but I made sure that the new target had the correct settings. :confused:

However, your question inspired me to create a new project, with default settings (I did not touch any settings.)

Now all is good, even with the Swift Language Version set to Swift 5. :confused: :joy:

Thank you for helping me out; I really appreciate your generosity.

PS: Xcode has been the most nondeterministic tool I have ever used. :slight_smile:

Good, if you can still take it with humor. I have other thoughts which I will self-censor here.

1 Like