The standard library could provide this:
@dynamicMemberLookup
public struct UnsafePointer<Pointee> {
// ...as it is currently...
public subscript<NewPointee>(dynamicMember: ReferenceWritableKeyPath<Pointee, NewPointee>) -> UnsafeMutablePointer<NewPointee>? {
// standard library magic goes here--key path internals contain
// enough data to make this work for stored properties in structs and classes.
}
public subscript <NewPointee>(dynamicMember: KeyPath<Pointee, NewPointee>) -> UnsafePointer<NewPointee>? {
// The same, but immutable for immutable stored properties.
}
}
So that you could say this:
let personPtr: UnsafePointer<Person> = ...
let postalCodePtr: UnsafePointer<PostalCode>? = personPtr.address.postalCode
(The types in that example could be inferred—I'm just writing them out to clarify the semantics.)