Expand description
§Use Diagnostic compiler messages from proc_macro2 code with Result-like syntax
Provides a DiagnosticResult which makes it easy to implement multi-level compiler messages based upon the experimental proc_macro::Diagnostic and allows simple idiomatic error handling via ? while ensuring errors & warnings are properly emitted by the compiler.
Provides a “fire and forget” API which works (and is tested) on nightly, stable and will automatically provide new features on stable as they become available. We have taken great care to provide an experience which automatically gets better as experimental features are stabilised and correctly and safely identifies the features available at build time.
§Note
This crate is deliberately opinionated and focuses on making it easy to create good compiler errors and handle them easily:
- Top level diagnostics must be either an
Erroror aWarning - (Only)
Help&Notes can be added as children - A note highlighting the original call site will be added to any
Errors /Warnings which do not span the call site themselves, or contain a childNote/Helpwhich does. - Multi-level nesting is not possible
- We do not provide an implementation of the full
proc_macro::DiagnosticAPI. Other crates attempt to do this, if that is what you are after.
§Stability & MSRV
Given that this crate exposes an experimental API from std it works best on a nightly toolchain. I have taken great care to craft an API which works consistently on stable and which will leverage experimental features as soon as they stabilise, without additional intervention.
🔬 Experimental Features
This crate makes use of two groups of experimental features on nightly, and implements the following technical compromises on where these features are unavailable:
§Diagnostic compiler messages
On systems where the experimental API is not available:
- Multi-Span messages are not possible. The first
Span(based on insertion order, not code position) will be used and any additionalSpanswill be disregarded- All messages will be output as compiler errors.
note: ...becomeserror: note: ...§Custom Try types
On systems where custom try types are not available, handling
Warnings is less ergonomic:
Warnings are immediately emitted upon construction- any
HelporNotes added to aWarningwill not be emitted- any custom handling will not activate
§Stability guarantees
We recognise that you probably do not have control over the toolchain used to compile your crate, that is decided by someone downstream. This crate is therefore constructed in a way that will ensure your code always compiles, regardless of whether it is ultimately built on a nightly toolchain, the current stable toolchain, or a future stable toolchain where some of the above experimental features are stabilised.
We do this by using the amazing autocfg to securely identify the availability of each feature we use as well as the need to enable an experimental feature flag.
We run automated tests every month to ensure no fundamental changes affect this crate and test every PR against the current nightly, as well as the current equivalent beta & stable. We test & lint every push 4 times: against current nightly, current stable and nightly with only try / diagnostic enabled.
We recommend you also test your crate on at least stable & nightly before publishing.
If you find an issue before we do, please raise an issue on github.
The only thing you need to worry about: Please do NOT expand the type alias DiagnosticResult<T> on stable, if you do your crate will not work on nightly, and will break at some point in the future when try_trait_v2 is stabilised.
§MSRV
This crate supports every version of edition 2024 (rust 1.85.1 onwards, released as stable on 20225-03-18).
§Dependencies
We deliberately keep the dependency list short and pay attention to any transitive dependencies we bring in.
Current dependency tree:
proc_macro2_diagnostic <- This crate
└── proc-macro2
└── unicode-ident
└── syn
├── quote
│ └── proc-macro2
└── unicode-ident
[build-dependencies]
├── autocfg
└── ninja-build_rs
└── autocfg§Alternatives
- The similarly named proc_macro2_diagnostics attempts to provide the full Diagnostic API, also on stable. Although it doesn’t allow simple handling via
?or guaranteed emission; uses a not-recommended hack to identify stable/nightly and in our experience tends to break in its attempt to color output. But it’s very popular and complete, just not what we, the authors, were looking for.
Modules§
- prelude
- Prelude for easy
*`` imports:use proc_macro2_diagnostic::prelude::*`
Structs§
- Diagnostic
- The internal Diagnostic stored within DiagnosticResult. Not (currently) designed for direct usage.
- Diagnostic
Result - Result-like type which can represent a valid return value, an error or a warning accompanying
a valid return value. Warnings will be emitted upon
?, allowing your code to continue with the valid value. Errors will short-circuit upon?and be emitted upon final conversion to a proc_macro::TokenStream
Enums§
- Diagnostic
Result Kind - The type of top-level message contained in the DiagnosticResult
- Level
- 1:1 match for proc_macro::Level.
Traits§
- AsDiagnostic
- Diagnostic
Kind - Multi
Span - A helper trait for APIs that accept one or more
Spans. - ToDiagnostic
- Provides methods to generate a diagnostic in “failure” case. This is a bit like
Option::ok_or()but returns aDiagnosticResultand can be implemented on additional types. - ToTokens
Functions§
- Ok
- Create an
Okresult. - error
- Create an error spanning the macro call_site
- error_
spanned - Create an error at the given
Spans. - warn_
spanned - Create a warning which will emit a message at the given
Spans and deconstruct to a valid value via?.
Type Aliases§
- Diagnostic
Stream - A convenience type which is designed to be returned from a proc_macro2-based macro implementation.