Reputation: 5700
I'm attempting to create a Swift Predicate using the #Predicate
macro as shown here:
final class Foo
{
var title: String = ""
var name: String = ""
}
let p = #Predicate<Foo> { $0.title == "test" }
This compiles fine, but at runtime crashes with this:
Foundation/KeyPath+Inspection.swift:65: Fatal error: Predicate does not support keypaths with multiple components
Here's what the macro expands to, according to Xcode:
Foundation.Predicate<Foo>({
PredicateExpressions.build_Equal(
lhs: PredicateExpressions.build_KeyPath(
root: PredicateExpressions.build_Arg($0),
keyPath: \.title
),
rhs: PredicateExpressions.build_Arg("test")
)
})
Why? I've seen some discussion threads where this error message pops up when an optional is involved in a KeyPath, but that's not the case here. And there's not multiple components.
(I'm looking to parse Predicate expressions to convert them into custom database query statements, but I can't even get a dead-simple predicate to actually exist without crashing.)
Upvotes: 0
Views: 39
Reputation: 5700
Removing final
before the class declaration solves the issue.
// Works:
class Foo {
var title: String = ""
}
// Crashes:
final class Foo {
var title: String = ""
}
I noticed that THIS worked just fine:
@Model
final class Foo {
var title: String = ""
}
let p = #Predicate<Foo> { $0.title == "test" } // No crash
All the @Model
macro really does is rewrite the class into fancy computed properties, so I gave this a shot and found that it also works fine:
final class Foo {
var title: String {
return ""
}
}
let p = #Predicate<Foo> { $0.title == "test" } // No crash
But if you use the final
keyword and attempt to create a KeyPath Predicate to a stored property of that class, it crashes.
That has to be a bug. The docs for Predicate
make no mention of limitations for static dispatch. If this is somehow expected behavior, the nonsensical "multiple components in keyPath" error message is entirely misleading. Hopefully this can save someone else the hours I've wasted.
Upvotes: 0