Partial KeyPath - Switch not exhaustive

Hi,

I have a partial keypath and I would like to use a switch on it.

Question:

  1. Why is the switch statement not exhaustive, wouldn't the compiler know about all the possible properties of Car?. Am I missing something?
  2. Is there a way to do this without adding a default case or a better approach?
  3. Also noticed that in the case I had to mention \Car.price instead of \.price, I thought compiler would be able to infer. Am I missing something?

Code:

struct Car {
    var name : String
    var price : Double
}

func f1(partialKeyPath: PartialKeyPath<Car>) {
    
    switch partialKeyPath { //Error: Switch must be exhaustive

    case \Car.price:
        print("price")
    case \Car.name:
        print("name")
    }
}
extension Car {
  var heh: String { "heh" }
}
2 Likes

@Lantua Thanks a lot for the prompt response.

Oh you mean, I could have defined Car in my framework and it could be extended in the code that uses my framework?

Mainly because of computed properties in extensions?

Yes, you can form a valid keypath to those declared in extension.

The only way for it to be provable is to have Car in a very strict scope, e.g, private (I don’t know if there’s such checking). Even then, if Car conforms to public protocols, you could still form key paths to extensions of those protocols.

1 Like

Thanks a lot, I was breaking my head over it.

Protocol seems interesting, I didn't think that far. I tried with a protocol keypath still not exhaustive. I guess protocols could be extended too ... :D

Not sure why the root type in the case couldn't be inferred.

Keep in mind that I’m not saying there’s any exhaustive proof in this area. I’m only saying that, if there’s one, only those meeting these conditions (is non-public, and not conforming to public protocols like Equatable) would be eligible.

1 Like

Thanks @Lantua I didn't read your post carefully... I think I will return an optional and handle at the call site.

Thanks a lot for patiently answering my doubts.

1 Like

You can also use default inside switch if most other handles fits the bill with switch.

1 Like

Thanks @Lantua , I think the default option would reduce the if let / guard handling at the call site.

Even if there are no more properties added by the extensions, you there are still more keypaths than these two, for example:

f1(partialKeyPath: \Car.name.count as PartialKeyPath<Car>)
4 Likes

Thanks a lot @cukr I completely forgot about properties each of them could have.

Looks like I definitely need to handle the default case.