I\'ve got this simplified Rust code:
use std::io::Result;
pub trait PacketBuffer {}
pub trait DnsRecordData {
fn write(&self
The error comes from the fact that you can't create trait objects for DnsRecordData
due to the trait not being "object-safe". This concept is explained in the trait objects section of The Rust Programming Language.
In your particular case, the trait contains a generic method. To create a trait object, the compiler has to synthesize a vtable for the trait, containing a function pointer for every method the trait has. But because the trait has a generic method, it effectively has as many methods as the method could be instantiated with, which is potentially infinite. Therefore, you cannot make a trait object for DnsRecordData
.
The intention is that
DnsRecord
should be able to hold any struct implementing theDnsRecordData
trait
That's not what the code says.
Vec<DnsRecord<dyn DnsRecordData>>
This is a vector of the struct DnsRecord
containing the trait DnsRecordData
. If you want "any struct implementing the DnsRecordData
trait", you need a generic:
pub struct DnsPacket<D>
where
D: DnsRecordData,
{
pub answers: Vec<DnsRecord<D>>,
}
Traits can be implemented, but they also have their own type. In order to create this type, the trait needs to be object-safe - Trait Object is not Object-safe error.
As the error message states, this trait cannot be a trait object because there are generic types on the method.
The first error states that DnsRecord
requires that whatever type it is parameterized with must implement DnsRecordData
. However, the type of the trait object doesn't actually implement that. Normally, you'd use a trait object via a reference (&dyn DnsRecordData
) or a box (Box<dyn DnsRecordData>
), both of which should implement the trait, preventing this error.