Deriving Trait for Deref Trait


#1

I currently have the following sort of architecture:

struct DynamicRustPlugin {
    underlying: Box<Trait>
    importantHandle: SomeType
}

Specifically, the importantHandle is some global dynamic library Rust plugin magic that ensures a host dynamic library isn’t closed while the Box<Trait> is loaded, and only one instance of a given shared object is loaded globally, per program, at a time. The struct itself isn’t really important other than its Drop and safety-by-existence qualities.

(Specifically, the Rust plugin has a #[no_mangle] new function that returns a Box<Trait> of a trait defined in a shared crate and the DynamicRustPlugin holds this trait object while ensuring the library it came from stays open. I don’t know if this is “officially” supported, but it works perfectly on every platform and build configuration/toolchain I’ve tested on and I’m using copious tests and CI to make sure it doesn’t break).

I have another collection further up that owns a Box<Trait> as well, since my plugin manager has multiple plugin options such as RPC as well, and for various reasons I can’t use generics, but due to this safety magic, it needs to hold DynamicRustPlugin as a trait object, not the Box<Trait> itself.

DynamicRustPlugin implements Deref<Target=Trait> and DerefMut<Target=Trait> and Trait itself doesn’t take self by move. It seems that the following rules hold:

* If `Trait` only requires immutable references, and a type implements `Deref<Target=impls Trait>`, it can trivially implement `Trait`
* If `Trait` requires mutable references (but not ownership), and a type implements `Deref<Target=impls Trait>` and `DerefMut`, it can trivially implement `Trait`

(Also, the compiler could, maybe, do magic to prevent two chained virtual function calls by automatically setting the vtable entry for the Box<DerefImplementer as Trait> to simply its Deref target’s vtable entry?)

Is there any reason there’s no way to #[derive] in this case? Are there obvious problems I’m missing? Just too niche of a situation to have been added/be worth adding? The only obvious problem I see is if it’s a common trait such as, e.g., Debug it would be ambiguous whether #[derive(Debug)] means the struct itself or the Deref to a Debug but there could easily be an attribute like #[derive_deref(Trait)] that does this.

It’s a bit tiresome implementing each method of a big trait just to do

 fn foo(&self) {
     self.underlying.foo()
 }

Each time.


#2

I think you’re talking about (easier) delegation. There have been some discussions on this, including a fairly recent one at https://internals.rust-lang.org/t/3-weeks-to-delegation-please-help/5742/37.