proc-macro-error
This crate aims to make error reporting in proc-macros simple and easy to use.
Migrate from panic!
-based errors for as little effort as possible!
Also, there's ability to [append a dummy token stream][dummy] to your errors.
Enticement
Your errors look like this?
error: proc-macro derive panicked
--> $DIR/bool_default_value.rs:11:10
|
11 | #[derive(StructOpt, Debug)]
| ^^^^^^^^^
|
= help: message: default_value is meaningless for bool
But you would like it to be like this!
error: default_value is meaningless for bool
--> $DIR/bool_default_value.rs:14:24
|
14 | #[structopt(short, default_value = true)]
| ^^^^^^^^^^^^^
This is exactly what this crate is built for!!!
Usage
Panic-like usage
#
#
#
#
#
use *;
use TokenStream;
use ;
use quote;
# static _IGNORE: &str = "
// This is your main entry point
#[proc_macro]
// this attribute *MUST* be placed on top of the #[proc_macro] function
#[proc_macro_error]
# ";
Multiple errors
use *;
use TokenStream;
use ;
use quote;
#
# static _IGNORE: &str = "
#[proc_macro]
#[proc_macro_error]
# ";
Limitations
- No support for warnings.
- Very limited support for "help" suggestions.
- If a panic occurs somewhere in your macro no errors will be displayed.
Motivation
Error handling in proc-macros sucks. It's not much of a choice today:
you either "bubble up" the error up to the top-level of your macro and convert it to
a compile_error!
invocation or just use a good old panic. Both these ways suck:
-
Former sucks because it's quite redundant to unroll a proper error handling just for critical errors that will crash the macro anyway so people mostly choose not to bother with it at all and use panic. Almost nobody does it, simple
.expect
is too tempting. -
Later sucks because there's no way to carry out span info via
panic!
.rustc
will highlight the whole invocation itself but not some specific token inside it. Furthermore, panics aren't for error-reporting at all; panics are for bug-detecting (like unwrapping onNone
or out-of range indexing) or for early development stages when you need a prototype ASAP and error handling can wait. Mixing these usages only messes things up. -
There is
proc_macro::Diagnostics
which is awesome but it has been experimental for more than a year and is unlikely to be stabilized any time soon.
This crate will be deprecated once Diagnostics
is stable.
That said, we need a solution, but this solution must meet these conditions:
- It must be better than
panic!
. The main point: it must offer a way to carry span information over to user. - It must require as little effort as possible to migrate from
panic!
. Ideally, a new macro with the same semantics plus ability to carry out span info. A support for emitting multiple errors would be great too. - It must be usable on stable.
This crate aims to provide such a mechanism. All you have to do is annotate your top-level
#[proc_macro]
function with #[proc_macro_errors]
attribute and change panics to
[abort!
]/[abort_call_site!
] where appropriate, see Usage.
Disclaimer
Please note that this crate is not intended to be used in any other way
than a proc-macro error reporting, use Result
and ?
for anything else.