Unify the error modules
diff --git a/src/error.rs b/src/error.rs
index 6673aa3..adaf080 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -6,9 +6,98 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use buffer::Cursor;
-use std::error::Error;
+use std;
use std::fmt::{self, Display};
+use std::iter::FromIterator;
+
+use proc_macro2::{
+ Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
+};
+
+use buffer::Cursor;
+
+/// The result of a Syn parser.
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Error returned when a Syn parser cannot parse the input tokens.
+///
+/// Refer to the [module documentation] for details about parsing in Syn.
+///
+/// [module documentation]: index.html
+///
+/// *This type is available if Syn is built with the `"parsing"` feature.*
+#[derive(Debug)]
+pub struct Error {
+ span: Span,
+ message: String,
+}
+
+impl Error {
+ pub fn new<T: Display>(span: Span, message: T) -> Self {
+ Error {
+ span: span,
+ message: message.to_string(),
+ }
+ }
+
+ /// 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.
+ ///
+ /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
+ /// [`parse_macro_input!`]: ../macro.parse_macro_input.html
+ pub fn into_compile_error(self) -> TokenStream {
+ // compile_error!($message)
+ TokenStream::from_iter(vec![
+ TokenTree::Ident(Ident::new("compile_error", self.span)),
+ TokenTree::Punct({
+ let mut punct = Punct::new('!', Spacing::Alone);
+ punct.set_span(self.span);
+ punct
+ }),
+ TokenTree::Group({
+ let mut group = Group::new(Delimiter::Brace, {
+ TokenStream::from_iter(vec![TokenTree::Literal({
+ let mut string = Literal::string(&self.message);
+ string.set_span(self.span);
+ string
+ })])
+ });
+ group.set_span(self.span);
+ group
+ }),
+ ])
+ }
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error {
+ if cursor.eof() {
+ Error::new(scope, format!("unexpected end of input, {}", message))
+ } else {
+ Error::new(cursor.span(), message)
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(&self.message)
+ }
+}
+
+impl std::error::Error for Error {
+ fn description(&self) -> &str {
+ "parse error"
+ }
+}
+
+impl From<LexError> for Error {
+ fn from(err: LexError) -> Self {
+ Error::new(Span::call_site(), format!("{:?}", err))
+ }
+}
/// The result of a `Synom` parser.
///
@@ -17,44 +106,11 @@
/// [module documentation]: index.html
///
/// *This type is available if Syn is built with the `"parsing"` feature.*
-pub type PResult<'a, O> = Result<(O, Cursor<'a>), ParseError>;
+pub type PResult<'a, O> = std::result::Result<(O, Cursor<'a>), Error>;
/// An error with a default error message.
///
/// NOTE: We should provide better error messages in the future.
pub fn parse_error<'a, O>() -> PResult<'a, O> {
- Err(ParseError(None))
-}
-
-/// Error returned when a `Synom` parser cannot parse the input tokens.
-///
-/// Refer to the [module documentation] for details about parsing in Syn.
-///
-/// [module documentation]: index.html
-///
-/// *This type is available if Syn is built with the `"parsing"` feature.*
-#[derive(Debug)]
-pub struct ParseError(Option<String>);
-
-impl Error for ParseError {
- fn description(&self) -> &str {
- match self.0 {
- Some(ref desc) => desc,
- None => "failed to parse",
- }
- }
-}
-
-impl Display for ParseError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Display::fmt(self.description(), f)
- }
-}
-
-impl ParseError {
- // For syn use only. Not public API.
- #[doc(hidden)]
- pub fn new<T: Into<String>>(msg: T) -> Self {
- ParseError(Some(msg.into()))
- }
+ Err(Error::new(Span::call_site(), "parse error"))
}
diff --git a/src/lib.rs b/src/lib.rs
index 809bb10..4648e37 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -582,11 +582,13 @@
#[cfg(feature = "parsing")]
use synom::{Parser, Synom};
+#[cfg(feature = "parsing")]
+use proc_macro2::Span;
#[cfg(feature = "parsing")]
-mod error;
+pub mod error;
#[cfg(feature = "parsing")]
-use error::ParseError;
+use error::Error;
// Not public API.
#[cfg(feature = "parsing")]
@@ -645,7 +647,7 @@
feature = "parsing",
feature = "proc-macro"
))]
-pub fn parse<T>(tokens: proc_macro::TokenStream) -> Result<T, ParseError>
+pub fn parse<T>(tokens: proc_macro::TokenStream) -> Result<T, Error>
where
T: Synom,
{
@@ -665,13 +667,13 @@
///
/// *This function is available if Syn is built with the `"parsing"` feature.*
#[cfg(feature = "parsing")]
-pub fn parse2<T>(tokens: proc_macro2::TokenStream) -> Result<T, ParseError>
+pub fn parse2<T>(tokens: proc_macro2::TokenStream) -> Result<T, Error>
where
T: Synom,
{
let parser = T::parse;
parser.parse2(tokens).map_err(|err| match T::description() {
- Some(s) => ParseError::new(format!("failed to parse {}: {}", s, err)),
+ Some(s) => Error::new(Span::call_site(), format!("failed to parse {}: {}", s, err)),
None => err,
})
}
@@ -705,10 +707,10 @@
/// # fn main() { run().unwrap() }
/// ```
#[cfg(feature = "parsing")]
-pub fn parse_str<T: Synom>(s: &str) -> Result<T, ParseError> {
+pub fn parse_str<T: Synom>(s: &str) -> Result<T, Error> {
match s.parse() {
Ok(tts) => parse2(tts),
- Err(_) => Err(ParseError::new("error while lexing input string")),
+ Err(_) => Err(Error::new(Span::call_site(), "error while lexing input string")),
}
}
@@ -753,7 +755,7 @@
/// # fn main() { run().unwrap() }
/// ```
#[cfg(all(feature = "parsing", feature = "full"))]
-pub fn parse_file(mut content: &str) -> Result<File, ParseError> {
+pub fn parse_file(mut content: &str) -> Result<File, Error> {
// Strip the BOM if it is present
const BOM: &'static str = "\u{feff}";
if content.starts_with(BOM) {
diff --git a/src/lit.rs b/src/lit.rs
index 47555d4..299704d 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -15,7 +15,7 @@
#[cfg(feature = "parsing")]
use proc_macro2::TokenStream;
#[cfg(feature = "parsing")]
-use {ParseError, Synom};
+use {Error, Synom};
use proc_macro2::TokenTree;
@@ -122,12 +122,12 @@
///
/// All spans in the syntax tree will point to the span of this `LitStr`.
#[cfg(feature = "parsing")]
- pub fn parse<T: Synom>(&self) -> Result<T, ParseError> {
+ pub fn parse<T: Synom>(&self) -> Result<T, Error> {
use proc_macro2::Group;
// Parse string literal into a token stream with every span equal to the
// original literal's span.
- fn spanned_tokens(s: &LitStr) -> Result<TokenStream, ParseError> {
+ fn spanned_tokens(s: &LitStr) -> Result<TokenStream, Error> {
let stream = ::parse_str(&s.value())?;
Ok(respan_token_stream(stream, s.span()))
}
diff --git a/src/next/error.rs b/src/next/error.rs
deleted file mode 100644
index 05473f3..0000000
--- a/src/next/error.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-use std;
-use std::fmt::{self, Display};
-use std::iter::FromIterator;
-
-use proc_macro2::{
- Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
-};
-
-use buffer::Cursor;
-
-/// The result of a Syn parser.
-pub type Result<T> = std::result::Result<T, Error>;
-
-/// Error returned when a Syn parser cannot parse the input tokens.
-#[derive(Debug)]
-pub struct Error {
- span: Span,
- message: String,
-}
-
-impl Error {
- pub fn new<T: Display>(span: Span, message: T) -> Self {
- Error {
- span: span,
- message: message.to_string(),
- }
- }
-
- /// 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.
- ///
- /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
- /// [`parse_macro_input!`]: ../macro.parse_macro_input.html
- pub fn into_compile_error(self) -> TokenStream {
- // compile_error!($message)
- TokenStream::from_iter(vec![
- TokenTree::Ident(Ident::new("compile_error", self.span)),
- TokenTree::Punct({
- let mut punct = Punct::new('!', Spacing::Alone);
- punct.set_span(self.span);
- punct
- }),
- TokenTree::Group({
- let mut group = Group::new(Delimiter::Brace, {
- TokenStream::from_iter(vec![TokenTree::Literal({
- let mut string = Literal::string(&self.message);
- string.set_span(self.span);
- string
- })])
- });
- group.set_span(self.span);
- group
- }),
- ])
- }
-}
-
-// Not public API.
-#[doc(hidden)]
-pub fn new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error {
- if cursor.eof() {
- Error::new(scope, format!("unexpected end of input, {}", message))
- } else {
- Error::new(cursor.span(), message)
- }
-}
-
-impl Display for Error {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str(&self.message)
- }
-}
-
-impl std::error::Error for Error {
- fn description(&self) -> &str {
- "parse error"
- }
-}
-
-impl From<LexError> for Error {
- fn from(err: LexError) -> Self {
- Error::new(Span::call_site(), format!("{:?}", err))
- }
-}
diff --git a/src/next/group.rs b/src/next/group.rs
index 35aa5af..7493050 100644
--- a/src/next/group.rs
+++ b/src/next/group.rs
@@ -1,6 +1,7 @@
use proc_macro2::Delimiter;
-use super::parse::{ParseBuffer, Result};
+use error::Result;
+use super::parse::ParseBuffer;
use token;
pub struct Braces<'a> {
diff --git a/src/next/lookahead.rs b/src/next/lookahead.rs
index c051a8d..433cbaf 100644
--- a/src/next/lookahead.rs
+++ b/src/next/lookahead.rs
@@ -1,11 +1,10 @@
use std::cell::RefCell;
-use buffer::Cursor;
use proc_macro2::Span;
+use buffer::Cursor;
+use error::{self, Error};
use span::IntoSpans;
-use super::error;
-use super::parse::Error;
use token::Token;
/// Support for checking the next token in a stream to decide how to parse.
diff --git a/src/next/mod.rs b/src/next/mod.rs
index 8815570..27612e8 100644
--- a/src/next/mod.rs
+++ b/src/next/mod.rs
@@ -7,8 +7,6 @@
#[macro_use]
mod group;
-mod error;
-
use std::str::FromStr;
use buffer::TokenBuffer;
@@ -16,7 +14,8 @@
use proc_macro;
use proc_macro2::{self, Span};
-use self::parse::{Parse, ParseBuffer, Result};
+use error::Result;
+use self::parse::{Parse, ParseBuffer};
/// Parse tokens of source code into the chosen syntax tree node.
#[cfg(feature = "proc-macro")]
diff --git a/src/next/parse.rs b/src/next/parse.rs
index ed275ef..7e5f310 100644
--- a/src/next/parse.rs
+++ b/src/next/parse.rs
@@ -7,11 +7,9 @@
use std::ops::Deref;
use buffer::Cursor;
+use error::{self, Error, Result};
use proc_macro2::{Ident, Span};
-use super::error;
-
-pub use super::error::{Error, Result};
pub use super::lookahead::{Lookahead1, Peek};
/// Parsing interface implemented by all types that can be parsed in a default
diff --git a/src/synom.rs b/src/synom.rs
index 01ed855..ecf2f56 100644
--- a/src/synom.rs
+++ b/src/synom.rs
@@ -13,11 +13,11 @@
//! cheaply copyable cursor over a range of tokens in a token stream, and
//! `PResult` is a result that packages together a parsed syntax tree node `T`
//! with a stream of remaining unparsed tokens after `T` represented as another
-//! `Cursor`, or a [`ParseError`] if parsing failed.
+//! `Cursor`, or an [`Error`] if parsing failed.
//!
//! [`Cursor`]: ../buffer/index.html
//! [`PResult<T>`]: type.PResult.html
-//! [`ParseError`]: struct.ParseError.html
+//! [`Error`]: struct.Error.html
//!
//! This `Cursor`- and `PResult`-based interface is convenient for parser
//! combinators and parser implementations, but not necessarily when you just
@@ -39,7 +39,7 @@
//! ```
//! use syn::Type;
//!
-//! # fn run_parser() -> Result<(), syn::synom::ParseError> {
+//! # fn run_parser() -> Result<(), syn::synom::Error> {
//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;
//! # Ok(())
//! # }
@@ -90,7 +90,7 @@
//! use syn::punctuated::Punctuated;
//! use syn::{PathSegment, Expr, Attribute};
//!
-//! # fn run_parsers() -> Result<(), syn::synom::ParseError> {
+//! # fn run_parsers() -> Result<(), syn::synom::Error> {
//! # let tokens = TokenStream::new().into();
//! // Parse a nonempty sequence of path segments separated by `::` punctuation
//! // with no trailing punctuation.
@@ -158,7 +158,7 @@
use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
use error::parse_error;
-pub use error::{PResult, ParseError};
+pub use error::{PResult, Error};
use buffer::{Cursor, TokenBuffer};
use next;
@@ -213,7 +213,7 @@
let state = next::parse::ParseBuffer::new(Span::call_site(), input);
match <T as next::parse::Parse>::parse(&state) {
Ok(node) => Ok((node, state.cursor())),
- Err(err) => Err(ParseError::new(err.to_string())),
+ Err(err) => Err(err),
}
}
}
@@ -295,7 +295,7 @@
type Output;
/// Parse a proc-macro2 token stream into the chosen syntax tree node.
- fn parse2(self, tokens: TokenStream) -> Result<Self::Output, ParseError>;
+ fn parse2(self, tokens: TokenStream) -> Result<Self::Output, Error>;
/// Parse tokens of source code into the chosen syntax tree node.
///
@@ -305,7 +305,7 @@
not(all(target_arch = "wasm32", target_os = "unknown")),
feature = "proc-macro"
))]
- fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output, ParseError> {
+ fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output, Error> {
self.parse2(tokens.into())
}
@@ -315,10 +315,10 @@
///
/// Every span in the resulting syntax tree will be set to resolve at the
/// macro call site.
- fn parse_str(self, s: &str) -> Result<Self::Output, ParseError> {
+ fn parse_str(self, s: &str) -> Result<Self::Output, Error> {
match s.parse() {
Ok(tts) => self.parse2(tts),
- Err(_) => Err(ParseError::new("error while lexing input string")),
+ Err(_) => Err(Error::new(Span::call_site(), "error while lexing input string")),
}
}
}
@@ -329,16 +329,16 @@
{
type Output = T;
- fn parse2(self, tokens: TokenStream) -> Result<T, ParseError> {
+ fn parse2(self, tokens: TokenStream) -> Result<T, Error> {
let buf = TokenBuffer::new2(tokens);
let (t, rest) = self(buf.begin())?;
if rest.eof() {
Ok(t)
} else if rest == buf.begin() {
// parsed nothing
- Err(ParseError::new("failed to parse anything"))
+ Err(Error::new(Span::call_site(), "failed to parse anything"))
} else {
- Err(ParseError::new("failed to parse all tokens"))
+ Err(Error::new(Span::call_site(), "failed to parse all tokens"))
}
}
}
diff --git a/src/token.rs b/src/token.rs
index 90f20f9..7b1e320 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -114,9 +114,11 @@
use quote::{ToTokens, TokenStreamExt};
#[cfg(feature = "parsing")]
+use error::Result;
+#[cfg(feature = "parsing")]
use next::lookahead;
#[cfg(feature = "parsing")]
-use next::parse::{Lookahead1, Parse, ParseStream, Result};
+use next::parse::{Lookahead1, Parse, ParseStream};
use span::IntoSpans;
/// Marker trait for types that represent single tokens.
@@ -772,7 +774,8 @@
use proc_macro2::{Delimiter, Spacing, Span};
use buffer::Cursor;
- use next::parse::{Error, ParseStream, Result};
+ use error::{Error, Result};
+ use next::parse::ParseStream;
use parse_error;
use span::FromSpans;
use synom::PResult;
diff --git a/tests/test_ident.rs b/tests/test_ident.rs
index 73187d3..c2e2d9e 100644
--- a/tests/test_ident.rs
+++ b/tests/test_ident.rs
@@ -11,9 +11,9 @@
use proc_macro2::{Ident, Span, TokenStream};
use std::str::FromStr;
-use syn::synom::ParseError;
+use syn::error::Error;
-fn parse(s: &str) -> Result<Ident, ParseError> {
+fn parse(s: &str) -> Result<Ident, Error> {
syn::parse2(TokenStream::from_str(s).unwrap())
}
diff --git a/tests/test_meta_item.rs b/tests/test_meta_item.rs
index a45e36e..3f118d1 100644
--- a/tests/test_meta_item.rs
+++ b/tests/test_meta_item.rs
@@ -175,7 +175,7 @@
assert!(rest.eof());
e
}
- Err(err) => panic!(err),
+ Err(err) => panic!(err.to_string()),
};
assert_eq!(expected.into(), attr.interpret_meta().unwrap());
}