compilation_guard/lib.rs
1use proc_macro::{self, TokenStream};
2
3/// Forces compilation to fail.
4///
5/// e.g.
6/// ```rust
7/// #![allow(unused_imports, dead_code)]
8///
9/// use compilation_guard::compilation_guard;
10/// #[cfg_attr(all(unstable, feature = "enable-macro"), derive(VeryExpensiveMacro))]
11/// #[cfg_attr(all(not(unstable), feature = "enable-macro"), compilation_guard("lol"))]
12/// struct A;
13///
14/// fn main() {
15///
16/// }
17/// ```
18///
19/// If you don't enable the unstable flag, you get this.
20/// ```
21/// error: custom attribute panicked
22/// --> src/main.rs:5:58
23/// |
24/// 5 | #[cfg_attr(all(not(unstable), feature = "enable-macro"), compilation_guard("lol"))]
25/// | ^^^^^^^^^^^^^^^^^^^^^^^^
26/// |
27/// = help: message: Compilation guard was triggered!
28/// lol
29/// ```
30///
31#[proc_macro_attribute]
32pub fn compilation_guard(input: TokenStream, _: TokenStream) -> TokenStream {
33 panic_logic(input);
34 unreachable!()
35}
36
37fn panic_logic(input: TokenStream) {
38 let mut iter = input.into_iter();
39 match (iter.next(), iter.next()) {
40 (Some(proc_macro::TokenTree::Literal(literal)), None) => {
41 let s = literal.to_string();
42 let s = format!("Compilation guard was triggered!\n{}", &s[1..s.len()-1]);
43 panic!("{s}");
44 }
45 _ => panic!("This macro is expected to receive a `literal` as an argument.")
46 }
47}