[−][src]Module proc_macro_error::dummy 
Facility to emit dummy implementations (or whatever) in case an error happen.
compile_error! does not abort a compilation right away. This means
rustc doesn't just show you the error and abort, it carries on the
compilation process looking for other errors to report.
Let's consider an example:
use proc_macro::TokenStream; use proc_macro_error::*; trait MyTrait { fn do_thing(); } // this proc macro is supposed to generate MyTrait impl #[proc_macro_derive(MyTrait)] #[proc_macro_error] fn example(input: TokenStream) -> TokenStream { // somewhere deep inside abort!(span, "something's wrong"); // this implementation will be generated if no error happened quote! { impl MyTrait for #name { fn do_thing() {/* whatever */} } } } // ================ // in main.rs // this derive triggers an error #[derive(MyTrait)] // first BOOM! struct Foo; fn main() { Foo::do_thing(); // second BOOM! }
The problem is: the generated token stream contains only compile_error!
invocation, the impl was not generated. That means user will see two compilation
errors:
error: something's wrong
 --> $DIR/probe.rs:9:10
  |
9 |#[proc_macro_derive(MyTrait)]
  |                    ^^^^^^^
error[E0599]: no function or associated item named `do_thing` found for type `Foo` in the current scope
 --> src\main.rs:3:10
  |
1 | struct Foo;
  | ----------- function or associated item `do_thing` not found for this
2 | fn main() {
3 |     Foo::do_thing(); // second BOOM!
  |          ^^^^^^^^ function or associated item not found in `Foo`
But the second error is meaningless! We definitely need to fix this.
Most used approach in cases like this is "dummy implementation" -
omit impl MyTrait for #name and fill functions bodies with unimplemented!().
This is how you do it:
use proc_macro::TokenStream; use proc_macro_error::*; trait MyTrait { fn do_thing(); } // this proc macro is supposed to generate MyTrait impl #[proc_macro_derive(MyTrait)] #[proc_macro_error] fn example(input: TokenStream) -> TokenStream { // first of all - we set a dummy impl which will be appended to // `compile_error!` invocations in case a trigger does happen set_dummy(quote! { impl MyTrait for #name { fn do_thing() { unimplemented!() } } }); // somewhere deep inside abort!(span, "something's wrong"); // this implementation will be generated if no error happened quote! { impl MyTrait for #name { fn do_thing() {/* whatever */} } } } // ================ // in main.rs // this derive triggers an error #[derive(MyTrait)] // first BOOM! struct Foo; fn main() { Foo::do_thing(); // no more errors! }
Functions
| append_dummy | Same as [ | 
| set_dummy | Sets dummy token stream which will be appended to  |