Crate proc_macro_error[][src]

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 to your errors.

Real world examples

Limitations

#[proc_macro_error] attribute

This attribute MUST be present on the top level of your macro (the function annotated with any of #[proc_macro], #[proc_macro_derive], #[proc_macro_attribute]).

This attribute performs the setup and cleanup necessary to make things work.

In most cases you’ll need the simple #[proc_macro_error] form without any additional settings. Feel free to skip the “Syntax” section.

Syntax

#[proc_macro_error] or #[proc_macro_error(settings...)], where settings... is a comma-separated list of:

Macros

Most of the time you want to use the macros. Syntax is described in the next section below.

You’ll need to decide how you want to emit errors:

You can mix these usages.

abort and emit_error take a “source span” as the first argument. This source will be used to highlight the place the error originates from. It must be one of:

The rest is your message in format-like style.

See the next section for detailed syntax.

Syntax

All the macros have pretty much the same syntax:

  1. abort!(single_expr)

    Shortcut for Diagnostic::from(expr).abort().

  2. abort!(span, message)

    The first argument is an expression the span info should be taken from.

    The second argument is the error message, it must implement ToString.

  3. abort!(span, format_literal, format_args...)

    This form is pretty much the same as 2, except format!(format_literal, format_args...) will be used to for the message instead of ToString.

That’s it. abort!, emit_warning, emit_error share this exact syntax.

abort_call_site!, emit_call_site_warning, emit_call_site_error lack 1 form and do not take span in 2’th and 3’th forms. Those are essentially shortcuts for macro!(Span::call_site(), args...).

diagnostic! requires a Level instance between span and second argument (1’th form is the same).

Important!

If you have some type from proc_macro or syn to point to, do not call .span() on it but rather use it directly:

let ty: syn::Type = syn::parse2(input).unwrap();
abort!(ty, "BOOM");
//     ^^ <-- avoid .span()

.span() calls work too, but you may experience regressions in message quality.

Note attachments

  1. Every macro can have “note” attachments (only 2 and 3 form).
let opt_help = if have_some_info { Some("did you mean `this`?") } else { None };

abort!(
    span, message; // <--- attachments start with `;` (semicolon)

    help = "format {} {}", "arg1", "arg2"; // <--- every attachment ends with `;`,
                                           //      maybe except the last one

    note = "to_string"; // <--- one arg uses `.to_string()` instead of `format!()`

    yay = "I see what {} did here", "you"; // <--- "help =" and "hint =" are mapped
                                           // to Diagnostic::help,
                                           // anything else is Diagnostic::note

    wow = note_span => "custom span"; // <--- attachments can have their own span
                                      //      it takes effect only on nightly though

    hint =? opt_help; // <-- "optional" attachment, get displayed only if `Some`
                      //     must be single `Option` expression

    note =? note_span => opt_help // <-- optional attachments can have custom spans too
);

Diagnostic type

Diagnostic type is intentionally designed to be API compatible with proc_macro::Diagnostic. Not all API is implemented, only the part that can be reasonably implemented on stable.

Re-exports

pub use crate::dummy::append_dummy;
pub use crate::dummy::set_dummy;

Modules

dummy

Facility to emit dummy implementations (or whatever) in case an error happen.

Macros

abort

Abort proc-macro execution right now and display the error.

abort_call_site

Shortcut for abort!(Span::call_site(), msg...). This macro is still preferable over plain panic, panics are not for error reporting.

diagnostic

Build Diagnostic instance from provided arguments.

emit_call_site_error

Shortcut for emit_error!(Span::call_site(), ...). This macro is still preferable over plain panic, panics are not for error reporting..

emit_call_site_warning

Shortcut for emit_warning!(Span::call_site(), ...).

emit_error

Emit an error while not aborting the proc-macro right away.

emit_warning

Emit a warning. Warnings are not errors and compilation won’t fail because of them.

Structs

Diagnostic

Represents a single diagnostic message

Enums

Level

Represents a diagnostic level

Traits

OptionExt

This traits expands Option with some handy shortcuts.

ResultExt

This traits expands Result<T, Into<Diagnostic>> with some handy shortcuts.

Functions

abort_if_dirty

Abort macro execution and display all the emitted errors, if any.

Attribute Macros

proc_macro_error