I like the pattern of an interface trait that reference counts self
, like so:
trait MyTrait {
fn clone_one_or_create(self: &Arc<Self>, other: &Arc<dyn MyTrait>) -> Arc<dyn MyTrait>;
}
With support only for "single indirections" like Arc<Self>
, the closest pattern now is cloning the object before every method call, a.clone().foo()
, which is bad for readability and makes a lot of needless atomic increment/decrement calls.
I found the guidance that dynamic dispatch is impossible behind multiple indirections confusing, but accepted that it makes sense if dynamic dispatch from Arc<dyn Trait>
involves constructing something like a temporary Arc<T>
.
Now that I know about std::raw::TraitObject
layout and DispatchFromDyn
, though, it makes less sense, because all current implementations of DispatchFromDyn
don't create at temporary, the compiler just drops the metadata field and relabels the data as *mut ArcInner<()>
, or similar. This means that to dispatch from &Arc<dyn Trait>
, the compiler can just relabel the argument to *mut Arc<()>
: there isn't even any pointer arithmetic, because the data is the first field in the trait object.
@kennytm knew this more than two years ago: I wish I knew the right search terms to find this thread a while ago!
Is implementation of DispatchFromDyn
for &Box<T>
, &Rc<T>
, and &Arc<T>
already being planned? I think it would be really useful.