Skip to main content

proc_macro_error3/
macros.rs

1/// Build [`Diagnostic`](struct.Diagnostic.html) instance from provided arguments.
2///
3/// # Syntax
4///
5/// See [the guide](index.html#guide).
6///
7#[macro_export]
8macro_rules! diagnostic {
9    // from alias
10    ($err:expr $(,)*) => { $crate::Diagnostic::from($err) };
11
12    // span, message, help
13    ($span:expr, $level:expr, $fmt:expr, $($args:expr),+ $(,)* ; $($rest:tt)+) => {{
14        #[allow(unused_imports)]
15        use $crate::__export::{
16            ToTokensAsSpanRange,
17            Span2AsSpanRange,
18            SpanAsSpanRange,
19            SpanRangeAsSpanRange
20        };
21        use $crate::DiagnosticExt;
22        let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
23
24        let diag = $crate::Diagnostic::spanned_range(
25            span_range,
26            $level,
27            format!($fmt, $($args),*)
28        );
29        $crate::__pme__suggestions!(diag $($rest)*);
30        diag
31    }};
32
33    ($span:expr, $level:expr, $msg:expr $(,)* ; $($rest:tt)+) => {{
34        #[allow(unused_imports)]
35        use $crate::__export::{
36            ToTokensAsSpanRange,
37            Span2AsSpanRange,
38            SpanAsSpanRange,
39            SpanRangeAsSpanRange
40        };
41        use $crate::DiagnosticExt;
42        let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
43
44        let diag = $crate::Diagnostic::spanned_range(span_range, $level, $msg.to_string());
45        $crate::__pme__suggestions!(diag $($rest)*);
46        diag
47    }};
48
49    // span, message, no help
50    ($span:expr, $level:expr, $fmt:expr, $($args:expr),+ $(,)*) => {{
51        #[allow(unused_imports)]
52        use $crate::__export::{
53            ToTokensAsSpanRange,
54            Span2AsSpanRange,
55            SpanAsSpanRange,
56            SpanRangeAsSpanRange
57        };
58        use $crate::DiagnosticExt;
59        let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
60
61        $crate::Diagnostic::spanned_range(
62            span_range,
63            $level,
64            format!($fmt, $($args),*)
65        )
66    }};
67
68    ($span:expr, $level:expr, $msg:expr $(,)*) => {{
69        #[allow(unused_imports)]
70        use $crate::__export::{
71            ToTokensAsSpanRange,
72            Span2AsSpanRange,
73            SpanAsSpanRange,
74            SpanRangeAsSpanRange
75        };
76        use $crate::DiagnosticExt;
77        let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
78
79        $crate::Diagnostic::spanned_range(span_range, $level, $msg.to_string())
80    }};
81}
82
83/// Abort proc-macro execution right now and display the error.
84///
85/// # Syntax
86///
87/// See [the guide](index.html#guide).
88#[macro_export]
89macro_rules! abort {
90    ($err:expr $(,)*) => {
91        $crate::diagnostic!($err).abort()
92    };
93
94    ($span:expr, $($tts:tt)*) => {
95        $crate::diagnostic!($span, $crate::Level::Error, $($tts)*).abort()
96    };
97}
98
99/// Shortcut for `abort!(Span::call_site(), msg...)`. This macro
100/// is still preferable over plain panic, panics are not for error reporting.
101///
102/// # Syntax
103///
104/// See [the guide](index.html#guide).
105///
106#[macro_export]
107macro_rules! abort_call_site {
108    ($($tts:tt)*) => {
109        $crate::abort!($crate::__export::proc_macro2::Span::call_site(), $($tts)*)
110    };
111}
112
113/// Emit an error while not aborting the proc-macro right away.
114///
115/// # Syntax
116///
117/// See [the guide](index.html#guide).
118///
119#[macro_export]
120macro_rules! emit_error {
121    ($err:expr $(,)*) => {
122        $crate::diagnostic!($err).emit()
123    };
124
125    ($span:expr, $($tts:tt)*) => {{
126        let level = $crate::Level::Error;
127        $crate::diagnostic!($span, level, $($tts)*).emit()
128    }};
129}
130
131/// Shortcut for `emit_error!(Span::call_site(), ...)`. This macro
132/// is still preferable over plain panic, panics are not for error reporting..
133///
134/// # Syntax
135///
136/// See [the guide](index.html#guide).
137///
138#[macro_export]
139macro_rules! emit_call_site_error {
140    ($($tts:tt)*) => {
141        $crate::emit_error!($crate::__export::proc_macro2::Span::call_site(), $($tts)*)
142    };
143}
144
145/// Emit a warning. Warnings are not errors and compilation won't fail because of them.
146///
147/// **Does nothing on stable**
148///
149/// # Syntax
150///
151/// See [the guide](index.html#guide).
152///
153#[macro_export]
154macro_rules! emit_warning {
155    ($span:expr, $($tts:tt)*) => {
156        $crate::diagnostic!($span, $crate::Level::Warning, $($tts)*).emit()
157    };
158}
159
160/// Shortcut for `emit_warning!(Span::call_site(), ...)`.
161///
162/// **Does nothing on stable**
163///
164/// # Syntax
165///
166/// See [the guide](index.html#guide).
167///
168#[macro_export]
169macro_rules! emit_call_site_warning {
170    ($($tts:tt)*) => {{
171        $crate::emit_warning!($crate::__export::proc_macro2::Span::call_site(), $($tts)*)
172    }};
173}
174
175#[doc(hidden)]
176#[macro_export]
177macro_rules! __pme__suggestions {
178    ($var:ident $(,)*) => ();
179
180    ($var:ident $help:ident =? $msg:expr $(,)*) => {
181        let $var = if let Some(msg) = $msg {
182            $var.suggestion(stringify!($help), msg.to_string())
183        } else {
184            $var
185        };
186    };
187    ($var:ident $help:ident =? $span:expr => $msg:expr $(,)*) => {
188        let $var = if let Some(msg) = $msg {
189            $var.span_suggestion($span.into(), stringify!($help), msg.to_string())
190        } else {
191            $var
192        };
193    };
194
195    ($var:ident $help:ident =? $msg:expr $(,)* ; $($rest:tt)*) => {
196        $crate::__pme__suggestions!($var $help =? $msg);
197        $crate::__pme__suggestions!($var $($rest)*);
198    };
199    ($var:ident $help:ident =? $span:expr => $msg:expr $(,)* ; $($rest:tt)*) => {
200        $crate::__pme__suggestions!($var $help =? $span => $msg);
201        $crate::__pme__suggestions!($var $($rest)*);
202    };
203
204
205    ($var:ident $help:ident = $msg:expr $(,)*) => {
206        let $var = $var.suggestion(stringify!($help), $msg.to_string());
207    };
208    ($var:ident $help:ident = $fmt:expr, $($args:expr),+ $(,)*) => {
209        let $var = $var.suggestion(
210            stringify!($help),
211            format!($fmt, $($args),*)
212        );
213    };
214    ($var:ident $help:ident = $span:expr => $msg:expr $(,)*) => {
215        let $var = $var.span_suggestion($span.into(), stringify!($help), $msg.to_string());
216    };
217    ($var:ident $help:ident = $span:expr => $fmt:expr, $($args:expr),+ $(,)*) => {
218        let $var = $var.span_suggestion(
219            $span.into(),
220            stringify!($help),
221            format!($fmt, $($args),*)
222        );
223    };
224
225    ($var:ident $help:ident = $msg:expr ; $($rest:tt)*) => {
226        $crate::__pme__suggestions!($var $help = $msg);
227        $crate::__pme__suggestions!($var $($rest)*);
228    };
229    ($var:ident $help:ident = $fmt:expr, $($args:expr),+ $(,)* ; $($rest:tt)*) => {
230        $crate::__pme__suggestions!($var $help = $fmt, $($args),*);
231        $crate::__pme__suggestions!($var $($rest)*);
232    };
233    ($var:ident $help:ident = $span:expr => $msg:expr $(,)* ; $($rest:tt)*) => {
234        $crate::__pme__suggestions!($var $help = $span => $msg);
235        $crate::__pme__suggestions!($var $($rest)*);
236    };
237    ($var:ident $help:ident = $span:expr => $fmt:expr, $($args:expr),+ $(,)* ; $($rest:tt)*) => {
238        $crate::__pme__suggestions!($var $help = $span => $fmt, $($args),*);
239        $crate::__pme__suggestions!($var $($rest)*);
240    };
241}