Macro static_assertions::assert_obj_safe
source · macro_rules! assert_obj_safe { ($($xs:path),+ $(,)?) => { ... }; }
Expand description
Asserts that the traits support dynamic dispatch (object-safety).
This is useful for when changes are made to a trait that accidentally
prevent it from being used as an object. Such a case would be adding a
generic method and forgetting to add where Self: Sized
after it. If left
unnoticed, that mistake will affect crate users and break both forward and
backward compatibility.
§Examples
When exposing a public API, it’s important that traits that could previously use dynamic dispatch can still do so in future compatible crate versions.
trait MySafeTrait {
fn foo(&self) -> u32;
}
assert_obj_safe!(std::fmt::Write, MySafeTrait);
Works with traits that are not in the calling module:
mod inner {
pub trait BasicTrait {
fn bar(&self);
}
assert_obj_safe!(BasicTrait);
}
assert_obj_safe!(inner::BasicTrait);
The following example fails to compile because raw pointers cannot be sent between threads safely:
assert_impl!(*const u8, Send);
The following example fails to compile because generics without
where Self: Sized
are not allowed in object-safe trait methods:
trait MyUnsafeTrait {
fn baz<T>(&self) -> T;
}
assert_obj_safe!(MyUnsafeTrait);
When we fix that, the previous code will compile:
trait MyUnsafeTrait {
fn baz<T>(&self) -> T where Self: Sized;
}
assert_obj_safe!(MyUnsafeTrait);