What's up with this latter syntax? Did I miss something? Is it a bug or by design?

struct S {
  var value: [Int] = []
  func foo(_: KeyPath<S, Int> = \.value.count) {}
  func bar(_: KeyPath<S, Int> = \value.count) {}
}

This code compiles just fine. It's also interesting because the latter syntax works as a short-hand form for this property wrapper.

@propertyWrapper
struct Derived<Root, Value> {
  var wrappedValue: Value {
    get { fatalError() }
    set { fatalError() }
  }
​
  let keyPath: ReferenceWritableKeyPath<Root, Value>
​
  init(_ keyPath: ReferenceWritableKeyPath<Root, Value>) {
    self.keyPath = keyPath
  }
​
  static subscript(
    _enclosingInstance instance: Root,
    wrapped wrappedKeyPath: ReferenceWritableKeyPath<Root, Value>,
    storage storageKeyPath: ReferenceWritableKeyPath<Root, Self>
  ) -> Value {
    get {
      instance[keyPath: instance[keyPath: storageKeyPath].keyPath]
    }
    set {
      instance[keyPath: instance[keyPath: storageKeyPath].keyPath] = newValue
    }
  }
}
​
​
class Parent: UIView {
  private let label = UILabel()
​
  @Derived(\label.text)
  var text: String?
}
​
let instance = Parent()
instance.text // nil
instance.text = "foo"

cc @Joe_Groff

1 Like

That looks like a bug to me.

3 Likes

Okay, I'll file a bug, it was too good to be true as a short-hand form. :smiley:

https://bugs.swift.org/browse/SR-12290

Hmm, I thought the parser would diagnose the missing period but it doesn't. It just parses the rest of the key path expression without diagnosing.

Another weird issue:
When I change your example of the usage of the Derived wrapper to include the . as such:

@Derived(\.label.text)

I get a compiler error: Type of expression is ambiguous without more context
But without the ., the code compiles just fine without any ambiguities.
Is this perhaps another bug?

I tested on Swift 5.1.3 (Xcode 11.3) and Swift 5.2 beta included in Xcode 11.4.

It seems like the context isn't taken into consideration for type inference. You can just add a type name for now I suppose.

1 Like

I don‘t think that‘s a bug though. If you completely desugar this property wrapper, there is no context that would provide the Root type. The computed property isn‘t directly connected to the stored property to infer its type from.

1 Like