proc_macro2_diagnostics/
ext.rs

1use proc_macro2::Span;
2
3use crate::diagnostic::{Level, Diagnostic};
4
5macro_rules! diagnostic_def {
6    ($name:ident) => (
7        /// Create a new `Diagnostic` of the kind of this method's name with the
8        /// span `self`.
9        fn $name<T: Into<String>>(self, message: T) -> Diagnostic;
10    )
11}
12
13/// Extension trait for `proc_macro2::Span` emulating the proc-macro diagnostic
14/// API on stable and nightly.
15///
16/// # Example
17///
18/// ```rust
19/// use proc_macro2::Span;
20/// use proc_macro2_diagnostics::SpanDiagnosticExt;
21///
22/// let span = Span::call_site();
23/// let diag = span.error("there's a problem here...");
24///
25/// // emit into an expression context.
26/// # let diag = span.error("there's a problem here...");
27/// let tokens = diag.emit_as_expr_tokens();
28///
29/// // or emit into an item context.
30/// # let diag = span.error("there's a problem here...");
31/// let tokens = diag.emit_as_item_tokens();
32/// ```
33pub trait SpanDiagnosticExt {
34    diagnostic_def!(error);
35    diagnostic_def!(warning);
36    diagnostic_def!(note);
37    diagnostic_def!(help);
38}
39
40macro_rules! diagnostic_method {
41    ($name:ident, $level:expr) => (
42        fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
43            Diagnostic::spanned(self, $level, message)
44        }
45    )
46}
47
48impl SpanDiagnosticExt for Span {
49    diagnostic_method!(error, Level::Error);
50    diagnostic_method!(warning, Level::Warning);
51    diagnostic_method!(note, Level::Note);
52    diagnostic_method!(help, Level::Help);
53}