const_fn/
error.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use std::iter::FromIterator;
4
5use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
6
7macro_rules! format_err {
8    ($span:expr, $msg:expr $(,)*) => {
9        crate::error::Error::new($span, String::from($msg))
10    };
11    ($span:expr, $($tt:tt)*) => {
12        format_err!($span, format!($($tt)*))
13    };
14}
15
16macro_rules! bail {
17    ($($tt:tt)*) => {
18        return Err(format_err!($($tt)*))
19    };
20}
21
22pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;
23
24pub(crate) struct Error {
25    span: Span,
26    msg: String,
27}
28
29impl Error {
30    pub(crate) fn new(span: Span, msg: String) -> Self {
31        Self { span, msg }
32    }
33
34    // https://github.com/dtolnay/syn/blob/1.0.39/src/error.rs#L218-L237
35    pub(crate) fn into_compile_error(self) -> TokenStream {
36        // compile_error!($msg)
37        TokenStream::from_iter(vec![
38            TokenTree::Ident(Ident::new("compile_error", self.span)),
39            TokenTree::Punct({
40                let mut punct = Punct::new('!', Spacing::Alone);
41                punct.set_span(self.span);
42                punct
43            }),
44            TokenTree::Group({
45                let mut group = Group::new(Delimiter::Brace, {
46                    TokenStream::from_iter(vec![TokenTree::Literal({
47                        let mut string = Literal::string(&self.msg);
48                        string.set_span(self.span);
49                        string
50                    })])
51                });
52                group.set_span(self.span);
53                group
54            }),
55        ])
56    }
57}