(background: I am trying to reimplement something I have a decent grasp on from earlier, (in a very different language), so it's not all vibes)
What I want to make is a graph of objects with references to other objects, because that's what makes sense when you're dealing with the actual objects, which is what I want to be the focus. (e.g. Bike
-> Frame
-> SeatPost
... )
The problem comes in when I have (potentially) conflicting design goals:
- The object graph needs to be iterable as
dyn T
:s (ok) - Concrete object types can just have other objects. (ok)
- Adding concrete object types should be possible without changing the core (so it can be in crate of its own) (ok)
- I need to be able to tell if two objects are the same or not (?)
- Concrete object type implementations should not have to worry too much about the graph implementation details. (not really ok rn, but possibly manageable)
Where I am now is using Rc<dyn T>
to deal with the objects generically. This works, I have a topological sort iterator that is (while shockingly ugly) actually working. (afaict, anyway)
I've tried to read a bit about the problems of dyn reference pointer comparisons, but I don't feel much wiser.(*1) Do I need to have a trait method that returns a concrete type pointer, cast to * const ()
, or can it be done more elegantly? Is it even guaranteed to work?
A lot of the design issues I'm seeing seem to stem from the compiler's freedom to generate and/or merge vtable:s at will, rendering fat pointers nondeterministic.
In a similar vein, this can't be a default trait implementation, but it can be the same everywhere:
fn as_any_rc(self: Rc<Self>) -> Rc<dyn Any> {
self
}
This is needed because I can't just (thing as Rc<dyn Any>)
where I'd use that, because Tracking issue for dyn upcasting coercion #65991.
I could hide that in a derive macro, I guess, but it's starting to feel dodgy.
I'm all in favour of appeasing the Cosmic Horror of Compiler Chaos, because it gives us some very nice things, but the nihilism does seem to occasionally take away things I was hoping to use.
*1: