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());
 }