links: Object Safety
Object safety is an important concept in Rust when working with trait objects. A trait is considered object safe if it meets certain criteria that allow it to be used as a trait object, enabling polymorphism. Here’s a summary of the key points on object safety from the official Rust documentation:
Definition:
Object Safety Rules:
Self Type in Methods: Methods in the trait must not have a Self type in their signatures, except for the receiver. This means you can't use methods that return Self or have Self as a parameter.
trait NotObjectSafe {
fn foo(&self) -> Self; // This is not allowed
}
Generic Methods: Methods that have generic type parameters are not allowed in object-safe traits.
trait NotObjectSafe {
fn foo<T>(&self, x: T); // This is not allowed
}
Sized: The trait must not require Self: Sized because trait objects are dynamically sized.
trait ObjectSafe: Sized {} // This is not allowed
Receiver Types:
&self&mut selfself (but not Self: Sized)Examples of Object-Safe Traits:
trait ObjectSafe {
fn foo(&self);
fn bar(&mut self);
fn baz(self: Box<Self>);
}
Non-Object-Safe Traits:
trait NotObjectSafe {
fn foo(&self) -> Self; // Returns Self
fn bar<T>(&self, x: T); // Has generic parameters
}
dyn Trait).Object safety ensures that traits can be turned into trait objects, enabling dynamic dispatch. The key rules are avoiding Self in method signatures (except as a receiver), not having generic methods, and ensuring the trait does not require Self: Sized. These constraints are crucial for enabling polymorphism in Rust.
For a more detailed explanation and examples, refer to the official Rust documentation on object safety.