[!NOTE]
This is a maintained fork of
proc-macro-error-2, which itself was a fork ofproc-macro-error. The goal is to keep the crate maintained while preserving the original API and behavior as much as possible.Notable changes from
proc-macro-errortoproc-macro-error-2:
- Upgraded
synto2.- Raised the MSRV to
1.61.- Removed automatic nightly detection; use the
nightlyfeature for improved diagnostics.Notable changes in this fork compared to
proc-macro-error-2:
- Fixed the future-incompatibility warning from
rust-lang/rust#127909- #3 Fixed the args expansion in macros missed the comma in the presence of trailing commas.
- #4 Fixed panics when parsing
syn::Errorfails.- The changelog contains all notable changes
Makes error reporting in procedural macros nice and easy
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, you can explicitly append a dummy token stream to your errors.
To achieve this, this crate serves as a tiny shim around
proc_macro::Diagnostic and compile_error!. It detects the most preferable
way to emit errors based on compiler's version. When the underlying diagnostic
type is finally stabilized, this crate will be simply delegating to it,
requiring no changes in your code!
So you can just use this crate and have both some of proc_macro::Diagnostic
functionality available on stable ahead of time and your error-reporting code
future-proof.
[]
= "3.0"
Supports rustc 1.61 and up
Quick example
Code:
This is how the error is rendered in a terminal:
And this is what your users will see in their IDE:
Examples
Panic-like usage
use ;
use TokenStream;
use ;
use quote;
// This is your main entry point
// This attribute *MUST* be placed on top of the #[proc_macro] function
proc_macro::Diagnostic-like usage
use *;
use TokenStream;
use ;
use quote;
Real world examples
structopt-derive(abort-like usage)auto-impl(emit-like usage)
Limitations
- Warnings are emitted only on nightly, they are ignored on stable.
- "help" suggestions can't have their own span info on stable, (essentially inheriting the parent span).
- If your macro happens to trigger a panic, no errors will be displayed. This is
not a technical limitation but rather intentional design.
panicis not for error reporting.
MSRV policy
The MSRV is currently 1.61, and this is considered a breaking change to
increase.
However, if an existing dependency requires a higher MSRV without a semver breaking update, this may be raised.
Motivation
Error handling in proc-macros sucks. There's not much of a choice today: you
either "bubble up" the error up to the top-level of the 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. Simple
.expectis too tempting.Also, if you do decide to implement this
Result-based architecture in your macro you're going to have to rewrite it entirely onceproc_macro::Diagnosticis finally stable. Not cool. -
Later sucks because there's no way to carry out the span info via
panic!.rustcwill highlight the 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 on
Noneor out-of-range indexing) or for early development stages when you need a prototype ASAP so error handling can wait. Mixing these usages only messes things up. -
There is
proc_macro::Diagnosticwhich is awesome but it has been experimental for more than a year and is unlikely to be stabilized any time soon.This crate's API is intentionally designed to be compatible with
proc_macro::Diagnosticand delegates to it whenever possible. OnceDiagnosticsis stable this crate will always delegate to it, no code changes will be required on user side.
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 the span information over to user. - It must take as little effort as possible to migrate from
panic!. Ideally, a new macro with similar semantics plus ability to carry out span info. - It must maintain compatibility with
proc_macro::Diagnostic. - 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_error] attribute and
change panics to abort!/abort_call_site! where appropriate, see the
Guide.
Disclaimer
Please note that this crate is not intended to be used in any way other than
error reporting in procedural macros, use Result and ? (possibly along
with one of the many helpers out there) for anything else.