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}