• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use proc_macro::TokenStream;
2 use proc_macro2::Span;
3 use quote::quote;
4 use syn::Error;
5 
6 #[derive(Copy, Clone)]
7 pub enum Kind {
8     Enum,
9     Match,
10     Struct,
11     Let,
12 }
13 
emit(err: Error, kind: Kind, original: TokenStream) -> TokenStream14 pub fn emit(err: Error, kind: Kind, original: TokenStream) -> TokenStream {
15     let mut err = err;
16     if !probably_has_spans(kind) {
17         // Otherwise the error is printed without any line number.
18         err = Error::new(Span::call_site(), &err.to_string());
19     }
20 
21     let err = err.to_compile_error();
22     let original = proc_macro2::TokenStream::from(original);
23 
24     let expanded = match kind {
25         Kind::Enum | Kind::Let | Kind::Struct => quote!(#err #original),
26         Kind::Match => quote!({ #err #original }),
27     };
28 
29     TokenStream::from(expanded)
30 }
31 
32 // Rustc is so bad at spans.
33 // https://github.com/rust-lang/rust/issues/43081
probably_has_spans(kind: Kind) -> bool34 fn probably_has_spans(kind: Kind) -> bool {
35     match kind {
36         Kind::Enum | Kind::Struct => true,
37         Kind::Match | Kind::Let => false,
38     }
39 }
40