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