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.
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.
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.
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.
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).
I've been bitten by this as well (In Xcode 26), and unsure how to proceed.
The property wrapper itself is Sendable ![]()
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)
}
}
Yet, it's not working with Strict Concurrency enabled.
getonly ornonmutating setproperty wrappers would have their backing storage defined with alet.
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?