Objective-C available property not available via protocol extension

The following code has a fatal runtime error Could not extract a String from KeyPath Swift.KeyPath<Foo, Foundation.UUID>.

import Foundation

final class Foo: NSObject, Protocol, Identifiable {
  @objc
  let id: UUID

  override init() {
    id = UUID()
    super.init()
  }
}

protocol Protocol {}

extension Protocol where Self: Identifiable {
  static func fatal() {
    let expression = NSExpression(forKeyPath: \Self.id)
    print(expression)
  }
}

// Works
let works = NSExpression(forKeyPath: \Foo.id)
print(works)

// Fatal error
Foo.fatal()

I feel like this is a bug since Foo definitely makes id available to the Objective-C code base (through @objc). But perhaps I am just being too cute with the language for my own good.

Thoughts/help?

Here's another version of it with a different error message without all the protocol indirection.

import Foundation

final class Foo: NSObject {
  @objc
  let id: UUID

  override init() {
    id = UUID()
    super.init()
  }
}

extension Foo {
  static func fatal() {
    let expression = NSExpression(forKeyPath: \Self.id)
    print(expression)
  }

  static func works() {
    let expression = NSExpression(forKeyPath: \Foo.id)
    print(expression)
  }
}

// Works
let works = NSExpression(forKeyPath: \Foo.id)
print(works)

// Works
Foo.works()

// Fatal error
Foo.fatal()

could not demangle keypath type from '�

Terms of Service

Privacy Policy

Cookie Policy