const_fn/
error.rs
1use 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 pub(crate) fn into_compile_error(self) -> TokenStream {
36 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}