We recently added code that can flatten optionals in a couple of ways, but because these methods weren't disfavored, they take precedence and can produce case key paths incapable of expressing what you want, like the ability to embed an optional in an case that contains one:
@CasePathable
enum Foo {
case bar(Int?)
}
let kp = \Foo.Cases.bar // CaseKeyPath<Foo, Int>, not <Foo, Int?>
kp(nil) // 'nil' is not compatible with expected argument type 'Int'
This PR disfavors these overloads to allow you to flatten optionals contextually, but by default will leave them alone.
It also fixes a bug in PartialCaseKeyPath.callAsFunction that would prevent non-optionals from being promoted to optionals in cases that expect them:
Finally, this PR fixes a bug in which PartialCaseKeyPath.callAsFunction was technically available on CaseKeyPath, which meant you could call it with any value:
let kp = \Foo.Cases.bar
// Before:
kp("Hello") // nil
// After:
kp("Hello") // Cannot convert value of type 'String' to expected argument type 'Int?'
We recently added code that can flatten optionals in a couple of ways, but because these methods weren't disfavored, they take precedence and can produce case key paths incapable of expressing what you want, like the ability to embed an optional in an case that contains one:
This PR disfavors these overloads to allow you to flatten optionals contextually, but by default will leave them alone.
It also fixes a bug in
PartialCaseKeyPath.callAsFunction
that would prevent non-optionals from being promoted to optionals in cases that expect them:Finally, this PR fixes a bug in which
PartialCaseKeyPath.callAsFunction
was technically available onCaseKeyPath
, which meant you could call it with any value: