While working with low-level code for a sort of linked list, I found myself accessing .pointee
a lot. Enough that I wanted an abbreviation for it. Since prefix func *
wouldn't work the way it does in C (it would be read-only), I wrote a propertyWrapper instead:
@propertyWrapper struct PointerWrapped<T> {
var wrappedValue: UnsafeMutablePointer<T>
var projectedValue: T {
_read {
yield wrappedValue.pointee
}
nonmutating set {
wrappedValue.pointee = newValue
}
nonmutating _modify {
yield &wrappedValue.pointee
}
}
}
However, I then quickly found myself wanting to do this:
if @PointerWrapped var next = $node.next {
// ...
}
To my surprise, this doesn't even parse, and gives a rather generic error message ("expected expression, var, or let in 'if' condition"). It's fairly trivial to work around:
if let next = $node.next {
@PointerWrapped var next = next
// ...
}
But I'm surprised that I have to.
Why isn't this permitted? If it can be implemented as a fairly trivial transformation in the frontend, is there a deeper reason to discourage this in general? Or is it just a matter of "no use case was presented"?
I'll note that while the transformation is trivial for if let
and while let
, it's more involved for guard let
, but only due to a frontend restriction in variable naming:
guard let next = $node.next else { return }
@PointerWrapped var next = next // invalid redeclaration of next