Static property wrappers and strict concurrency in 5.10

While we wait for an officially sanctioned solution, I did a small package that implements @noremac’s workaround automatically using a macro: GitHub - Frizlab/SafeGlobal.

It looks like it works but I did only a limited testing of it.

1 Like

This is still an issue with Swift 6.0.
How are we supposed to deal with this when using property wrappers?

extension String {
  // Static property 'test' is not concurrency-safe because it is non-isolated global shared mutable state; this is an error in the Swift 6 language mode
  @PropertyWrapper
  public static var test
}

Of the 3 suggested fix-its, 2 of them lead to invalid code:

The only valid one is adding @MainActor, but that's not always a desirable option, users might not want to tie all accesses of a certain property to the main actor.

2 Likes

My understanding is: you can’t. On Fluent Models and Sendable warnings | The Vapor Blog

I went the macro route in my solution for this reason.

3rd option is valid as well, if you'll ensure at the level of PropertyWrapper safety (e.g. with locks), then use @PropertyWrapper nonisolated(unsafe) static var test.

It would be desirable to be able to express dynamic isolation in many cases, but it has to be defined unambiguously, so the compiler can reason about safety. If we assume that we'd have something like isolated(any) static var test, it is unclear how it would behave, as property can be accessed from any concurrency context right now, making this hypothetical isolated(any) useless.

1 Like

3rd option is valid as well,

Nope, it's not:

'nonisolated' is not supported on properties with property wrappers

That's odd and unfortunate, I haven't found any notion either in proposal or in review/pitch threads that this unavailable for property wrappers.

I opened a thread about it here - Using nonisolated with wrapped properties

But I think we need [Pitch] Allow Property Wrappers on Let Declarations to be implemented first and then you should be able to add nonisolated to a wrapped property (assuming it’s declared as a let).

3 Likes

I've been bitten by this as well (In Xcode 26), and unsure how to proceed.

  1. You can't change property-wrapped things to a let
  2. You can't make propert-wrapped things non-isoalted
  3. @MainActor doesn't work here either.

The property wrapper itself is Sendable :thinking:

Anyone has smart suggestions?

I think you have to not use property wrappers. Using macros instead, you should be able to do something that works.

Adding my two-cents here!

I have this simple property wrapper:

/// A property wrapper that allows access to a Sample File.
/// Before the file is accessed, it's first copied into it's on mutable copy so we don't affect any other tests.
@propertyWrapper
public struct SampleFile: Sendable {

    private let fileName: String

    init(fileName: String) {
        self.fileName = fileName
    }

    public var wrappedValue: Data {
        let file = fileName.split(separator: ".").first!
        let fileExtension = fileName.split(separator: ".").last!
        let url = Bundle.module.url(forResource: String(file), withExtension: String(fileExtension))!
        return try! Data(contentsOf: url)
    }
}
  • It's nonmutating
  • It's Sendable

Yet, it's not working with Strict Concurrency enabled.

  • nonisolated(unsafe) does not work with Property Wrappers
  • The compiler is still not smart enough to do:
  • get only or nonmutating set property wrappers would have their backing storage defined with a let.

That would solve this and sounds like a reasonable way forward.

But how about Macros?
Well, yes, that would solve it. Honestly, I can very easily rewrite the above example as well. However, Macros are more complicated to create compared to property wrappers and if this is the way forward, I feel like we should consider property wrappers to be deprecated or such since I don't see a way now to make them work with Strict Concurrency.

I'd love to get some more thoughts on this and the current state.

@Douglas_Gregor what is your vision on Property Wrappers and Strict Concurrency?

6 Likes