diff options
Diffstat (limited to 'vendor/proc-macro-error-attr/src')
-rw-r--r-- | vendor/proc-macro-error-attr/src/lib.rs | 121 | ||||
-rw-r--r-- | vendor/proc-macro-error-attr/src/parse.rs | 89 | ||||
-rw-r--r-- | vendor/proc-macro-error-attr/src/settings.rs | 72 |
3 files changed, 0 insertions, 282 deletions
diff --git a/vendor/proc-macro-error-attr/src/lib.rs b/vendor/proc-macro-error-attr/src/lib.rs deleted file mode 100644 index ac0ac21a2..000000000 --- a/vendor/proc-macro-error-attr/src/lib.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! This is `#[proc_macro_error]` attribute to be used with -//! [`proc-macro-error`](https://docs.rs/proc-macro-error/). There you go. - -extern crate proc_macro; - -use crate::parse::parse_input; -use crate::parse::Attribute; -use proc_macro::TokenStream; -use proc_macro2::{Literal, Span, TokenStream as TokenStream2, TokenTree}; -use quote::{quote, quote_spanned}; - -use crate::settings::{Setting::*, *}; - -mod parse; -mod settings; - -type Result<T> = std::result::Result<T, Error>; - -struct Error { - span: Span, - message: String, -} - -impl Error { - fn new(span: Span, message: String) -> Self { - Error { span, message } - } - - fn into_compile_error(self) -> TokenStream2 { - let mut message = Literal::string(&self.message); - message.set_span(self.span); - quote_spanned!(self.span=> compile_error!{#message}) - } -} - -#[proc_macro_attribute] -pub fn proc_macro_error(attr: TokenStream, input: TokenStream) -> TokenStream { - match impl_proc_macro_error(attr.into(), input.clone().into()) { - Ok(ts) => ts, - Err(e) => { - let error = e.into_compile_error(); - let input = TokenStream2::from(input); - - quote!(#input #error).into() - } - } -} - -fn impl_proc_macro_error(attr: TokenStream2, input: TokenStream2) -> Result<TokenStream> { - let (attrs, signature, body) = parse_input(input)?; - let mut settings = parse_settings(attr)?; - - let is_proc_macro = is_proc_macro(&attrs); - if is_proc_macro { - settings.set(AssertUnwindSafe); - } - - if detect_proc_macro_hack(&attrs) { - settings.set(ProcMacroHack); - } - - if settings.is_set(ProcMacroHack) { - settings.set(AllowNotMacro); - } - - if !(settings.is_set(AllowNotMacro) || is_proc_macro) { - return Err(Error::new( - Span::call_site(), - "#[proc_macro_error] attribute can be used only with procedural macros\n\n \ - = hint: if you are really sure that #[proc_macro_error] should be applied \ - to this exact function, use #[proc_macro_error(allow_not_macro)]\n" - .into(), - )); - } - - let body = gen_body(body, settings); - - let res = quote! { - #(#attrs)* - #(#signature)* - { #body } - }; - Ok(res.into()) -} - -#[cfg(not(always_assert_unwind))] -fn gen_body(block: TokenTree, settings: Settings) -> proc_macro2::TokenStream { - let is_proc_macro_hack = settings.is_set(ProcMacroHack); - let closure = if settings.is_set(AssertUnwindSafe) { - quote!(::std::panic::AssertUnwindSafe(|| #block )) - } else { - quote!(|| #block) - }; - - quote!( ::proc_macro_error::entry_point(#closure, #is_proc_macro_hack) ) -} - -// FIXME: -// proc_macro::TokenStream does not implement UnwindSafe until 1.37.0. -// Considering this is the closure's return type the unwind safety check would fail -// for virtually every closure possible, the check is meaningless. -#[cfg(always_assert_unwind)] -fn gen_body(block: TokenTree, settings: Settings) -> proc_macro2::TokenStream { - let is_proc_macro_hack = settings.is_set(ProcMacroHack); - let closure = quote!(::std::panic::AssertUnwindSafe(|| #block )); - quote!( ::proc_macro_error::entry_point(#closure, #is_proc_macro_hack) ) -} - -fn detect_proc_macro_hack(attrs: &[Attribute]) -> bool { - attrs - .iter() - .any(|attr| attr.path_is_ident("proc_macro_hack")) -} - -fn is_proc_macro(attrs: &[Attribute]) -> bool { - attrs.iter().any(|attr| { - attr.path_is_ident("proc_macro") - || attr.path_is_ident("proc_macro_derive") - || attr.path_is_ident("proc_macro_attribute") - }) -} diff --git a/vendor/proc-macro-error-attr/src/parse.rs b/vendor/proc-macro-error-attr/src/parse.rs deleted file mode 100644 index 6f4663f80..000000000 --- a/vendor/proc-macro-error-attr/src/parse.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::{Error, Result}; -use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree}; -use quote::ToTokens; -use std::iter::Peekable; - -pub(crate) fn parse_input( - input: TokenStream, -) -> Result<(Vec<Attribute>, Vec<TokenTree>, TokenTree)> { - let mut input = input.into_iter().peekable(); - let mut attrs = Vec::new(); - - while let Some(attr) = parse_next_attr(&mut input)? { - attrs.push(attr); - } - - let sig = parse_signature(&mut input); - let body = input.next().ok_or_else(|| { - Error::new( - Span::call_site(), - "`#[proc_macro_error]` can be applied only to functions".to_string(), - ) - })?; - - Ok((attrs, sig, body)) -} - -fn parse_next_attr( - input: &mut Peekable<impl Iterator<Item = TokenTree>>, -) -> Result<Option<Attribute>> { - let shebang = match input.peek() { - Some(TokenTree::Punct(ref punct)) if punct.as_char() == '#' => input.next().unwrap(), - _ => return Ok(None), - }; - - let group = match input.peek() { - Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::Bracket => { - let res = group.clone(); - input.next(); - res - } - other => { - let span = other.map_or(Span::call_site(), |tt| tt.span()); - return Err(Error::new(span, "expected `[`".to_string())); - } - }; - - let path = match group.stream().into_iter().next() { - Some(TokenTree::Ident(ident)) => Some(ident), - _ => None, - }; - - Ok(Some(Attribute { - shebang, - group: TokenTree::Group(group), - path, - })) -} - -fn parse_signature(input: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Vec<TokenTree> { - let mut sig = Vec::new(); - loop { - match input.peek() { - Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::Brace => { - return sig; - } - None => return sig, - _ => sig.push(input.next().unwrap()), - } - } -} - -pub(crate) struct Attribute { - pub(crate) shebang: TokenTree, - pub(crate) group: TokenTree, - pub(crate) path: Option<Ident>, -} - -impl Attribute { - pub(crate) fn path_is_ident(&self, ident: &str) -> bool { - self.path.as_ref().map_or(false, |p| *p == ident) - } -} - -impl ToTokens for Attribute { - fn to_tokens(&self, ts: &mut TokenStream) { - self.shebang.to_tokens(ts); - self.group.to_tokens(ts); - } -} diff --git a/vendor/proc-macro-error-attr/src/settings.rs b/vendor/proc-macro-error-attr/src/settings.rs deleted file mode 100644 index 0b7ec766f..000000000 --- a/vendor/proc-macro-error-attr/src/settings.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::{Error, Result}; -use proc_macro2::{Ident, Span, TokenStream, TokenTree}; - -macro_rules! decl_settings { - ($($val:expr => $variant:ident),+ $(,)*) => { - #[derive(PartialEq)] - pub(crate) enum Setting { - $($variant),* - } - - fn ident_to_setting(ident: Ident) -> Result<Setting> { - match &*ident.to_string() { - $($val => Ok(Setting::$variant),)* - _ => { - let possible_vals = [$($val),*] - .iter() - .map(|v| format!("`{}`", v)) - .collect::<Vec<_>>() - .join(", "); - - Err(Error::new( - ident.span(), - format!("unknown setting `{}`, expected one of {}", ident, possible_vals))) - } - } - } - }; -} - -decl_settings! { - "assert_unwind_safe" => AssertUnwindSafe, - "allow_not_macro" => AllowNotMacro, - "proc_macro_hack" => ProcMacroHack, -} - -pub(crate) fn parse_settings(input: TokenStream) -> Result<Settings> { - let mut input = input.into_iter(); - let mut res = Settings(Vec::new()); - loop { - match input.next() { - Some(TokenTree::Ident(ident)) => { - res.0.push(ident_to_setting(ident)?); - } - None => return Ok(res), - other => { - let span = other.map_or(Span::call_site(), |tt| tt.span()); - return Err(Error::new(span, "expected identifier".to_string())); - } - } - - match input.next() { - Some(TokenTree::Punct(ref punct)) if punct.as_char() == ',' => {} - None => return Ok(res), - other => { - let span = other.map_or(Span::call_site(), |tt| tt.span()); - return Err(Error::new(span, "expected `,`".to_string())); - } - } - } -} - -pub(crate) struct Settings(Vec<Setting>); - -impl Settings { - pub(crate) fn is_set(&self, setting: Setting) -> bool { - self.0.iter().any(|s| *s == setting) - } - - pub(crate) fn set(&mut self, setting: Setting) { - self.0.push(setting) - } -} |