Verbatim logic in one place
diff --git a/src/expr.rs b/src/expr.rs
index 6141caa..7910cf7 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1612,7 +1612,7 @@
         |
         call!(expr_closure, allow_struct)
         |
-        call!(expr_unstable_async_closure, allow_struct)
+        call!(expr_unstable_async_closure, allow_struct) => { Expr::Verbatim }
         |
         cond_reduce!(allow_block, syn!(ExprBlock)) => { Expr::Block }
         |
@@ -2128,13 +2128,8 @@
     ));
 
     #[cfg(feature = "full")]
-    fn grab_cursor(cursor: Cursor) -> PResult<Cursor> {
-        Ok((cursor, cursor))
-    }
-
-    #[cfg(feature = "full")]
-    named!(expr_unstable_async_closure(allow_struct: bool) -> Expr, do_parse!(
-        begin: call!(grab_cursor) >>
+    named!(expr_unstable_async_closure(allow_struct: bool) -> ExprVerbatim, do_parse!(
+        begin: call!(verbatim::grab_cursor) >>
         _attrs: many0!(Attribute::parse_outer) >>
         _asyncness: keyword!(async) >>
         _movability: option!(keyword!(static)) >>
@@ -2156,30 +2151,22 @@
             |
             map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
         ) >>
-        end: call!(grab_cursor) >>
-        ({
-            let tts = begin.token_stream().into_iter().collect::<Vec<_>>();
-            let len = tts.len() - end.token_stream().into_iter().count();
-            ExprVerbatim {
-                tts: tts.into_iter().take(len).collect(),
-            }.into()
+        end: call!(verbatim::grab_cursor) >>
+        (ExprVerbatim {
+            tts: verbatim::token_range(begin..end),
         })
     ));
 
     #[cfg(feature = "full")]
     named!(unstable_async_block -> ExprVerbatim, do_parse!(
-        begin: call!(grab_cursor) >>
+        begin: call!(verbatim::grab_cursor) >>
         _attrs: many0!(Attribute::parse_outer) >>
         _asyncness: keyword!(async) >>
         _capture: option!(keyword!(move)) >>
         _body: syn!(Block) >>
-        end: call!(grab_cursor) >>
-        ({
-            let tts = begin.token_stream().into_iter().collect::<Vec<_>>();
-            let len = tts.len() - end.token_stream().into_iter().count();
-            ExprVerbatim {
-                tts: tts.into_iter().take(len).collect(),
-            }.into()
+        end: call!(verbatim::grab_cursor) >>
+        (ExprVerbatim {
+            tts: verbatim::token_range(begin..end),
         })
     ));
 
diff --git a/src/item.rs b/src/item.rs
index feab364..5a5437d 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -714,8 +714,7 @@
 pub mod parsing {
     use super::*;
 
-    use buffer::Cursor;
-    use synom::{PResult, Synom};
+    use synom::Synom;
 
     impl_synom!(Item "item" alt!(
         syn!(ItemExternCrate) => { Item::ExternCrate }
@@ -988,12 +987,8 @@
         })
     ));
 
-    fn grab_cursor(cursor: Cursor) -> PResult<Cursor> {
-        Ok((cursor, cursor))
-    }
-
     named!(unstable_async_fn -> ItemVerbatim, do_parse!(
-        begin: call!(grab_cursor) >>
+        begin: call!(verbatim::grab_cursor) >>
         _outer_attrs: many0!(Attribute::parse_outer) >>
         _vis: syn!(Visibility) >>
         _constness: option!(keyword!(const)) >>
@@ -1010,13 +1005,9 @@
             many0!(Attribute::parse_inner),
             call!(Block::parse_within),
         )) >>
-        end: call!(grab_cursor) >>
-        ({
-            let tts = begin.token_stream().into_iter().collect::<Vec<_>>();
-            let len = tts.len() - end.token_stream().into_iter().count();
-            ItemVerbatim {
-                tts: tts.into_iter().take(len).collect(),
-            }
+        end: call!(verbatim::grab_cursor) >>
+        (ItemVerbatim {
+            tts: verbatim::token_range(begin..end),
         })
     ));
 
@@ -1540,7 +1531,7 @@
     ));
 
     named!(unstable_async_method -> ImplItemVerbatim, do_parse!(
-        begin: call!(grab_cursor) >>
+        begin: call!(verbatim::grab_cursor) >>
         _outer_attrs: many0!(Attribute::parse_outer) >>
         _vis: syn!(Visibility) >>
         _defaultness: option!(keyword!(default)) >>
@@ -1558,13 +1549,9 @@
             many0!(Attribute::parse_inner),
             call!(Block::parse_within),
         )) >>
-        end: call!(grab_cursor) >>
-        ({
-            let tts = begin.token_stream().into_iter().collect::<Vec<_>>();
-            let len = tts.len() - end.token_stream().into_iter().count();
-            ImplItemVerbatim {
-                tts: tts.into_iter().take(len).collect(),
-            }
+        end: call!(verbatim::grab_cursor) >>
+        (ImplItemVerbatim {
+            tts: verbatim::token_range(begin..end),
         })
     ));
 
diff --git a/src/lib.rs b/src/lib.rs
index 3c99003..60da219 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -447,6 +447,9 @@
 #[cfg(all(feature = "parsing", feature = "printing"))]
 pub mod spanned;
 
+#[cfg(feature = "full")]
+mod verbatim;
+
 mod gen {
     /// Syntax tree traversal to walk a shared borrow of a syntax tree.
     ///
diff --git a/src/verbatim.rs b/src/verbatim.rs
new file mode 100644
index 0000000..8ab0603
--- /dev/null
+++ b/src/verbatim.rs
@@ -0,0 +1,20 @@
+use std::ops::Range;
+
+use buffer::Cursor;
+use proc_macro2::TokenStream;
+use synom::PResult;
+
+pub fn grab_cursor(cursor: Cursor) -> PResult<Cursor> {
+    Ok((cursor, cursor))
+}
+
+pub fn token_range(range: Range<Cursor>) -> TokenStream {
+    let mut tts = Vec::new();
+    let mut cursor = range.start;
+    while cursor != range.end {
+        let (tt, next) = cursor.token_tree().expect("malformed token range");
+        tts.push(tt);
+        cursor = next;
+    }
+    tts.into_iter().collect()
+}