-
Notifications
You must be signed in to change notification settings - Fork 1.6k
RFC: Exhaustive traits. Traits that enable cross trait casting between trait objects. #3885
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
base: master
Are you sure you want to change the base?
Conversation
…haustive' trait is static edited comment to be less vague
|
We could avoid Rule 1 by building the vtable lookup table externally in As |
|
I made another RFC: #3888. If that lands, rather than having every trait object being forced to store metadata for casting, there could be a trait Castable: 'static {
const self EXHAUSTABLE_IMPLEMENTATIONS: &'static [(TypeId, TraitVTable)];
}which could have a blanket implementation of: impl<T: 'static> Castable for T {
const self EXHAUSTABLE_IMPLEMENTATIONS: &'static [(TypeId, TraitVTable)] = std::intrinsics::exhausive_implementations::<T>();
}Which would make the metadata for casting opt in Though this will require a good chunk of changes to the It would be ideal to make this Of course we can do compiler magic, and make the |
This RFC proposes #[exhaustive] traits to enable sound cross-trait casting for trait objects.
For any concrete type T, the set of #[exhaustive] traits it implements is finite and deterministic, allowing runtime checks like “if this dyn A also implements dyn B, cast and use it.”
The design adds a per-type exhaustive trait→vtable map and enforces four rules (type-crate ownership of implementation, trait arguments determined by Self, object safe, and 'static only) to keep the mapping coherent under separate compilation.
Use cases include capability-based game entities (e.g., Damageable, Walkable traits) and GUI widgets (e.g., Clickable, Scrollable),
avoiding manual registry/macro approaches such as bevy_reflect.
This enables patterns such as: "if dyn Character is dyn Flyable, then character.fly()"
Rendered