carlhung
(Carlhung)
1
@propertyWrapper
final class Wrapper<T> {
final class InnerWrapper {
let val: T
init(val: T) {self.val = val}
}
var storedValue: InnerWrapper
var projectedValue: InnerWrapper {
storedValue
}
var wrappedValue: T {
self.storedValue.val
}
init(wrappedValue: T) {
self.storedValue = InnerWrapper(val: wrappedValue)
}
init(projectedValue: Wrapper) {
self.storedValue = projectedValue.storedValue
}
}
in a type's body, it works fine:
class Base {
@Wrapper // It works fine.
var x = 0
func run() {
let y = x
// foo(val: $x)
}
}
when using it on a function, I got an error:
cannot convert value of type 'Wrapper<T>.InnerWrapper' to expected argument type 'Wrapper<T>'
func foo<T>(@Wrapper val: T) {}
I think it is a bug??
It might be a bug. But does it matter? The reason you're seeing it is because your projectedValue labeling is inaccurate.
There are two ways to solve it:
- Don't use the argument label
projectedValue.
init(_ projectedValue: Wrapper) {
storedValue = projectedValue.storedValue
}
- Don't use the obfuscation of
storedValue, which isn't doing anything useful.
var wrappedValue: T { projectedValue.val }
var projectedValue: InnerWrapper
init(wrappedValue: T) {
projectedValue = .init(val: wrappedValue)
}
init(_ wrapper: Wrapper) {
projectedValue = wrapper.projectedValue
}
hborla
(Holly Borla)
3
The error message is not helpful, but the error is because your init(projectedValue) accepts the wrapper type instead of the projected value type. This fixes the problem:
@propertyWrapper
final class Wrapper<T> {
final class InnerWrapper {
let val: T
init(val: T) {self.val = val}
}
var storedValue: InnerWrapper
var projectedValue: InnerWrapper {
storedValue
}
var wrappedValue: T {
self.storedValue.val
}
init(wrappedValue: T) {
self.storedValue = InnerWrapper(val: wrappedValue)
}
init(projectedValue: InnerWrapper) {
self.storedValue = projectedValue
}
}
func foo<T>(@Wrapper val: T) {}
It's worth filing a bug Issues · apple/swift · GitHub to improve the error message!
1 Like