-
Notifications
You must be signed in to change notification settings - Fork 184
Bug: #Predicate macro incorrectly fails for ‘final’ classes #1173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think this and #1174 are both a symptom of The real solution is that now that swiftlang/swift#70451 is merged, we should start using the |
@jmschonfeld Ah, that might explain why the behavior is intermittent depending on how many (and what kind) of properties a class has. Glad to hear there's an idea for a workaround. |
Slightly unrelated, but is it possible to consider a design that eliminates this restriction altogether? That is, could Context:MongoDB recently killed Realm, which is why I’m now forced to build a new data framework on top of Couchbase, which offers a multi-user, offline-first sync. Realm’s “Swift Query Syntax” was magical. It was concise and allowed easily navigating relationships. The closures below got rewritten to
This would be a LOT more work than merely fixing the |
In a future world where we have a lot more APIs around
If in the future we had robust APIs for enumerating the components of a keypath and splitting a keypath into multiple key paths representing each component then perhaps it could be possible since then the implementation of |
@jmschonfeld Ah; makes sense. I've likewise found I guess replacing |
I'm not sure what defines a "multi-component" KeyPath. For example, I was surprised to see that this works:
The predicate ran fine, filtered a Collection, etc. But before I build a whole framework on top of this, I'd like to verify that this is indeed valid and not just a false-negative from Or is "multi-component" something more convoluted like: |
That predicate is indeed valid, but that's due to how the predicate macro handles key paths. Rather than turning |
Summary
I've discovered that Foundation's
#Predicate
fails when a class is marked asfinal
. Here's a very simple test case:That expands to:
It compiles correctly, but at runtime crashes on the
build_KeyPath
line:Thread 1: Fatal error: Predicate does not support keypaths with multiple components
This is obviously not correct; there is only one component in the KeyPath. If you remove
final
from the class declaration, it works fine.I see where this check exists in Foundation (
swift-foundation/Sources/FoundationEssentials/Predicate/KeyPath+Inspection.swift
Lines 50 to 88 in 2f4f5b8
final
should affect whether aUUID
property has an offset.Any Value
The behavior is not limited to
UUID
. I can reproduce it with aString
,Int
, and other values.Speculation
I can’t find any information on how the presence of
final
affects the memory layout of a class such thatoffset(of:)
would fail. I thought maybe the issue affects only types that are capable of storing their value without allocation (i.e. tagged pointers), but again I can’t see howfinal
would affect that.Intermittent
IF a class has a certain combination of properties, this issue does not always manifest. For example, Predicates ran just fine here:
But add
var id: UUID = UUID()
and that fails untilfinal
is removed. Given theoffset(of:)
check, I figured the issue might have something to do with the exact way properties are aligned and packed into the storage for the class. But that’s just a guess.Environment
Xcode 16.2.
Since
#Predicate
isn’t available in Playgrounds, I created a new project from the “command line application” template in Xcode. I changed no build settings.The text was updated successfully, but these errors were encountered: