Expand description
An attribute macro that generates methods for retrieving supertraits from trait-objects (upcasting).
If you have a trait with a supertrait, you sometimes want to upcast a trait object. Rust currently does not support this.
trait Super {}
trait Sub: Super {}
fn wants_upcast(sub: Box<dyn Sub>) {
let s: Box<dyn Super> = sub;
// do something with super.
}This results in the following error:
error[E0308]: mismatched types
--> src/lib.rs:27:29
|
8 | let s: Box<dyn Super> = sub;
| -------------- ^^^ expected trait `Super`, found trait `Sub`
| |
| expected due to this
|
= note: expected struct `std::boxed::Box<dyn Super>`
found struct `std::boxed::Box<(dyn Sub + 'static)>`
error: aborting due to previous errorThe as_dyn_trait attribute solves this problem:
#[as_dyn_trait]
trait Super {}
trait Sub: Super {}
fn wants_upcast(sub: Box<dyn Sub>) {
// s has type Box<dyn Super>.
let s = sub.as_dyn_super();
// do something with super.
}To achieve this, the macro generates several traits. For a trait MyTrait, the names of these
traits and their methods are:
AsDynMyTraitRef:fn as_dyn_my_trait(&self) -> &dyn MyTrait;fn as_dyn_my_trait_mut(&mut self) -> &mut dyn MyTrait;
AsDynMyTraitBox:fn as_dyn_my_trait(self: Box<Self>) -> Box<dyn MyTrait>;
AsDynMyTraitRc:fn as_dyn_my_trait(self: Rc<Self>) -> Rc<dyn MyTrait>;
AsDynMyTraitArc:fn as_dyn_my_trait(self: Arc<Self>) -> Arc<dyn MyTrait>;
AsDynMyTraitPinRef:fn as_dyn_my_trait(self: Pin<&Self>) -> Pin<&dyn MyTrait>;fn as_dyn_my_trait_mut(self: Pin<&mut Self>) -> Pin<&mut dyn MyTrait>;
AsDynMyTraitPinBox:fn as_dyn_my_trait(self: Pin<Box<Self>>) -> Pin<Box<dyn MyTrait>>;
AsDynMyTraitPinRc:fn as_dyn_my_trait(self: Pin<Rc<Self>>) -> Pin<Rc<dyn MyTrait>>;
AsDynMyTraitPinArc:fn as_dyn_my_trait(self: Pin<Arc<Self>>) -> Pin<Arc<dyn MyTrait>>;
These traits are automatically implemented for all Sized types that implement MyTrait. If you
want to implement MyTrait for dynamically sized types, you need to do add these implementations manually.
Since you cannot turn a DST into a trait object, such an implementation must always panic.
In order for those traits to work on trait objects, all of them are automatically supertraits of MyTrait.
The attribute supports several options. The options are passed to the attribute as a comma-separated list:
#[as_dyn_trait(enable_pin = true, trait_name_prefix = DifferentName)]
trait Super {}trait_name_prefix: The prefix to use for the generated traits. Default isAsDynfollowed by the trait name.ref_trait_name: The name of the trait for references. Default is the trait name prefix withRefappended.box_trait_name: The name of the trait forBox<_>. Default is the trait name prefix withBoxappended.rc_trait_name: The name of the trait forRc<_>. Default is the trait name prefix withRcappended.arc_trait_name: The name of the trait forArc<_>. Default is the trait name prefix withArcappended.pin_ref_trait_name: The name of the trait for Pin<_> references. Default is the trait name prefix withPinRefappended.pin_box_trait_name: The name of the trait forPin<Box<_>>. Default is the trait name prefix withPinBoxappended.pin_rc_trait_name: The name of the trait forPin<Rc<_>>. Default is the trait name prefix withPinRcappended.pin_arc_trait_name: The name of the trait forPin<Arc<_>>. Default is the trait name prefix withPinArcappended.method_name: The name of the conversion method. Default is theas_dyn_followed by the trait name (converted to lower-snake-case).mut_method_name: The name of the conversion method for mutable references. Default is theas_dyn_followed by the trait name (converted to lower-snake-case) and_mut.enable_ref: Enables conversion of references. Default is true.enable_box: Enables conversion ofBox<_>. Default is true.enable_rc: Enables conversion ofRc<_>. Default is true.enable_arc: Enables conversion ofArc<_>. Default is true.enable_pin: Enables conversion of thePin<_>types. These are only generated conversion of the corresponding base pointer is also enabled. Default is false.
This attribute does not use or generate any unsafe code.
Attribute Macros§
- as_
dyn_ trait - Generates methods for retrieving trait objects of supertraits from trait objects of subtraits.