swiftlang / swift

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

[SR-12506] Property shouldn't expose its wrapper type #54948

Open 05109ee7-7cd9-4cd4-92d0-698e676fc6af opened 4 years ago

05109ee7-7cd9-4cd4-92d0-698e676fc6af commented 4 years ago
Previous ID SR-12506
Radar rdar://problem/62201608
Original Reporter @an0
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, PropertyWrappers | |Assignee | None | |Priority | Medium | md5: d33a32abb221da545423d25b55f9ff7a

Issue Description:

Property wrapper is an implementation detail of the property, i.e., for a property declared as

@Wrapper var a: Int

only this part of information should be exposed:

var a: Int

So @Wrapper's access level should not be tied to `a`'s access levels. However, currently the compiler forces this tie, and reports this error:

"Property must be declared private because its property wrapper type uses a private type"

for this code:

class Prefs: NSObject {
    private static var defaults: [String: Any] = [:]

    @propertyWrapper
    private struct UserDefaults<T> {

        let key: String
        let defaultValue: T

        init(key: String, defaultValue: T) {
            self.key = key
            self.defaultValue = defaultValue
        }

        var wrappedValue: T {
            get {
                defaults[key] as? T ?? defaultValue
            }
            set {
                defaults[key] = newValue
            }
        }

    }

    // Why do I need to expose wrapper type? It is an implemention detail. All my API users see should be just "static var a: Int".
    @UserDefaults(key: "a", defaultValue: 0) static var a: Int
}
beccadax commented 4 years ago

@swift-ci create