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]
72macro_rules! assert_obj_safe {
73 ($($xs:path),+ $(,)?) => {
74 $(const _: Option<&$xs> = None;)+
75 };
76}
77