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