When I try and use Property Wrappers in a Sendable class, I get the error: "Stored property '_name' of 'Sendable'-conforming class 'Foo' is mutable; this is an error in the Swift 6 language mode".
Sample code:
@propertyWrapper struct Uppercase {
private var str: String
var wrappedValue: String {
get { str }
set { self.str = str.uppercased() }
}
init(wrappedValue: String) {
self.str = wrappedValue.uppercased()
}
}
final public class Foo: Sendable {
@Uppercase var name = "Matt"
}
This error makes total sense, however, I wondered if there is any way (or any future proposal) to allow a property wrapper to be created with a constant synthesized wrapper variable?
i.e. rather than generate the wrapper as:
var _name: UpperCase
instead generate:
let _name: UpperCase
Without something like this, I imagine property wrappers are completely unusable in Swift 6 for Sendable classes.
Just to add to this post, I realised my example above was invalid for other reasons.
I've rewritten it to demonstrate the point better...
import Foundation
import os
@propertyWrapper final class Uppercase: Sendable {
private let str: OSAllocatedUnfairLock<String>
var wrappedValue: String {
get { str.withLock { $0 } }
set { str.withLock { $0 = newValue.uppercased() } }
}
init(wrappedValue: String) {
self.str = .init(initialState: wrappedValue.uppercased())
}
}
final public class Foo: Sendable {
// This compiles fine ok
let _name = Uppercase(wrappedValue: "Matt")
var name: String {
get { _name.wrappedValue }
set { _name.wrappedValue = newValue }
}
// This doesn't compile because the synthesized _name is mutable
@Uppercase var surname = "Holgate"
}
(also worth adding that I know that this is sort of an anti-pattern for locking in property wrappers, but it's kind of valid for the case I am using I think).