Struct syn::Error [−][src]
Error returned when a Syn parser cannot parse the input tokens.
Error reporting in proc macros
The correct way to report errors back to the compiler from a procedural
macro is by emitting an appropriately spanned invocation of
compile_error!
in the generated code. This produces a better diagnostic
message than simply panicking the macro.
When parsing macro input, the parse_macro_input!
macro handles the
conversion to compile_error!
automatically.
use proc_macro::TokenStream; use syn::{parse_macro_input, AttributeArgs, ItemFn}; #[proc_macro_attribute] pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as AttributeArgs); let input = parse_macro_input!(input as ItemFn); /* ... */ }
For errors that arise later than the initial parsing stage, the
.to_compile_error()
method can be used to perform an explicit conversion
to compile_error!
.
#[proc_macro_derive(MyDerive)] pub fn my_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); // fn(DeriveInput) -> syn::Result<proc_macro2::TokenStream> expand::my_derive(input) .unwrap_or_else(|err| err.to_compile_error()) .into() }
Implementations
impl Error
[src]
pub fn new<T: Display>(span: Span, message: T) -> Self
[src]
Usually the ParseStream::error
method will be used instead, which
automatically uses the correct span from the current position of the
parse stream.
Use Error::new
when the error needs to be triggered on some span other
than where the parse stream is currently positioned.
Example
use syn::{Error, Ident, LitStr, Result, Token}; use syn::parse::ParseStream; // Parses input that looks like `name = "string"` where the key must be // the identifier `name` and the value may be any string literal. // Returns the string literal. fn parse_name(input: ParseStream) -> Result<LitStr> { let name_token: Ident = input.parse()?; if name_token != "name" { // Trigger an error not on the current position of the stream, // but on the position of the unexpected identifier. return Err(Error::new(name_token.span(), "expected `name`")); } input.parse::<Token![=]>()?; let s: LitStr = input.parse()?; Ok(s) }
pub fn new_spanned<T: ToTokens, U: Display>(tokens: T, message: U) -> Self
[src]
Creates an error with the specified message spanning the given syntax tree node.
Unlike the Error::new
constructor, this constructor takes an argument
tokens
which is a syntax tree node. This allows the resulting Error
to attempt to span all tokens inside of tokens
. While you would
typically be able to use the Spanned
trait with the above Error::new
constructor, implementation limitations today mean that
Error::new_spanned
may provide a higher-quality error message on
stable Rust.
When in doubt it’s recommended to stick to Error::new
(or
ParseStream::error
)!
pub fn span(&self) -> Span
[src]
The source location of the error.
Spans are not thread-safe so this function returns Span::call_site()
if called from a different thread than the one on which the Error
was
originally created.
pub fn to_compile_error(&self) -> TokenStream
[src]
Render the error as an invocation of compile_error!
.
The parse_macro_input!
macro provides a convenient way to invoke
this method correctly in a procedural macro.
pub fn into_compile_error(self) -> TokenStream
[src]
Render the error as an invocation of compile_error!
.
Example
use proc_macro::TokenStream; use syn::{parse_macro_input, DeriveInput, Error}; #[proc_macro_derive(MyTrait)] pub fn derive_my_trait(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); my_trait::expand(input) .unwrap_or_else(Error::into_compile_error) .into() } mod my_trait { use proc_macro2::TokenStream; use syn::{DeriveInput, Result}; pub(crate) fn expand(input: DeriveInput) -> Result<TokenStream> { /* ... */ } }
pub fn combine(&mut self, another: Error)
[src]
Add another error message to self such that when to_compile_error()
is
called, both errors will be emitted together.
Trait Implementations
impl Clone for Error
[src]
fn clone(&self) -> Self
[src]
pub fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl Debug for Error
[src]
impl Display for Error
[src]
impl Error for Error
[src]
pub fn source(&self) -> Option<&(dyn Error + 'static)>
1.30.0[src]
pub fn backtrace(&self) -> Option<&Backtrace>
[src]
pub fn description(&self) -> &str
1.0.0[src]
pub fn cause(&self) -> Option<&dyn Error>
1.0.0[src]
impl Extend<Error> for Error
[src]
fn extend<T: IntoIterator<Item = Error>>(&mut self, iter: T)
[src]
pub fn extend_one(&mut self, item: A)
[src]
pub fn extend_reserve(&mut self, additional: usize)
[src]
impl From<LexError> for Error
[src]
impl IntoIterator for Error
[src]
type Item = Error
The type of the elements being iterated over.
type IntoIter = IntoIter
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<'a> IntoIterator for &'a Error
[src]
Auto Trait Implementations
impl RefUnwindSafe for Error
impl Send for Error
impl Sync for Error
impl Unpin for Error
impl UnwindSafe for Error
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,