Merge syn-error-experiment
diff --git a/src/next/parse.rs b/src/next/parse.rs
new file mode 100644
index 0000000..447b8e1
--- /dev/null
+++ b/src/next/parse.rs
@@ -0,0 +1,135 @@
+//! Parsing interface for parsing a token stream into a syntax tree node.
+
+use std::cell::Cell;
+use std::fmt::Display;
+use std::marker::PhantomData;
+use std::mem;
+use std::ops::Deref;
+
+use buffer::Cursor;
+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
+/// way from a token stream.
+pub trait Parse: Sized {
+    fn parse(input: ParseStream) -> Result<Self>;
+}
+
+/// Input to a Syn parser function.
+pub type ParseStream<'a> = &'a ParseBuffer<'a>;
+
+/// Cursor position within a buffered token stream.
+#[derive(Clone)]
+pub struct ParseBuffer<'a> {
+    scope: Span,
+    cell: Cell<Cursor<'static>>,
+    marker: PhantomData<Cursor<'a>>,
+}
+
+// Not public API.
+#[doc(hidden)]
+#[derive(Copy, Clone)]
+pub struct StepCursor<'c, 'a> {
+    scope: Span,
+    cursor: Cursor<'c>,
+    marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
+}
+
+impl<'c, 'a> Deref for StepCursor<'c, 'a> {
+    type Target = Cursor<'c>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.cursor
+    }
+}
+
+impl<'c, 'a> StepCursor<'c, 'a> {
+    // Not public API.
+    #[doc(hidden)]
+    pub fn advance(self, other: Cursor<'c>) -> Cursor<'a> {
+        unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(other) }
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn error<T: Display>(self, message: T) -> Error {
+        error::new_at(self.scope, self.cursor, message)
+    }
+}
+
+impl<'a> ParseBuffer<'a> {
+    // Not public API.
+    #[doc(hidden)]
+    pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
+        let extend = unsafe { mem::transmute::<Cursor<'a>, Cursor<'static>>(cursor) };
+        ParseBuffer {
+            scope: scope,
+            cell: Cell::new(extend),
+            marker: PhantomData,
+        }
+    }
+
+    pub fn cursor(&self) -> Cursor<'a> {
+        self.cell.get()
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.cursor().eof()
+    }
+
+    pub fn lookahead1(&self) -> Lookahead1<'a> {
+        Lookahead1::new(self.scope, self.cursor())
+    }
+
+    pub fn parse<T: Parse>(&self) -> Result<T> {
+        T::parse(self)
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn step_cursor<F, R>(&self, function: F) -> Result<R>
+    where
+        F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
+    {
+        match function(StepCursor {
+            scope: self.scope,
+            cursor: self.cell.get(),
+            marker: PhantomData,
+        }) {
+            Ok((ret, cursor)) => {
+                self.cell.set(cursor);
+                Ok(ret)
+            }
+            Err(err) => Err(err),
+        }
+    }
+}
+
+impl Parse for Ident {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| {
+            if let Some((ident, rest)) = cursor.ident() {
+                Ok((ident, rest))
+            } else {
+                Err(cursor.error("expected identifier"))
+            }
+        })
+    }
+}
+
+// In reality the impl would be for Punctuated.
+impl<T: Parse> Parse for Vec<T> {
+    fn parse(input: ParseStream) -> Result<Self> {
+        let mut vec = Vec::new();
+        while !input.is_empty() {
+            let t = input.parse::<T>()?;
+            vec.push(t);
+        }
+        Ok(vec)
+    }
+}