SE-0252: Key Path Member Lookup

Take the example with storageValue from the property delegate proposal. I think the pitched idea of storageValue should be revisited as it‘s too magical and as @jrose pointed out in the other thread it shadows the property delegate type itself, which on the other hand makes it a perfect candidate for key-path lookup.

https://github.com/DougGregor/swift-evolution/blob/property-delegates/proposals/NNNN-property-delegates.md

protocol Copyable: AnyObject {
  func copy() -> Self
}

@propertyDelegate
@dynamicMemberLookup
struct CopyOnWrite<Value: Copyable> {
  init(initialValue: Value) {
    value = initialValue
  }
  
  private(set) var value: Value
  
  var storageValue: Value {
    mutating get {
      if !isKnownUniquelyReferenced(&value) {
        value = value.copy()
      }
      return value
    }
    set {
      value = newValue
    }
  }

  subscript<T>(dynamicMember keyPath: WritableKeyPath<Value, T>) -> T {
    get { return storageValue[keyPath: keyPath] }
    set { storageValue[keyPath: keyPath] = newValue } 
  }
}
class StorageManager {
  func allocate<T>(_: T.Type) -> UnsafeMutablePointer<T> { ... }
}

@propertyDelegate
@dynamicMemberLookup
struct LongTermStorage<Value> {
  let pointer: UnsafeMutablePointer<Value>

  init(manager: StorageManager, initialValue: Value) {
    pointer = manager.allocate(Value.self)
    pointer.initialize(to: initialValue)
  }

  var value: Value {
    get { return pointer.pointee }
    set { pointer.pointee = newValue }
  }

  var storageValue: UnsafeMutablePointer<Value> {
    return pointer
  }

  subscript<T>(
    dynamicMember keyPath: WritableKeyPath<UnsafeMutablePointer<Value>, T>
  ) -> T {
    get { return storageValue[keyPath: keyPath] }
    set { storageValue[keyPath: keyPath] = newValue } 
  }
}