| 1 | // FIXME: Link below is required to render in index | 
| 2 | /// Asserts that the traits support dynamic dispatch | 
|---|
| 3 | /// ([object-safety](https://doc.rust-lang.org/book/ch17-02-trait-objects.html#object-safety-is-required-for-trait-objects)). | 
|---|
| 4 | /// | 
|---|
| 5 | /// This is useful for when changes are made to a trait that accidentally | 
|---|
| 6 | /// prevent it from being used as an [object]. Such a case would be adding a | 
|---|
| 7 | /// generic method and forgetting to add `where Self: Sized` after it. If left | 
|---|
| 8 | /// unnoticed, that mistake will affect crate users and break both forward and | 
|---|
| 9 | /// backward compatibility. | 
|---|
| 10 | /// | 
|---|
| 11 | /// # Examples | 
|---|
| 12 | /// | 
|---|
| 13 | /// When exposing a public API, it's important that traits that could previously | 
|---|
| 14 | /// use dynamic dispatch can still do so in future compatible crate versions. | 
|---|
| 15 | /// | 
|---|
| 16 | /// ``` | 
|---|
| 17 | /// # #[ macro_use] extern crate static_assertions; fn main() {} | 
|---|
| 18 | /// trait MySafeTrait { | 
|---|
| 19 | ///     fn foo(&self) -> u32; | 
|---|
| 20 | /// } | 
|---|
| 21 | /// | 
|---|
| 22 | /// assert_obj_safe!(std::fmt::Write, MySafeTrait); | 
|---|
| 23 | /// ``` | 
|---|
| 24 | /// | 
|---|
| 25 | /// Works with traits that are not in the calling module: | 
|---|
| 26 | /// | 
|---|
| 27 | /// ``` | 
|---|
| 28 | /// # #[ macro_use] extern crate static_assertions; fn main() {} | 
|---|
| 29 | /// mod inner { | 
|---|
| 30 | ///     pub trait BasicTrait { | 
|---|
| 31 | ///         fn bar(&self); | 
|---|
| 32 | ///     } | 
|---|
| 33 | ///     assert_obj_safe!(BasicTrait); | 
|---|
| 34 | /// } | 
|---|
| 35 | /// | 
|---|
| 36 | /// assert_obj_safe!(inner::BasicTrait); | 
|---|
| 37 | /// ``` | 
|---|
| 38 | /// | 
|---|
| 39 | /// The following example fails to compile because raw pointers cannot be sent | 
|---|
| 40 | ///  between threads safely: | 
|---|
| 41 | /// | 
|---|
| 42 | /// ```compile_fail | 
|---|
| 43 | /// # #[ macro_use] extern crate static_assertions; fn main() {} | 
|---|
| 44 | /// assert_impl!(*const u8, Send); | 
|---|
| 45 | /// ``` | 
|---|
| 46 | /// | 
|---|
| 47 | /// The following example fails to compile because generics without | 
|---|
| 48 | /// `where Self: Sized` are not allowed in [object-safe][object] trait methods: | 
|---|
| 49 | /// | 
|---|
| 50 | /// ```compile_fail | 
|---|
| 51 | /// # #[ macro_use] extern crate static_assertions; fn main() {} | 
|---|
| 52 | /// trait MyUnsafeTrait { | 
|---|
| 53 | ///     fn baz<T>(&self) -> T; | 
|---|
| 54 | /// } | 
|---|
| 55 | /// | 
|---|
| 56 | /// assert_obj_safe!(MyUnsafeTrait); | 
|---|
| 57 | /// ``` | 
|---|
| 58 | /// | 
|---|
| 59 | /// When we fix that, the previous code will compile: | 
|---|
| 60 | /// | 
|---|
| 61 | /// ``` | 
|---|
| 62 | /// # #[ macro_use] extern crate static_assertions; fn main() {} | 
|---|
| 63 | /// trait MyUnsafeTrait { | 
|---|
| 64 | ///     fn baz<T>(&self) -> T where Self: Sized; | 
|---|
| 65 | /// } | 
|---|
| 66 | /// | 
|---|
| 67 | /// assert_obj_safe!(MyUnsafeTrait); | 
|---|
| 68 | /// ``` | 
|---|
| 69 | /// | 
|---|
| 70 | /// [object]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#object-safety-is-required-for-trait-objects | 
|---|
| 71 | #[ macro_export] | 
|---|
| 72 | macro_rules! assert_obj_safe { | 
|---|
| 73 | ($($xs:path),+ $(,)?) => { | 
|---|
| 74 | $(const _: Option<&$xs> = None;)+ | 
|---|
| 75 | }; | 
|---|
| 76 | } | 
|---|
| 77 |  | 
|---|