[][src]Crate proc_macro_error

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.

Limitations

  • Warnings are emitted only on nightly, they're ignored on stable.
  • "help" suggestions cannot have their own span info on stable, (they inherit parent span).
  • If a panic occurs somewhere in your macro no errors will be displayed. This is not a technical limitation but intentional design, panic is not for error reporting.

Guide

Macros

First of all - all the emitting-related API must be used within a function annotated with #[proc_macro_error] attribute. You'll just get a panic otherwise, no errors will be shown.

For most of the time you will be using macros.

  • abort!:

    Very much panic-like usage - abort execution and show the error. Expands to ! (never type).

  • abort_call_site!:

    Shortcut for abort!(Span::call_site(), ...). Expands to ! (never type).

  • emit_error!:

    proc_macro::Diagnostic-like usage - emit the error but do not abort the macro. The compilation will fail nonetheless. Expands to () (unit type).

  • emit_call_site_error!:

    Shortcut for emit_error!(Span::call_site(), ...). Expands to () (unit type).

  • emit_warning!:

    Like emit_error! but emit a warning instead of error. The compilation will succeed. Expands to () (unit type).

    Beware: warnings are nightly only, they are completely ignored on stable.

  • emit_call_site_warning!:

    Shortcut for emit_warning!(Span::call_site(), ...). Expands to () (unit type).

  • diagnostic:

    Build instance of Diagnostic in format-like style.

Syntax

All the macros have pretty much the same syntax:

  1. This example is not tested
    abort!(single_expr)

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

  2. This example is not tested
    abort!(span, message)

    Shortcut for Diagnostic::spanned(span, message.to_string()).abort()

  3. This example is not tested
    abort!(span, format_literal, format_args...)

    Shortcut for Diagnostic::spanned(span, format!(format_literal, format_args...)).abort()

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 and 3 forms.

diagnostic! require Level instance between span and second argument (1 form is the same).

Note attachments

  1. Every macro can have "note" attachments (only 2 and 3 form).
This example is not tested
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_macro2::Diagnostic]. Not all API is implemented, only the part that can be reasonably implemented on stable.

Re-exports

pub use self::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, see Motivation

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, see Motivation.

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 an error while not aborting the proc-macro right away.

Structs

Diagnostic

Represents a single diagnostic message

Enums

Level

Represents a diagnostic level

Traits

OptionExt

This traits expands Option<T> 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

This attribute MUST be present on the top level of your macro.