Merge branch master into next
diff --git a/codegen/src/main.rs b/codegen/src/main.rs
index 4a7ec38..9a12cee 100644
--- a/codegen/src/main.rs
+++ b/codegen/src/main.rs
@@ -246,7 +246,7 @@
     pub struct AstStruct(pub Vec<AstItem>);
     impl Synom for AstStruct {
         named!(parse -> Self, do_parse!(
-            many0!(Attribute::parse_outer) >>
+            many0!(Attribute::old_parse_outer) >>
             keyword!(pub) >>
             keyword!(struct) >>
             res: call!(ast_struct_inner) >>
@@ -265,7 +265,7 @@
     pub struct AstEnum(pub Vec<AstItem>);
     impl Synom for AstEnum {
         named!(parse -> Self, do_parse!(
-            many0!(Attribute::parse_outer) >>
+            many0!(Attribute::old_parse_outer) >>
             keyword!(pub) >>
             keyword!(enum) >>
             id: syn!(Ident) >>
@@ -292,7 +292,7 @@
         inner: Option<AstItem>,
     }
     named!(eos_variant -> EosVariant, do_parse!(
-        many0!(Attribute::parse_outer) >>
+        many0!(Attribute::old_parse_outer) >>
         keyword!(pub) >>
         variant: syn!(Ident) >>
         member: option!(map!(parens!(alt!(
@@ -312,7 +312,7 @@
     pub struct AstEnumOfStructs(pub Vec<AstItem>);
     impl Synom for AstEnumOfStructs {
         named!(parse -> Self, do_parse!(
-            many0!(Attribute::parse_outer) >>
+            many0!(Attribute::old_parse_outer) >>
             keyword!(pub) >>
             keyword!(enum) >>
             id: syn!(Ident) >>
@@ -351,6 +351,8 @@
     use proc_macro2::{Span, TokenStream};
     use quote::{ToTokens, TokenStreamExt};
     use syn::punctuated::Punctuated;
+    use syn::synom::ext::IdentExt;
+    use syn::synom::Parser;
     use syn::*;
 
     #[derive(Default)]
@@ -374,7 +376,9 @@
         Option(&'a Type),
         Tuple(&'a Punctuated<Type, Token![,]>),
         Simple(&'a AstItem),
-        Token(TokenStream),
+        TokenPunct(TokenStream),
+        TokenKeyword(TokenStream),
+        TokenGroup(Ident),
         Pass,
     }
 
@@ -391,7 +395,7 @@
                     "Punctuated" => RelevantType::Punctuated(first_arg(&last.arguments)),
                     "Option" => RelevantType::Option(first_arg(&last.arguments)),
                     "Brace" | "Bracket" | "Paren" | "Group" => {
-                        RelevantType::Token(last.ident.clone().into_token_stream())
+                        RelevantType::TokenGroup(last.ident.clone())
                     }
                     _ => {
                         if let Some(item) = lookup.get(&last.ident) {
@@ -406,7 +410,13 @@
             Type::Macro(TypeMacro { ref mac })
                 if mac.path.segments.last().unwrap().into_value().ident == "Token" =>
             {
-                RelevantType::Token(mac.into_token_stream())
+                let is_ident = Ident::parse_any.parse2(mac.tts.clone()).is_ok() ;
+                let is_underscore = parse2::<Token![_]>(mac.tts.clone()).is_ok();
+                if is_ident && !is_underscore {
+                    RelevantType::TokenKeyword(mac.into_token_stream())
+                } else {
+                    RelevantType::TokenPunct(mac.into_token_stream())
+                }
             }
             _ => RelevantType::Pass,
         }
@@ -642,17 +652,47 @@
         })
     }
 
-    fn token_visit(ty: TokenStream, kind: Kind, name: &Operand) -> TokenStream {
+    fn token_punct_visit(ty: TokenStream, kind: Kind, name: &Operand) -> TokenStream {
         let name = name.tokens();
         match kind {
             Fold => quote! {
-                #ty(tokens_helper(_visitor, &(#name).0))
+                #ty(tokens_helper(_visitor, &#name.spans))
             },
             Visit => quote! {
-                tokens_helper(_visitor, &(#name).0)
+                tokens_helper(_visitor, &#name.spans)
             },
             VisitMut => quote! {
-                tokens_helper(_visitor, &mut (#name).0)
+                tokens_helper(_visitor, &mut #name.spans)
+            },
+        }
+    }
+
+    fn token_keyword_visit(ty: TokenStream, kind: Kind, name: &Operand) -> TokenStream {
+        let name = name.tokens();
+        match kind {
+            Fold => quote! {
+                #ty(tokens_helper(_visitor, &#name.span))
+            },
+            Visit => quote! {
+                tokens_helper(_visitor, &#name.span)
+            },
+            VisitMut => quote! {
+                tokens_helper(_visitor, &mut #name.span)
+            },
+        }
+    }
+
+    fn token_group_visit(ty: Ident, kind: Kind, name: &Operand) -> TokenStream {
+        let name = name.tokens();
+        match kind {
+            Fold => quote! {
+                #ty(tokens_helper(_visitor, &#name.span))
+            },
+            Visit => quote! {
+                tokens_helper(_visitor, &#name.span)
+            },
+            VisitMut => quote! {
+                tokens_helper(_visitor, &mut #name.span)
             },
         }
     }
@@ -686,7 +726,9 @@
                     res
                 })
             }
-            RelevantType::Token(ty) => Some(token_visit(ty, kind, name)),
+            RelevantType::TokenPunct(ty) => Some(token_punct_visit(ty, kind, name)),
+            RelevantType::TokenKeyword(ty) => Some(token_keyword_visit(ty, kind, name)),
+            RelevantType::TokenGroup(ty) => Some(token_group_visit(ty, kind, name)),
             RelevantType::Pass => None,
         }
     }
diff --git a/rustfmt.toml b/rustfmt.toml
deleted file mode 100644
index b2715b2..0000000
--- a/rustfmt.toml
+++ /dev/null
@@ -1 +0,0 @@
-wrap_comments = true
diff --git a/src/attr.rs b/src/attr.rs
index d818b4f..a925ecf 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -39,8 +39,8 @@
     ///
     /// The `style` field of type `AttrStyle` distinguishes whether an attribute
     /// is outer or inner. Doc comments and block comments are promoted to
-    /// attributes that have `is_sugared_doc` set to true, as this is how they
-    /// are processed by the compiler and by `macro_rules!` macros.
+    /// attributes, as this is how they are processed by the compiler and by
+    /// `macro_rules!` macros.
     ///
     /// The `path` field gives the possibly colon-delimited path against which
     /// the attribute is resolved. It is equal to `"doc"` for desugared doc
@@ -64,7 +64,6 @@
         pub bracket_token: token::Bracket,
         pub path: Path,
         pub tts: TokenStream,
-        pub is_sugared_doc: bool,
     }
 }
 
@@ -79,7 +78,6 @@
             && self.bracket_token == other.bracket_token
             && self.path == other.path
             && TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
-            && self.is_sugared_doc == other.is_sugared_doc
     }
 }
 
@@ -94,7 +92,6 @@
         self.bracket_token.hash(state);
         self.path.hash(state);
         TokenStreamHelper(&self.tts).hash(state);
-        self.is_sugared_doc.hash(state);
     }
 }
 
@@ -397,6 +394,7 @@
 pub mod parsing {
     use super::*;
     use buffer::Cursor;
+    use parse::{ParseStream, Result};
     use parse_error;
     use proc_macro2::{Literal, Punct, Spacing, Span, TokenTree};
     use synom::PResult;
@@ -408,12 +406,28 @@
     }
 
     impl Attribute {
-        named!(pub parse_inner -> Self, alt!(
+        pub fn parse_outer(input: ParseStream) -> Result<Vec<Self>> {
+            let mut attrs = Vec::new();
+            while input.peek(Token![#]) {
+                attrs.push(input.parse_synom(Attribute::old_parse_outer)?);
+            }
+            Ok(attrs)
+        }
+
+        pub fn parse_inner(input: ParseStream) -> Result<Vec<Self>> {
+            let mut attrs = Vec::new();
+            while input.peek(Token![#]) && input.peek2(Token![!]) {
+                attrs.push(input.parse_synom(Attribute::old_parse_inner)?);
+            }
+            Ok(attrs)
+        }
+
+        named!(pub old_parse_inner -> Self, alt!(
             do_parse!(
                 pound: punct!(#) >>
                 bang: punct!(!) >>
                 path_and_tts: brackets!(tuple!(
-                    call!(Path::parse_mod_style),
+                    call!(Path::old_parse_mod_style),
                     syn!(TokenStream),
                 )) >>
                 ({
@@ -423,7 +437,6 @@
                         style: AttrStyle::Inner(bang),
                         path: path,
                         tts: tts,
-                        is_sugared_doc: false,
                         pound_token: pound,
                         bracket_token: bracket,
                     }
@@ -435,25 +448,24 @@
                 |lit| {
                     let span = lit.span();
                     Attribute {
-                        style: AttrStyle::Inner(<Token![!]>::new(span)),
+                        style: AttrStyle::Inner(Token![!](span)),
                         path: Ident::new("doc", span).into(),
                         tts: vec![
                             eq(span),
                             lit,
                         ].into_iter().collect(),
-                        is_sugared_doc: true,
-                        pound_token: <Token![#]>::new(span),
+                        pound_token: Token![#](span),
                         bracket_token: token::Bracket(span),
                     }
                 }
             )
         ));
 
-        named!(pub parse_outer -> Self, alt!(
+        named!(pub old_parse_outer -> Self, alt!(
             do_parse!(
                 pound: punct!(#) >>
                 path_and_tts: brackets!(tuple!(
-                    call!(Path::parse_mod_style),
+                    call!(Path::old_parse_mod_style),
                     syn!(TokenStream),
                 )) >>
                 ({
@@ -463,7 +475,6 @@
                         style: AttrStyle::Outer,
                         path: path,
                         tts: tts,
-                        is_sugared_doc: false,
                         pound_token: pound,
                         bracket_token: bracket,
                     }
@@ -481,8 +492,7 @@
                             eq(span),
                             lit,
                         ].into_iter().collect(),
-                        is_sugared_doc: true,
-                        pound_token: <Token![#]>::new(span),
+                        pound_token: Token![#](span),
                         bracket_token: token::Bracket(span),
                     }
                 }
diff --git a/src/data.rs b/src/data.rs
index 8ffc8a4..c8e9e06 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -185,160 +185,131 @@
 pub mod parsing {
     use super::*;
 
+    use parse::{Parse, ParseStream, Result};
+    use synom::ext::IdentExt;
     use synom::Synom;
 
-    impl Synom for Variant {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            id: syn!(Ident) >>
-            fields: alt!(
-                syn!(FieldsNamed) => { Fields::Named }
-                |
-                syn!(FieldsUnnamed) => { Fields::Unnamed }
-                |
-                epsilon!() => { |_| Fields::Unit }
-            ) >>
-            disr: option!(tuple!(punct!(=), syn!(Expr))) >>
-            (Variant {
-                ident: id,
-                attrs: attrs,
-                fields: fields,
-                discriminant: disr,
+    impl Parse for Variant {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(Variant {
+                attrs: input.call(Attribute::parse_outer)?,
+                ident: input.parse()?,
+                fields: {
+                    if input.peek(token::Brace) {
+                        Fields::Named(input.parse()?)
+                    } else if input.peek(token::Paren) {
+                        Fields::Unnamed(input.parse()?)
+                    } else {
+                        Fields::Unit
+                    }
+                },
+                discriminant: {
+                    if input.peek(Token![=]) {
+                        Some((input.parse()?, input.parse_synom(Expr::parse)?))
+                    } else {
+                        None
+                    }
+                },
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("enum variant")
         }
     }
 
-    impl Synom for FieldsNamed {
-        named!(parse -> Self, map!(
-            braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
-            |(brace, fields)| FieldsNamed {
-                brace_token: brace,
-                named: fields,
-            }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("named fields in a struct or struct variant")
+    impl Parse for FieldsNamed {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(FieldsNamed {
+                brace_token: braced!(content in input),
+                named: content.parse_terminated(Field::parse_named)?,
+            })
         }
     }
 
-    impl Synom for FieldsUnnamed {
-        named!(parse -> Self, map!(
-            parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
-            |(paren, fields)| FieldsUnnamed {
-                paren_token: paren,
-                unnamed: fields,
-            }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("unnamed fields in a tuple struct or tuple variant")
+    impl Parse for FieldsUnnamed {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(FieldsUnnamed {
+                paren_token: parenthesized!(content in input),
+                unnamed: content.parse_terminated(Field::parse_unnamed)?,
+            })
         }
     }
 
     impl Field {
-        named!(pub parse_named -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            vis: syn!(Visibility) >>
-            id: syn!(Ident) >>
-            colon: punct!(:) >>
-            ty: syn!(Type) >>
-            (Field {
-                ident: Some(id),
-                vis: vis,
-                attrs: attrs,
-                ty: ty,
-                colon_token: Some(colon),
+        fn parse_named(input: ParseStream) -> Result<Self> {
+            Ok(Field {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                ident: Some(input.parse()?),
+                colon_token: Some(input.parse()?),
+                ty: input.parse()?,
             })
-        ));
+        }
 
-        named!(pub parse_unnamed -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            vis: syn!(Visibility) >>
-            ty: syn!(Type) >>
-            (Field {
+        fn parse_unnamed(input: ParseStream) -> Result<Self> {
+            Ok(Field {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
                 ident: None,
                 colon_token: None,
-                vis: vis,
-                attrs: attrs,
-                ty: ty,
+                ty: input.parse()?,
             })
-        ));
+        }
     }
 
-    impl Synom for Visibility {
-        named!(parse -> Self, alt!(
-            do_parse!(
-                pub_token: keyword!(pub) >>
-                other: parens!(keyword!(crate)) >>
-                (Visibility::Restricted(VisRestricted {
-                    pub_token: pub_token,
-                    paren_token: other.0,
-                    in_token: None,
-                    path: Box::new(other.1.into()),
-                }))
-            )
-            |
-            do_parse!(
-                crate_token: keyword!(crate) >>
-                not!(punct!(::)) >>
-                (Visibility::Crate(VisCrate {
-                    crate_token: crate_token,
-                }))
-            )
-            |
-            do_parse!(
-                pub_token: keyword!(pub) >>
-                other: parens!(keyword!(self)) >>
-                (Visibility::Restricted(VisRestricted {
-                    pub_token: pub_token,
-                    paren_token: other.0,
-                    in_token: None,
-                    path: Box::new(other.1.into()),
-                }))
-            )
-            |
-            do_parse!(
-                pub_token: keyword!(pub) >>
-                other: parens!(keyword!(super)) >>
-                (Visibility::Restricted(VisRestricted {
-                    pub_token: pub_token,
-                    paren_token: other.0,
-                    in_token: None,
-                    path: Box::new(other.1.into()),
-                }))
-            )
-            |
-            do_parse!(
-                pub_token: keyword!(pub) >>
-                other: parens!(do_parse!(
-                    in_tok: keyword!(in) >>
-                    restricted: call!(Path::parse_mod_style) >>
-                    (in_tok, restricted)
-                )) >>
-                (Visibility::Restricted(VisRestricted {
-                    pub_token: pub_token,
-                    paren_token: other.0,
-                    in_token: Some((other.1).0),
-                    path: Box::new((other.1).1),
-                }))
-            )
-            |
-            keyword!(pub) => { |tok| {
-                Visibility::Public(VisPublic {
-                    pub_token: tok,
-                })
-            } }
-            |
-            epsilon!() => { |_| Visibility::Inherited }
-        ));
+    impl Parse for Visibility {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![pub]) {
+                Self::parse_pub(input)
+            } else if input.peek(Token![crate]) {
+                Self::parse_crate(input)
+            } else {
+                Ok(Visibility::Inherited)
+            }
+        }
+    }
 
-        fn description() -> Option<&'static str> {
-            Some("visibility qualifier such as `pub`")
+    impl Visibility {
+        fn parse_pub(input: ParseStream) -> Result<Self> {
+            let pub_token = input.parse::<Token![pub]>()?;
+
+            if input.peek(token::Paren) {
+                let ahead = input.fork();
+                let mut content;
+                parenthesized!(content in ahead);
+
+                if content.peek(Token![crate])
+                    || content.peek(Token![self])
+                    || content.peek(Token![super])
+                {
+                    return Ok(Visibility::Restricted(VisRestricted {
+                        pub_token: pub_token,
+                        paren_token: parenthesized!(content in input),
+                        in_token: None,
+                        path: Box::new(Path::from(content.parse_synom(Ident::parse_any)?)),
+                    }));
+                } else if content.peek(Token![in]) {
+                    return Ok(Visibility::Restricted(VisRestricted {
+                        pub_token: pub_token,
+                        paren_token: parenthesized!(content in input),
+                        in_token: Some(content.parse()?),
+                        path: Box::new(content.parse_synom(Path::old_parse_mod_style)?),
+                    }));
+                }
+            }
+
+            Ok(Visibility::Public(VisPublic {
+                pub_token: pub_token,
+            }))
+        }
+
+        fn parse_crate(input: ParseStream) -> Result<Self> {
+            if input.peek2(Token![::]) {
+                Ok(Visibility::Inherited)
+            } else {
+                Ok(Visibility::Crate(VisCrate {
+                    crate_token: input.parse()?,
+                }))
+            }
         }
     }
 }
diff --git a/src/derive.rs b/src/derive.rs
index ecef776..e956277 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -79,115 +79,131 @@
 pub mod parsing {
     use super::*;
 
-    use synom::Synom;
+    use parse::{Parse, ParseStream, Result};
 
-    enum DeriveInputKind {
-        Struct(Token![struct]),
-        Enum(Token![enum]),
-        Union(Token![union]),
-    }
+    impl Parse for DeriveInput {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let vis = input.parse::<Visibility>()?;
 
-    impl Synom for DeriveInputKind {
-        named!(parse -> Self, alt!(
-            keyword!(struct) => { DeriveInputKind::Struct }
-            |
-            keyword!(enum) => { DeriveInputKind::Enum }
-            |
-            keyword!(union) => { DeriveInputKind::Union }
-        ));
-    }
-
-    impl Synom for DeriveInput {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            vis: syn!(Visibility) >>
-            which: syn!(DeriveInputKind) >>
-            id: syn!(Ident) >>
-            generics: syn!(Generics) >>
-            item: switch!(value!(which),
-                DeriveInputKind::Struct(s) => map!(data_struct, move |(wh, fields, semi)| DeriveInput {
-                    ident: id,
-                    vis: vis,
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Token![struct]) {
+                let struct_token = input.parse::<Token![struct]>()?;
+                let ident = input.parse::<Ident>()?;
+                let generics = input.parse::<Generics>()?;
+                let (where_clause, fields, semi) = data_struct(input)?;
+                Ok(DeriveInput {
                     attrs: attrs,
+                    vis: vis,
+                    ident: ident,
                     generics: Generics {
-                        where_clause: wh,
+                        where_clause: where_clause,
                         ..generics
                     },
                     data: Data::Struct(DataStruct {
-                        struct_token: s,
+                        struct_token: struct_token,
                         fields: fields,
                         semi_token: semi,
                     }),
                 })
-                |
-                DeriveInputKind::Enum(e) => map!(data_enum, move |(wh, brace, variants)| DeriveInput {
-                    ident: id,
-                    vis: vis,
+            } else if lookahead.peek(Token![enum]) {
+                let enum_token = input.parse::<Token![enum]>()?;
+                let ident = input.parse::<Ident>()?;
+                let generics = input.parse::<Generics>()?;
+                let (where_clause, brace, variants) = data_enum(input)?;
+                Ok(DeriveInput {
                     attrs: attrs,
+                    vis: vis,
+                    ident: ident,
                     generics: Generics {
-                        where_clause: wh,
+                        where_clause: where_clause,
                         ..generics
                     },
                     data: Data::Enum(DataEnum {
-                        variants: variants,
+                        enum_token: enum_token,
                         brace_token: brace,
-                        enum_token: e,
+                        variants: variants,
                     }),
                 })
-                |
-                DeriveInputKind::Union(u) => map!(data_union, move |(wh, fields)| DeriveInput {
-                    ident: id,
-                    vis: vis,
+            } else if lookahead.peek(Token![union]) {
+                let union_token = input.parse::<Token![union]>()?;
+                let ident = input.parse::<Ident>()?;
+                let generics = input.parse::<Generics>()?;
+                let (where_clause, fields) = data_union(input)?;
+                Ok(DeriveInput {
                     attrs: attrs,
+                    vis: vis,
+                    ident: ident,
                     generics: Generics {
-                        where_clause: wh,
+                        where_clause: where_clause,
                         ..generics
                     },
                     data: Data::Union(DataUnion {
-                        union_token: u,
+                        union_token: union_token,
                         fields: fields,
                     }),
                 })
-            ) >>
-            (item)
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("derive input")
+            } else {
+                Err(lookahead.error())
+            }
         }
     }
 
-    named!(data_struct -> (Option<WhereClause>, Fields, Option<Token![;]>), alt!(
-        do_parse!(
-            wh: option!(syn!(WhereClause)) >>
-            fields: syn!(FieldsNamed) >>
-            (wh, Fields::Named(fields), None)
-        )
-        |
-        do_parse!(
-            fields: syn!(FieldsUnnamed) >>
-            wh: option!(syn!(WhereClause)) >>
-            semi: punct!(;) >>
-            (wh, Fields::Unnamed(fields), Some(semi))
-        )
-        |
-        do_parse!(
-            wh: option!(syn!(WhereClause)) >>
-            semi: punct!(;) >>
-            (wh, Fields::Unit, Some(semi))
-        )
-    ));
+    fn data_struct(input: ParseStream) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)> {
+        let mut lookahead = input.lookahead1();
+        let mut where_clause = None;
+        if lookahead.peek(Token![where]) {
+            where_clause = Some(input.parse()?);
+            lookahead = input.lookahead1();
+        }
 
-    named!(data_enum -> (Option<WhereClause>, token::Brace, Punctuated<Variant, Token![,]>), do_parse!(
-        wh: option!(syn!(WhereClause)) >>
-        data: braces!(Punctuated::parse_terminated) >>
-        (wh, data.0, data.1)
-    ));
+        if where_clause.is_none() && lookahead.peek(token::Paren) {
+            let fields = input.parse()?;
 
-    named!(data_union -> (Option<WhereClause>, FieldsNamed), tuple!(
-        option!(syn!(WhereClause)),
-        syn!(FieldsNamed),
-    ));
+            lookahead = input.lookahead1();
+            if lookahead.peek(Token![where]) {
+                where_clause = Some(input.parse()?);
+                lookahead = input.lookahead1();
+            }
+
+            if lookahead.peek(Token![;]) {
+                let semi = input.parse()?;
+                Ok((where_clause, Fields::Unnamed(fields), Some(semi)))
+            } else {
+                Err(lookahead.error())
+            }
+        } else if lookahead.peek(token::Brace) {
+            let fields = input.parse()?;
+            Ok((where_clause, Fields::Named(fields), None))
+        } else if lookahead.peek(Token![;]) {
+            let semi = input.parse()?;
+            Ok((where_clause, Fields::Unit, Some(semi)))
+        } else {
+            Err(lookahead.error())
+        }
+    }
+
+    fn data_enum(
+        input: ParseStream,
+    ) -> Result<(
+        Option<WhereClause>,
+        token::Brace,
+        Punctuated<Variant, Token![,]>,
+    )> {
+        let where_clause = input.parse()?;
+
+        let content;
+        let brace = braced!(content in input);
+        let variants = content.parse_terminated(<Variant as Parse>::parse)?;
+
+        Ok((where_clause, brace, variants))
+    }
+
+    fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
+        let where_clause = input.parse()?;
+        let fields = input.parse()?;
+        Ok((where_clause, fields))
+    }
 }
 
 #[cfg(feature = "printing")]
diff --git a/src/error.rs b/src/error.rs
index 6673aa3..8232cce 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -6,9 +6,102 @@
 // 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(),
+        }
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    /// 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 +110,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/export.rs b/src/export.rs
new file mode 100644
index 0000000..cceed14
--- /dev/null
+++ b/src/export.rs
@@ -0,0 +1,4 @@
+pub use std::result::Result::{Err, Ok};
+
+#[cfg(feature = "proc-macro")]
+pub use proc_macro::TokenStream;
diff --git a/src/expr.rs b/src/expr.rs
index 3742fb4..2be23fd 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -313,6 +313,7 @@
         /// *This type is available if Syn is built with the `"full"` feature.*
         pub Closure(ExprClosure #full {
             pub attrs: Vec<Attribute>,
+            pub asyncness: Option<Token![async]>,
             pub movability: Option<Token![static]>,
             pub capture: Option<Token![move]>,
             pub or1_token: Token![|],
@@ -336,6 +337,7 @@
         /// *This type is available if Syn is built with the `"full"` feature.*
         pub Block(ExprBlock #full {
             pub attrs: Vec<Attribute>,
+            pub label: Option<Label>,
             pub block: Block,
         }),
 
@@ -508,13 +510,22 @@
             pub question_token: Token![?],
         }),
 
-        /// A catch expression: `do catch { ... }`.
+        /// An async block: `async { ... }`.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
-        pub Catch(ExprCatch #full {
+        pub Async(ExprAsync #full {
             pub attrs: Vec<Attribute>,
-            pub do_token: Token![do],
-            pub catch_token: Token![catch],
+            pub async_token: Token![async],
+            pub capture: Option<Token![move]>,
+            pub block: Block,
+        }),
+
+        /// A try block: `try { ... }`.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub TryBlock(ExprTryBlock #full {
+            pub attrs: Vec<Attribute>,
+            pub try_token: Token![try],
             pub block: Block,
         }),
 
@@ -600,7 +611,8 @@
             | Expr::Paren(ExprParen { ref mut attrs, .. })
             | Expr::Group(ExprGroup { ref mut attrs, .. })
             | Expr::Try(ExprTry { ref mut attrs, .. })
-            | Expr::Catch(ExprCatch { ref mut attrs, .. })
+            | Expr::Async(ExprAsync { ref mut attrs, .. })
+            | Expr::TryBlock(ExprTryBlock { ref mut attrs, .. })
             | Expr::Yield(ExprYield { ref mut attrs, .. }) => mem::replace(attrs, new),
             Expr::Verbatim(_) => {
                 // TODO
@@ -1008,7 +1020,8 @@
         | Expr::WhileLet(..)
         | Expr::Loop(..)
         | Expr::ForLoop(..)
-        | Expr::Catch(..) => false,
+        | Expr::Async(..)
+        | Expr::TryBlock(..) => false,
         _ => true,
     }
 }
@@ -1016,7 +1029,7 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use path::parsing::mod_style_path_segment;
+    use path::parsing::old_mod_style_path_segment;
     #[cfg(feature = "full")]
     use path::parsing::ty_no_eq_after;
 
@@ -1139,7 +1152,7 @@
             )
             |
             do_parse!(
-                op: call!(BinOp::parse_assign_op) >>
+                op: shim!(BinOp::parse_assign_op) >>
                 // Recurse into self to parse right-associative operator.
                 rhs: call!(assign_expr, allow_struct, true) >>
                 ({
@@ -1334,7 +1347,7 @@
                 as_: keyword!(as) >>
                 // We can't accept `A + B` in cast expressions, as it's
                 // ambiguous with the + expression.
-                ty: call!(Type::without_plus) >>
+                ty: shim!(Type::without_plus) >>
                 ({
                     e = ExprCast {
                         attrs: Vec::new(),
@@ -1349,7 +1362,7 @@
                 colon: punct!(:) >>
                 // We can't accept `A + B` in cast expressions, as it's
                 // ambiguous with the + expression.
-                ty: call!(Type::without_plus) >>
+                ty: shim!(Type::without_plus) >>
                 ({
                     e = ExprType {
                         attrs: Vec::new(),
@@ -1371,7 +1384,7 @@
             as_: keyword!(as) >>
             // We can't accept `A + B` in cast expressions, as it's
             // ambiguous with the + expression.
-            ty: call!(Type::without_plus) >>
+            ty: shim!(Type::without_plus) >>
             ({
                 e = ExprCast {
                     attrs: Vec::new(),
@@ -1391,7 +1404,7 @@
     #[cfg(feature = "full")]
     named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
         do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             op: syn!(UnOp) >>
             expr: call!(unary_expr, allow_struct, true) >>
             (ExprUnary {
@@ -1402,7 +1415,7 @@
         )
         |
         do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             and: punct!(&) >>
             mutability: option!(keyword!(mut)) >>
             expr: call!(unary_expr, allow_struct, true) >>
@@ -1415,7 +1428,7 @@
         )
         |
         do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             box_: keyword!(box) >>
             expr: call!(unary_expr, allow_struct, true) >>
             (ExprBox {
@@ -1571,10 +1584,10 @@
         syn!(ExprLit) => { Expr::Lit } // must be before expr_struct
         |
         // must be before ExprStruct
-        call!(unstable_async_block) => { Expr::Verbatim }
+        syn!(ExprAsync) => { Expr::Async }
         |
         // must be before ExprStruct
-        call!(unstable_try_block) => { Expr::Verbatim }
+        syn!(ExprTryBlock) => { Expr::TryBlock }
         |
         // must be before expr_path
         cond_reduce!(allow_struct, syn!(ExprStruct)) => { Expr::Struct }
@@ -1607,8 +1620,6 @@
         |
         syn!(ExprMatch) => { Expr::Match }
         |
-        syn!(ExprCatch) => { Expr::Catch }
-        |
         syn!(ExprYield) => { Expr::Yield }
         |
         syn!(ExprUnsafe) => { Expr::Unsafe }
@@ -1617,8 +1628,6 @@
         |
         cond_reduce!(allow_block, syn!(ExprBlock)) => { Expr::Block }
         |
-        call!(unstable_labeled_block) => { Expr::Verbatim }
-        |
         // NOTE: This is the prefix-form of range
         call!(expr_range, allow_struct)
         |
@@ -1653,15 +1662,13 @@
             |
             syn!(ExprMatch) => { Expr::Match }
             |
-            syn!(ExprCatch) => { Expr::Catch }
+            syn!(ExprTryBlock) => { Expr::TryBlock }
             |
             syn!(ExprYield) => { Expr::Yield }
             |
             syn!(ExprUnsafe) => { Expr::Unsafe }
             |
             syn!(ExprBlock) => { Expr::Block }
-            |
-            call!(unstable_labeled_block) => { Expr::Verbatim }
         ) >>
         // If the next token is a `.` or a `?` it is special-cased to parse
         // as an expression instead of a blockexpression.
@@ -1682,7 +1689,7 @@
 
         #[cfg(feature = "full")]
         named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             lit: syn!(Lit) >>
             (ExprLit {
                 attrs: attrs,
@@ -1698,7 +1705,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprMacro {
         named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             mac: syn!(Macro) >>
             (ExprMacro {
                 attrs: attrs,
@@ -1714,7 +1721,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprGroup {
         named!(parse -> Self, do_parse!(
-            e: grouped!(syn!(Expr)) >>
+            e: old_grouped!(syn!(Expr)) >>
             (ExprGroup {
                 attrs: Vec::new(),
                 expr: Box::new(e.1),
@@ -1740,9 +1747,9 @@
 
         #[cfg(feature = "full")]
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             e: parens!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 syn!(Expr),
             )) >>
             (ExprParen {
@@ -1764,9 +1771,9 @@
     #[cfg(feature = "full")]
     impl Synom for ExprArray {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             elems: brackets!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Punctuated::parse_terminated),
             )) >>
             (ExprArray {
@@ -1835,9 +1842,9 @@
     #[cfg(feature = "full")]
     impl Synom for ExprTuple {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             elems: parens!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Punctuated::parse_terminated),
             )) >>
             (ExprTuple {
@@ -1922,6 +1929,7 @@
                 else_block: braces!(Block::parse_within) >>
                 (Expr::Block(ExprBlock {
                     attrs: Vec::new(),
+                    label: None,
                     block: Block {
                         brace_token: else_block.0,
                         stmts: else_block.1,
@@ -1935,14 +1943,14 @@
     #[cfg(feature = "full")]
     impl Synom for ExprForLoop {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             label: option!(syn!(Label)) >>
             for_: keyword!(for) >>
             pat: syn!(Pat) >>
             in_: keyword!(in) >>
             expr: expr_no_struct >>
             block: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Block::parse_within),
             )) >>
             (ExprForLoop {
@@ -1971,11 +1979,11 @@
     #[cfg(feature = "full")]
     impl Synom for ExprLoop {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             label: option!(syn!(Label)) >>
             loop_: keyword!(loop) >>
             block: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Block::parse_within),
             )) >>
             (ExprLoop {
@@ -2001,11 +2009,11 @@
     #[cfg(feature = "full")]
     impl Synom for ExprMatch {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             match_: keyword!(match) >>
             obj: expr_no_struct >>
             braced_content: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 many0!(syn!(Arm)),
             )) >>
             (ExprMatch {
@@ -2027,21 +2035,19 @@
     }
 
     #[cfg(feature = "full")]
-    impl Synom for ExprCatch {
+    impl Synom for ExprTryBlock {
         named!(parse -> Self, do_parse!(
-            do_: keyword!(do) >>
-            catch_: keyword!(catch) >>
-            catch_block: syn!(Block) >>
-            (ExprCatch {
+            try_token: keyword!(try) >>
+            block: syn!(Block) >>
+            (ExprTryBlock {
                 attrs: Vec::new(),
-                block: catch_block,
-                do_token: do_,
-                catch_token: catch_,
+                try_token: try_token,
+                block: block,
             })
         ));
 
         fn description() -> Option<&'static str> {
-            Some("`catch` expression")
+            Some("`try` block")
         }
     }
 
@@ -2065,7 +2071,7 @@
     #[cfg(feature = "full")]
     impl Synom for Arm {
         named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             leading_vert: option!(punct!(|)) >>
             pats: call!(Punctuated::parse_separated_nonempty) >>
             guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
@@ -2101,8 +2107,7 @@
 
     #[cfg(feature = "full")]
     named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         asyncness: option!(keyword!(async)) >>
         movability: option!(cond_reduce!(asyncness.is_none(), keyword!(static))) >>
         capture: option!(keyword!(move)) >>
@@ -2118,6 +2123,7 @@
                     ReturnType::Type(arrow, Box::new(ty)),
                     Expr::Block(ExprBlock {
                         attrs: Vec::new(),
+                        label: None,
                         block: body,
                     },
                 ))
@@ -2125,53 +2131,34 @@
             |
             map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
         ) >>
-        end: call!(verbatim::grab_cursor) >>
-        ({
-            if asyncness.is_some() {
-                // TODO: include asyncness in ExprClosure
-                // https://github.com/dtolnay/syn/issues/396
-                Expr::Verbatim(ExprVerbatim {
-                    tts: verbatim::token_range(begin..end),
-                })
-            } else {
-                Expr::Closure(ExprClosure {
-                    attrs: attrs,
-                    movability: movability,
-                    capture: capture,
-                    or1_token: or1,
-                    inputs: inputs,
-                    or2_token: or2,
-                    output: ret_and_body.0,
-                    body: Box::new(ret_and_body.1),
-                })
-            }
-        })
+        (Expr::Closure(ExprClosure {
+            attrs: attrs,
+            asyncness: asyncness,
+            movability: movability,
+            capture: capture,
+            or1_token: or1,
+            inputs: inputs,
+            or2_token: or2,
+            output: ret_and_body.0,
+            body: Box::new(ret_and_body.1),
+        }))
     ));
 
     #[cfg(feature = "full")]
-    named!(unstable_async_block -> ExprVerbatim, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        keyword!(async) >>
-        option!(keyword!(move)) >>
-        syn!(Block) >>
-        end: call!(verbatim::grab_cursor) >>
-        (ExprVerbatim {
-            tts: verbatim::token_range(begin..end),
-        })
-    ));
-
-    #[cfg(feature = "full")]
-    named!(unstable_try_block -> ExprVerbatim, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        keyword!(try) >>
-        syn!(Block) >>
-        end: call!(verbatim::grab_cursor) >>
-        (ExprVerbatim {
-            tts: verbatim::token_range(begin..end),
-        })
-    ));
+    impl Synom for ExprAsync {
+        named!(parse -> Self, do_parse!(
+            attrs: many0!(Attribute::old_parse_outer) >>
+            async_token: keyword!(async) >>
+            capture: option!(keyword!(move)) >>
+            block: syn!(Block) >>
+            (ExprAsync {
+                attrs: attrs,
+                async_token: async_token,
+                capture: capture,
+                block: block,
+            })
+        ));
+    }
 
     #[cfg(feature = "full")]
     named!(fn_arg -> FnArg, do_parse!(
@@ -2193,12 +2180,12 @@
     #[cfg(feature = "full")]
     impl Synom for ExprWhile {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             label: option!(syn!(Label)) >>
             while_: keyword!(while) >>
             cond: expr_no_struct >>
             block: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Block::parse_within),
             )) >>
             (ExprWhile {
@@ -2225,7 +2212,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprWhileLet {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             label: option!(syn!(Label)) >>
             while_: keyword!(while) >>
             let_: keyword!(let) >>
@@ -2233,7 +2220,7 @@
             eq: punct!(=) >>
             value: expr_no_struct >>
             block: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Block::parse_within),
             )) >>
             (ExprWhileLet {
@@ -2279,7 +2266,7 @@
     #[cfg(feature = "full")]
     impl Synom for ExprContinue {
         named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             cont: keyword!(continue) >>
             label: option!(syn!(Lifetime)) >>
             (ExprContinue {
@@ -2296,7 +2283,7 @@
 
     #[cfg(feature = "full")]
     named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         break_: keyword!(break) >>
         label: option!(syn!(Lifetime)) >>
         // We can't allow blocks after a `break` expression when we wouldn't
@@ -2312,7 +2299,7 @@
 
     #[cfg(feature = "full")]
     named!(expr_ret(allow_struct: bool) -> Expr, do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         return_: keyword!(return) >>
         // NOTE: return is greedy and eats blocks after it even when in a
         // position where structs are not allowed, such as in if statement
@@ -2330,10 +2317,10 @@
     #[cfg(feature = "full")]
     impl Synom for ExprStruct {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             path: syn!(Path) >>
             data: braces!(do_parse!(
-                inner_attrs: many0!(Attribute::parse_inner) >>
+                inner_attrs: many0!(Attribute::old_parse_inner) >>
                 fields: call!(Punctuated::parse_terminated) >>
                 base: option!(cond!(fields.empty_or_trailing(), do_parse!(
                     dots: punct!(..) >>
@@ -2371,7 +2358,7 @@
     #[cfg(feature = "full")]
     impl Synom for FieldValue {
         named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             field_value: alt!(
                 tuple!(syn!(Member), map!(punct!(:), Some), syn!(Expr))
                 |
@@ -2401,9 +2388,9 @@
     #[cfg(feature = "full")]
     impl Synom for ExprRepeat {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             data: brackets!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 syn!(Expr),
                 punct!(;),
                 syn!(Expr),
@@ -2429,10 +2416,10 @@
     #[cfg(feature = "full")]
     impl Synom for ExprUnsafe {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
             unsafe_: keyword!(unsafe) >>
             block: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Block::parse_within),
             )) >>
             (ExprUnsafe {
@@ -2457,9 +2444,10 @@
     #[cfg(feature = "full")]
     impl Synom for ExprBlock {
         named!(parse -> Self, do_parse!(
-            outer_attrs: many0!(Attribute::parse_outer) >>
+            outer_attrs: many0!(Attribute::old_parse_outer) >>
+            label: option!(syn!(Label)) >>
             block: braces!(tuple!(
-                many0!(Attribute::parse_inner),
+                many0!(Attribute::old_parse_inner),
                 call!(Block::parse_within),
             )) >>
             (ExprBlock {
@@ -2468,6 +2456,7 @@
                     attrs.extend((block.1).0);
                     attrs
                 },
+                label: label,
                 block: Block {
                     brace_token: block.0,
                     stmts: (block.1).1,
@@ -2481,21 +2470,6 @@
     }
 
     #[cfg(feature = "full")]
-    named!(unstable_labeled_block -> ExprVerbatim, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        syn!(Label) >>
-        braces!(tuple!(
-            many0!(Attribute::parse_inner),
-            call!(Block::parse_within),
-        )) >>
-        end: call!(verbatim::grab_cursor) >>
-        (ExprVerbatim {
-            tts: verbatim::token_range(begin..end),
-        })
-    ));
-
-    #[cfg(feature = "full")]
     named!(expr_range(allow_struct: bool) -> Expr, do_parse!(
         limits: syn!(RangeLimits) >>
         hi: opt_ambiguous_expr!(allow_struct) >>
@@ -2514,7 +2488,7 @@
             punct!(..=) => { RangeLimits::Closed }
             |
             // Must come before Dot2
-            punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
+            punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.spans)) }
             |
             punct!(..) => { RangeLimits::HalfOpen }
         ));
@@ -2537,7 +2511,7 @@
 
         #[cfg(feature = "full")]
         named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
+            attrs: many0!(Attribute::old_parse_outer) >>
             pair: qpath >>
             (ExprPath {
                 attrs: attrs,
@@ -2579,7 +2553,7 @@
             })
         )
         |
-        mod_style_path_segment
+        old_mod_style_path_segment
     ));
 
     named!(qpath -> (Option<QSelf>, Path), alt!(
@@ -2649,7 +2623,7 @@
                 (stmt)
             )) >>
             last: option!(do_parse!(
-                attrs: many0!(Attribute::parse_outer) >>
+                attrs: many0!(Attribute::old_parse_outer) >>
                 mut e: syn!(Expr) >>
                 ({
                     e.replace_attrs(attrs);
@@ -2687,8 +2661,8 @@
 
     #[cfg(feature = "full")]
     named!(stmt_mac -> Stmt, do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        what: call!(Path::parse_mod_style) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
+        what: call!(Path::old_parse_mod_style) >>
         bang: punct!(!) >>
     // Only parse braces here; paren and bracket will get parsed as
     // expression statements
@@ -2709,7 +2683,7 @@
 
     #[cfg(feature = "full")]
     named!(stmt_local -> Stmt, do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         let_: keyword!(let) >>
         pats: call!(Punctuated::parse_separated_nonempty) >>
         ty: option!(tuple!(punct!(:), syn!(Type))) >>
@@ -2730,7 +2704,7 @@
 
     #[cfg(feature = "full")]
     named!(stmt_blockexpr -> Stmt, do_parse!(
-        mut attrs: many0!(Attribute::parse_outer) >>
+        mut attrs: many0!(Attribute::old_parse_outer) >>
         mut e: expr_nosemi >>
         semi: option!(punct!(;)) >>
         ({
@@ -2746,7 +2720,7 @@
 
     #[cfg(feature = "full")]
     named!(stmt_expr -> Stmt, do_parse!(
-        mut attrs: many0!(Attribute::parse_outer) >>
+        mut attrs: many0!(Attribute::old_parse_outer) >>
         mut e: syn!(Expr) >>
         semi: punct!(;) >>
         ({
@@ -3103,9 +3077,9 @@
                 let after: Option<Punctuated<Pat, Token![,]>> = after;
                 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
                 PatSlice {
-                    dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
+                    dot2_token: middle.as_ref().map(|m| Token![..](m.0.spans)),
                     comma_token: middle.as_ref().and_then(|m| {
-                        m.1.as_ref().map(|m| Token![,](m.0))
+                        m.1.as_ref().map(|m| Token![,](m.spans))
                     }),
                     bracket_token: brackets,
                     middle: middle.and_then(|_| {
@@ -3433,11 +3407,20 @@
     }
 
     #[cfg(feature = "full")]
-    impl ToTokens for ExprCatch {
+    impl ToTokens for ExprAsync {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
-            self.do_token.to_tokens(tokens);
-            self.catch_token.to_tokens(tokens);
+            self.async_token.to_tokens(tokens);
+            self.capture.to_tokens(tokens);
+            self.block.to_tokens(tokens);
+        }
+    }
+
+    #[cfg(feature = "full")]
+    impl ToTokens for ExprTryBlock {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            outer_attrs_to_tokens(&self.attrs, tokens);
+            self.try_token.to_tokens(tokens);
             self.block.to_tokens(tokens);
         }
     }
@@ -3455,6 +3438,7 @@
     impl ToTokens for ExprClosure {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
+            self.asyncness.to_tokens(tokens);
             self.movability.to_tokens(tokens);
             self.capture.to_tokens(tokens);
             self.or1_token.to_tokens(tokens);
@@ -3493,6 +3477,7 @@
     impl ToTokens for ExprBlock {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
+            self.label.to_tokens(tokens);
             self.block.brace_token.surround(tokens, |tokens| {
                 inner_attrs_to_tokens(&self.attrs, tokens);
                 tokens.append_all(&self.block.stmts);
@@ -3824,7 +3809,7 @@
             self.lo.to_tokens(tokens);
             match self.limits {
                 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
-                RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
+                RangeLimits::Closed(ref t) => Token![...](t.spans).to_tokens(tokens),
             }
             self.hi.to_tokens(tokens);
         }
diff --git a/src/file.rs b/src/file.rs
index 9b5b11f..d692f11 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -88,21 +88,21 @@
 pub mod parsing {
     use super::*;
 
-    use synom::Synom;
+    use parse::{Parse, ParseStream, Result};
 
-    impl Synom for File {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_inner) >>
-            items: many0!(Item::parse) >>
-            (File {
+    impl Parse for File {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(File {
                 shebang: None,
-                attrs: attrs,
-                items: items,
+                attrs: input.call(Attribute::parse_inner)?,
+                items: {
+                    let mut items = Vec::new();
+                    while !input.is_empty() {
+                        items.push(input.parse_synom(Item::parse)?);
+                    }
+                    items
+                },
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("crate")
         }
     }
 }
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 54eb51a..5a5e5bf 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -132,6 +132,11 @@
     fn fold_expr_assign_op(&mut self, i: ExprAssignOp) -> ExprAssignOp {
         fold_expr_assign_op(self, i)
     }
+    #[cfg(feature = "full")]
+    #[cfg(any(feature = "full", feature = "derive"))]
+    fn fold_expr_async(&mut self, i: ExprAsync) -> ExprAsync {
+        fold_expr_async(self, i)
+    }
     #[cfg(any(feature = "full", feature = "derive"))]
     fn fold_expr_binary(&mut self, i: ExprBinary) -> ExprBinary {
         fold_expr_binary(self, i)
@@ -161,11 +166,6 @@
     }
     #[cfg(feature = "full")]
     #[cfg(any(feature = "full", feature = "derive"))]
-    fn fold_expr_catch(&mut self, i: ExprCatch) -> ExprCatch {
-        fold_expr_catch(self, i)
-    }
-    #[cfg(feature = "full")]
-    #[cfg(any(feature = "full", feature = "derive"))]
     fn fold_expr_closure(&mut self, i: ExprClosure) -> ExprClosure {
         fold_expr_closure(self, i)
     }
@@ -271,6 +271,11 @@
     }
     #[cfg(feature = "full")]
     #[cfg(any(feature = "full", feature = "derive"))]
+    fn fold_expr_try_block(&mut self, i: ExprTryBlock) -> ExprTryBlock {
+        fold_expr_try_block(self, i)
+    }
+    #[cfg(feature = "full")]
+    #[cfg(any(feature = "full", feature = "derive"))]
     fn fold_expr_tuple(&mut self, i: ExprTuple) -> ExprTuple {
         fold_expr_tuple(self, i)
     }
@@ -354,6 +359,10 @@
         fold_foreign_item_fn(self, i)
     }
     #[cfg(feature = "full")]
+    fn fold_foreign_item_macro(&mut self, i: ForeignItemMacro) -> ForeignItemMacro {
+        fold_foreign_item_macro(self, i)
+    }
+    #[cfg(feature = "full")]
     fn fold_foreign_item_static(&mut self, i: ForeignItemStatic) -> ForeignItemStatic {
         fold_foreign_item_static(self, i)
     }
@@ -394,6 +403,10 @@
         fold_impl_item_const(self, i)
     }
     #[cfg(feature = "full")]
+    fn fold_impl_item_existential(&mut self, i: ImplItemExistential) -> ImplItemExistential {
+        fold_impl_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn fold_impl_item_macro(&mut self, i: ImplItemMacro) -> ImplItemMacro {
         fold_impl_item_macro(self, i)
     }
@@ -426,6 +439,10 @@
         fold_item_enum(self, i)
     }
     #[cfg(feature = "full")]
+    fn fold_item_existential(&mut self, i: ItemExistential) -> ItemExistential {
+        fold_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn fold_item_extern_crate(&mut self, i: ItemExternCrate) -> ItemExternCrate {
         fold_item_extern_crate(self, i)
     }
@@ -880,7 +897,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi {
     Abi {
-        extern_token: Token![extern](tokens_helper(_visitor, &(_i.extern_token).0)),
+        extern_token: Token![extern](tokens_helper(_visitor, &_i.extern_token.span)),
         name: (_i.name).map(|it| _visitor.fold_lit_str(it)),
     }
 }
@@ -890,34 +907,35 @@
     _i: AngleBracketedGenericArguments,
 ) -> AngleBracketedGenericArguments {
     AngleBracketedGenericArguments {
-        colon2_token: (_i.colon2_token).map(|it| Token ! [ :: ](tokens_helper(_visitor, &(it).0))),
-        lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+        colon2_token: (_i.colon2_token)
+            .map(|it| Token ! [ :: ](tokens_helper(_visitor, &it.spans))),
+        lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
         args: FoldHelper::lift(_i.args, |it| _visitor.fold_generic_argument(it)),
-        gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+        gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
     }
 }
 #[cfg(feature = "full")]
 pub fn fold_arg_captured<V: Fold + ?Sized>(_visitor: &mut V, _i: ArgCaptured) -> ArgCaptured {
     ArgCaptured {
         pat: _visitor.fold_pat(_i.pat),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: _visitor.fold_type(_i.ty),
     }
 }
 #[cfg(feature = "full")]
 pub fn fold_arg_self<V: Fold + ?Sized>(_visitor: &mut V, _i: ArgSelf) -> ArgSelf {
     ArgSelf {
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
-        self_token: Token![self](tokens_helper(_visitor, &(_i.self_token).0)),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
+        self_token: Token![self](tokens_helper(_visitor, &_i.self_token.span)),
     }
 }
 #[cfg(feature = "full")]
 pub fn fold_arg_self_ref<V: Fold + ?Sized>(_visitor: &mut V, _i: ArgSelfRef) -> ArgSelfRef {
     ArgSelfRef {
-        and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
+        and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
         lifetime: (_i.lifetime).map(|it| _visitor.fold_lifetime(it)),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
-        self_token: Token![self](tokens_helper(_visitor, &(_i.self_token).0)),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
+        self_token: Token![self](tokens_helper(_visitor, &_i.self_token.span)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -925,17 +943,17 @@
 pub fn fold_arm<V: Fold + ?Sized>(_visitor: &mut V, _i: Arm) -> Arm {
     Arm {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        leading_vert: (_i.leading_vert).map(|it| Token ! [ | ](tokens_helper(_visitor, &(it).0))),
+        leading_vert: (_i.leading_vert).map(|it| Token ! [ | ](tokens_helper(_visitor, &it.spans))),
         pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
         guard: (_i.guard).map(|it| {
             (
-                Token ! [ if ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ if ](tokens_helper(_visitor, &(it).0.span)),
                 Box::new(_visitor.fold_expr(*(it).1)),
             )
         }),
-        fat_arrow_token: Token ! [ => ](tokens_helper(_visitor, &(_i.fat_arrow_token).0)),
+        fat_arrow_token: Token ! [ => ](tokens_helper(_visitor, &_i.fat_arrow_token.spans)),
         body: Box::new(_visitor.fold_expr(*_i.body)),
-        comma: (_i.comma).map(|it| Token ! [ , ](tokens_helper(_visitor, &(it).0))),
+        comma: (_i.comma).map(|it| Token ! [ , ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -943,19 +961,18 @@
     match _i {
         AttrStyle::Outer => AttrStyle::Outer,
         AttrStyle::Inner(_binding_0) => {
-            AttrStyle::Inner(Token![!](tokens_helper(_visitor, &(_binding_0).0)))
+            AttrStyle::Inner(Token![!](tokens_helper(_visitor, &_binding_0.spans)))
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_attribute<V: Fold + ?Sized>(_visitor: &mut V, _i: Attribute) -> Attribute {
     Attribute {
-        pound_token: Token ! [ # ](tokens_helper(_visitor, &(_i.pound_token).0)),
+        pound_token: Token ! [ # ](tokens_helper(_visitor, &_i.pound_token.spans)),
         style: _visitor.fold_attr_style(_i.style),
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         path: _visitor.fold_path(_i.path),
         tts: _i.tts,
-        is_sugared_doc: _i.is_sugared_doc,
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -964,7 +981,7 @@
         name: (_i.name).map(|it| {
             (
                 _visitor.fold_bare_fn_arg_name((it).0),
-                Token ! [ : ](tokens_helper(_visitor, &((it).1).0)),
+                Token ! [ : ](tokens_helper(_visitor, &(it).1.spans)),
             )
         }),
         ty: _visitor.fold_type(_i.ty),
@@ -978,7 +995,7 @@
     match _i {
         BareFnArgName::Named(_binding_0) => BareFnArgName::Named(_visitor.fold_ident(_binding_0)),
         BareFnArgName::Wild(_binding_0) => {
-            BareFnArgName::Wild(Token![_](tokens_helper(_visitor, &(_binding_0).0)))
+            BareFnArgName::Wild(Token![_](tokens_helper(_visitor, &_binding_0.spans)))
         }
     }
 }
@@ -986,84 +1003,88 @@
 pub fn fold_bin_op<V: Fold + ?Sized>(_visitor: &mut V, _i: BinOp) -> BinOp {
     match _i {
         BinOp::Add(_binding_0) => {
-            BinOp::Add(Token ! [ + ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Add(Token ! [ + ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Sub(_binding_0) => {
-            BinOp::Sub(Token ! [ - ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Sub(Token ! [ - ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Mul(_binding_0) => {
-            BinOp::Mul(Token ! [ * ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Mul(Token ! [ * ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Div(_binding_0) => {
-            BinOp::Div(Token ! [ / ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Div(Token ! [ / ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Rem(_binding_0) => {
-            BinOp::Rem(Token ! [ % ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Rem(Token ! [ % ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::And(_binding_0) => {
-            BinOp::And(Token ! [ && ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::And(Token ! [ && ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Or(_binding_0) => {
-            BinOp::Or(Token ! [ || ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Or(Token ! [ || ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::BitXor(_binding_0) => {
-            BinOp::BitXor(Token ! [ ^ ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::BitXor(Token ! [ ^ ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::BitAnd(_binding_0) => {
-            BinOp::BitAnd(Token ! [ & ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::BitAnd(Token ! [ & ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::BitOr(_binding_0) => {
-            BinOp::BitOr(Token ! [ | ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::BitOr(Token ! [ | ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Shl(_binding_0) => {
-            BinOp::Shl(Token ! [ << ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Shl(Token ! [ << ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Shr(_binding_0) => {
-            BinOp::Shr(Token ! [ >> ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Shr(Token ! [ >> ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Eq(_binding_0) => {
-            BinOp::Eq(Token ! [ == ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Eq(Token ! [ == ](tokens_helper(_visitor, &_binding_0.spans)))
         }
-        BinOp::Lt(_binding_0) => BinOp::Lt(Token ! [ < ](tokens_helper(_visitor, &(_binding_0).0))),
+        BinOp::Lt(_binding_0) => {
+            BinOp::Lt(Token ! [ < ](tokens_helper(_visitor, &_binding_0.spans)))
+        }
         BinOp::Le(_binding_0) => {
-            BinOp::Le(Token ! [ <= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Le(Token ! [ <= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Ne(_binding_0) => {
-            BinOp::Ne(Token ! [ != ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Ne(Token ! [ != ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::Ge(_binding_0) => {
-            BinOp::Ge(Token ! [ >= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::Ge(Token ! [ >= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
-        BinOp::Gt(_binding_0) => BinOp::Gt(Token ! [ > ](tokens_helper(_visitor, &(_binding_0).0))),
+        BinOp::Gt(_binding_0) => {
+            BinOp::Gt(Token ! [ > ](tokens_helper(_visitor, &_binding_0.spans)))
+        }
         BinOp::AddEq(_binding_0) => {
-            BinOp::AddEq(Token ! [ += ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::AddEq(Token ! [ += ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::SubEq(_binding_0) => {
-            BinOp::SubEq(Token ! [ -= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::SubEq(Token ! [ -= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::MulEq(_binding_0) => {
-            BinOp::MulEq(Token ! [ *= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::MulEq(Token ! [ *= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::DivEq(_binding_0) => {
-            BinOp::DivEq(Token ! [ /= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::DivEq(Token ! [ /= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::RemEq(_binding_0) => {
-            BinOp::RemEq(Token ! [ %= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::RemEq(Token ! [ %= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::BitXorEq(_binding_0) => {
-            BinOp::BitXorEq(Token ! [ ^= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::BitXorEq(Token ! [ ^= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::BitAndEq(_binding_0) => {
-            BinOp::BitAndEq(Token ! [ &= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::BitAndEq(Token ! [ &= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::BitOrEq(_binding_0) => {
-            BinOp::BitOrEq(Token ! [ |= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::BitOrEq(Token ! [ |= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::ShlEq(_binding_0) => {
-            BinOp::ShlEq(Token ! [ <<= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::ShlEq(Token ! [ <<= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
         BinOp::ShrEq(_binding_0) => {
-            BinOp::ShrEq(Token ! [ >>= ](tokens_helper(_visitor, &(_binding_0).0)))
+            BinOp::ShrEq(Token ! [ >>= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
     }
 }
@@ -1071,7 +1092,7 @@
 pub fn fold_binding<V: Fold + ?Sized>(_visitor: &mut V, _i: Binding) -> Binding {
     Binding {
         ident: _visitor.fold_ident(_i.ident),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         ty: _visitor.fold_type(_i.ty),
     }
 }
@@ -1079,7 +1100,7 @@
 #[cfg(feature = "full")]
 pub fn fold_block<V: Fold + ?Sized>(_visitor: &mut V, _i: Block) -> Block {
     Block {
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         stmts: FoldHelper::lift(_i.stmts, |it| _visitor.fold_stmt(it)),
     }
 }
@@ -1089,21 +1110,21 @@
     _i: BoundLifetimes,
 ) -> BoundLifetimes {
     BoundLifetimes {
-        for_token: Token ! [ for ](tokens_helper(_visitor, &(_i.for_token).0)),
-        lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+        for_token: Token ! [ for ](tokens_helper(_visitor, &_i.for_token.span)),
+        lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
         lifetimes: FoldHelper::lift(_i.lifetimes, |it| _visitor.fold_lifetime_def(it)),
-        gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+        gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_const_param<V: Fold + ?Sized>(_visitor: &mut V, _i: ConstParam) -> ConstParam {
     ConstParam {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+        const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: _visitor.fold_type(_i.ty),
-        eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &(it).0))),
+        eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &it.spans))),
         default: (_i.default).map(|it| _visitor.fold_expr(it)),
     }
 }
@@ -1118,23 +1139,23 @@
 #[cfg(feature = "derive")]
 pub fn fold_data_enum<V: Fold + ?Sized>(_visitor: &mut V, _i: DataEnum) -> DataEnum {
     DataEnum {
-        enum_token: Token ! [ enum ](tokens_helper(_visitor, &(_i.enum_token).0)),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        enum_token: Token ! [ enum ](tokens_helper(_visitor, &_i.enum_token.span)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         variants: FoldHelper::lift(_i.variants, |it| _visitor.fold_variant(it)),
     }
 }
 #[cfg(feature = "derive")]
 pub fn fold_data_struct<V: Fold + ?Sized>(_visitor: &mut V, _i: DataStruct) -> DataStruct {
     DataStruct {
-        struct_token: Token ! [ struct ](tokens_helper(_visitor, &(_i.struct_token).0)),
+        struct_token: Token ! [ struct ](tokens_helper(_visitor, &_i.struct_token.span)),
         fields: _visitor.fold_fields(_i.fields),
-        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "derive")]
 pub fn fold_data_union<V: Fold + ?Sized>(_visitor: &mut V, _i: DataUnion) -> DataUnion {
     DataUnion {
-        union_token: Token![union](tokens_helper(_visitor, &(_i.union_token).0)),
+        union_token: Token![union](tokens_helper(_visitor, &_i.union_token.span)),
         fields: _visitor.fold_fields_named(_i.fields),
     }
 }
@@ -1198,7 +1219,10 @@
         Expr::Paren(_binding_0) => Expr::Paren(_visitor.fold_expr_paren(_binding_0)),
         Expr::Group(_binding_0) => Expr::Group(full!(_visitor.fold_expr_group(_binding_0))),
         Expr::Try(_binding_0) => Expr::Try(full!(_visitor.fold_expr_try(_binding_0))),
-        Expr::Catch(_binding_0) => Expr::Catch(full!(_visitor.fold_expr_catch(_binding_0))),
+        Expr::Async(_binding_0) => Expr::Async(full!(_visitor.fold_expr_async(_binding_0))),
+        Expr::TryBlock(_binding_0) => {
+            Expr::TryBlock(full!(_visitor.fold_expr_try_block(_binding_0)))
+        }
         Expr::Yield(_binding_0) => Expr::Yield(full!(_visitor.fold_expr_yield(_binding_0))),
         Expr::Verbatim(_binding_0) => Expr::Verbatim(_visitor.fold_expr_verbatim(_binding_0)),
     }
@@ -1208,7 +1232,7 @@
 pub fn fold_expr_array<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprArray) -> ExprArray {
     ExprArray {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         elems: FoldHelper::lift(_i.elems, |it| _visitor.fold_expr(it)),
     }
 }
@@ -1218,7 +1242,7 @@
     ExprAssign {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         left: Box::new(_visitor.fold_expr(*_i.left)),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         right: Box::new(_visitor.fold_expr(*_i.right)),
     }
 }
@@ -1232,6 +1256,16 @@
         right: Box::new(_visitor.fold_expr(*_i.right)),
     }
 }
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn fold_expr_async<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprAsync) -> ExprAsync {
+    ExprAsync {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        async_token: Token![async](tokens_helper(_visitor, &_i.async_token.span)),
+        capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &it.span))),
+        block: _visitor.fold_block(_i.block),
+    }
+}
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_expr_binary<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBinary) -> ExprBinary {
     ExprBinary {
@@ -1246,6 +1280,7 @@
 pub fn fold_expr_block<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBlock) -> ExprBlock {
     ExprBlock {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        label: (_i.label).map(|it| _visitor.fold_label(it)),
         block: _visitor.fold_block(_i.block),
     }
 }
@@ -1254,7 +1289,7 @@
 pub fn fold_expr_box<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBox) -> ExprBox {
     ExprBox {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        box_token: Token ! [ box ](tokens_helper(_visitor, &(_i.box_token).0)),
+        box_token: Token ! [ box ](tokens_helper(_visitor, &_i.box_token.span)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
     }
 }
@@ -1263,7 +1298,7 @@
 pub fn fold_expr_break<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBreak) -> ExprBreak {
     ExprBreak {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        break_token: Token![break](tokens_helper(_visitor, &(_i.break_token).0)),
+        break_token: Token![break](tokens_helper(_visitor, &_i.break_token.span)),
         label: (_i.label).map(|it| _visitor.fold_lifetime(it)),
         expr: (_i.expr).map(|it| Box::new(_visitor.fold_expr(*it))),
     }
@@ -1273,7 +1308,7 @@
     ExprCall {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         func: Box::new(_visitor.fold_expr(*_i.func)),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         args: FoldHelper::lift(_i.args, |it| _visitor.fold_expr(it)),
     }
 }
@@ -1282,30 +1317,21 @@
     ExprCast {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        as_token: Token ! [ as ](tokens_helper(_visitor, &(_i.as_token).0)),
+        as_token: Token ! [ as ](tokens_helper(_visitor, &_i.as_token.span)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
     }
 }
 #[cfg(feature = "full")]
 #[cfg(any(feature = "full", feature = "derive"))]
-pub fn fold_expr_catch<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprCatch) -> ExprCatch {
-    ExprCatch {
-        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        do_token: Token ! [ do ](tokens_helper(_visitor, &(_i.do_token).0)),
-        catch_token: Token![catch](tokens_helper(_visitor, &(_i.catch_token).0)),
-        block: _visitor.fold_block(_i.block),
-    }
-}
-#[cfg(feature = "full")]
-#[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_expr_closure<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprClosure) -> ExprClosure {
     ExprClosure {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        movability: (_i.movability).map(|it| Token ! [ static ](tokens_helper(_visitor, &(it).0))),
-        capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &(it).0))),
-        or1_token: Token ! [ | ](tokens_helper(_visitor, &(_i.or1_token).0)),
+        asyncness: (_i.asyncness).map(|it| Token![async](tokens_helper(_visitor, &it.span))),
+        movability: (_i.movability).map(|it| Token ! [ static ](tokens_helper(_visitor, &it.span))),
+        capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &it.span))),
+        or1_token: Token ! [ | ](tokens_helper(_visitor, &_i.or1_token.spans)),
         inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_fn_arg(it)),
-        or2_token: Token ! [ | ](tokens_helper(_visitor, &(_i.or2_token).0)),
+        or2_token: Token ! [ | ](tokens_helper(_visitor, &_i.or2_token.spans)),
         output: _visitor.fold_return_type(_i.output),
         body: Box::new(_visitor.fold_expr(*_i.body)),
     }
@@ -1315,7 +1341,7 @@
 pub fn fold_expr_continue<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprContinue) -> ExprContinue {
     ExprContinue {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        continue_token: Token![continue](tokens_helper(_visitor, &(_i.continue_token).0)),
+        continue_token: Token![continue](tokens_helper(_visitor, &_i.continue_token.span)),
         label: (_i.label).map(|it| _visitor.fold_lifetime(it)),
     }
 }
@@ -1324,7 +1350,7 @@
     ExprField {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         base: Box::new(_visitor.fold_expr(*_i.base)),
-        dot_token: Token ! [ . ](tokens_helper(_visitor, &(_i.dot_token).0)),
+        dot_token: Token ! [ . ](tokens_helper(_visitor, &_i.dot_token.spans)),
         member: _visitor.fold_member(_i.member),
     }
 }
@@ -1334,9 +1360,9 @@
     ExprForLoop {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         label: (_i.label).map(|it| _visitor.fold_label(it)),
-        for_token: Token ! [ for ](tokens_helper(_visitor, &(_i.for_token).0)),
+        for_token: Token ! [ for ](tokens_helper(_visitor, &_i.for_token.span)),
         pat: Box::new(_visitor.fold_pat(*_i.pat)),
-        in_token: Token ! [ in ](tokens_helper(_visitor, &(_i.in_token).0)),
+        in_token: Token ! [ in ](tokens_helper(_visitor, &_i.in_token.span)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
         body: _visitor.fold_block(_i.body),
     }
@@ -1346,7 +1372,7 @@
 pub fn fold_expr_group<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprGroup) -> ExprGroup {
     ExprGroup {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        group_token: Group(tokens_helper(_visitor, &(_i.group_token).0)),
+        group_token: Group(tokens_helper(_visitor, &_i.group_token.span)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
     }
 }
@@ -1355,12 +1381,12 @@
 pub fn fold_expr_if<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprIf) -> ExprIf {
     ExprIf {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        if_token: Token ! [ if ](tokens_helper(_visitor, &(_i.if_token).0)),
+        if_token: Token ! [ if ](tokens_helper(_visitor, &_i.if_token.span)),
         cond: Box::new(_visitor.fold_expr(*_i.cond)),
         then_branch: _visitor.fold_block(_i.then_branch),
         else_branch: (_i.else_branch).map(|it| {
             (
-                Token ! [ else ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ else ](tokens_helper(_visitor, &(it).0.span)),
                 Box::new(_visitor.fold_expr(*(it).1)),
             )
         }),
@@ -1371,15 +1397,15 @@
 pub fn fold_expr_if_let<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprIfLet) -> ExprIfLet {
     ExprIfLet {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        if_token: Token ! [ if ](tokens_helper(_visitor, &(_i.if_token).0)),
-        let_token: Token ! [ let ](tokens_helper(_visitor, &(_i.let_token).0)),
+        if_token: Token ! [ if ](tokens_helper(_visitor, &_i.if_token.span)),
+        let_token: Token ! [ let ](tokens_helper(_visitor, &_i.let_token.span)),
         pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
         then_branch: _visitor.fold_block(_i.then_branch),
         else_branch: (_i.else_branch).map(|it| {
             (
-                Token ! [ else ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ else ](tokens_helper(_visitor, &(it).0.span)),
                 Box::new(_visitor.fold_expr(*(it).1)),
             )
         }),
@@ -1391,7 +1417,7 @@
     ExprInPlace {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         place: Box::new(_visitor.fold_expr(*_i.place)),
-        arrow_token: Token ! [ <- ](tokens_helper(_visitor, &(_i.arrow_token).0)),
+        arrow_token: Token ! [ <- ](tokens_helper(_visitor, &_i.arrow_token.spans)),
         value: Box::new(_visitor.fold_expr(*_i.value)),
     }
 }
@@ -1400,7 +1426,7 @@
     ExprIndex {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         index: Box::new(_visitor.fold_expr(*_i.index)),
     }
 }
@@ -1417,7 +1443,7 @@
     ExprLoop {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         label: (_i.label).map(|it| _visitor.fold_label(it)),
-        loop_token: Token ! [ loop ](tokens_helper(_visitor, &(_i.loop_token).0)),
+        loop_token: Token ! [ loop ](tokens_helper(_visitor, &_i.loop_token.span)),
         body: _visitor.fold_block(_i.body),
     }
 }
@@ -1434,9 +1460,9 @@
 pub fn fold_expr_match<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprMatch) -> ExprMatch {
     ExprMatch {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        match_token: Token ! [ match ](tokens_helper(_visitor, &(_i.match_token).0)),
+        match_token: Token ! [ match ](tokens_helper(_visitor, &_i.match_token.span)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         arms: FoldHelper::lift(_i.arms, |it| _visitor.fold_arm(it)),
     }
 }
@@ -1449,10 +1475,10 @@
     ExprMethodCall {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         receiver: Box::new(_visitor.fold_expr(*_i.receiver)),
-        dot_token: Token ! [ . ](tokens_helper(_visitor, &(_i.dot_token).0)),
+        dot_token: Token ! [ . ](tokens_helper(_visitor, &_i.dot_token.spans)),
         method: _visitor.fold_ident(_i.method),
         turbofish: (_i.turbofish).map(|it| _visitor.fold_method_turbofish(it)),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         args: FoldHelper::lift(_i.args, |it| _visitor.fold_expr(it)),
     }
 }
@@ -1460,7 +1486,7 @@
 pub fn fold_expr_paren<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprParen) -> ExprParen {
     ExprParen {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
     }
 }
@@ -1487,8 +1513,8 @@
 pub fn fold_expr_reference<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprReference) -> ExprReference {
     ExprReference {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
     }
 }
@@ -1497,9 +1523,9 @@
 pub fn fold_expr_repeat<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprRepeat) -> ExprRepeat {
     ExprRepeat {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
         len: Box::new(_visitor.fold_expr(*_i.len)),
     }
 }
@@ -1508,7 +1534,7 @@
 pub fn fold_expr_return<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprReturn) -> ExprReturn {
     ExprReturn {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        return_token: Token![return](tokens_helper(_visitor, &(_i.return_token).0)),
+        return_token: Token![return](tokens_helper(_visitor, &_i.return_token.span)),
         expr: (_i.expr).map(|it| Box::new(_visitor.fold_expr(*it))),
     }
 }
@@ -1518,9 +1544,9 @@
     ExprStruct {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         path: _visitor.fold_path(_i.path),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         fields: FoldHelper::lift(_i.fields, |it| _visitor.fold_field_value(it)),
-        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &(it).0))),
+        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &it.spans))),
         rest: (_i.rest).map(|it| Box::new(_visitor.fold_expr(*it))),
     }
 }
@@ -1530,7 +1556,16 @@
     ExprTry {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        question_token: Token ! [ ? ](tokens_helper(_visitor, &(_i.question_token).0)),
+        question_token: Token ! [ ? ](tokens_helper(_visitor, &_i.question_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn fold_expr_try_block<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprTryBlock) -> ExprTryBlock {
+    ExprTryBlock {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        try_token: Token![try](tokens_helper(_visitor, &_i.try_token.span)),
+        block: _visitor.fold_block(_i.block),
     }
 }
 #[cfg(feature = "full")]
@@ -1538,7 +1573,7 @@
 pub fn fold_expr_tuple<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprTuple) -> ExprTuple {
     ExprTuple {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         elems: FoldHelper::lift(_i.elems, |it| _visitor.fold_expr(it)),
     }
 }
@@ -1548,7 +1583,7 @@
     ExprType {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
     }
 }
@@ -1565,7 +1600,7 @@
 pub fn fold_expr_unsafe<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprUnsafe) -> ExprUnsafe {
     ExprUnsafe {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        unsafe_token: Token ! [ unsafe ](tokens_helper(_visitor, &(_i.unsafe_token).0)),
+        unsafe_token: Token ! [ unsafe ](tokens_helper(_visitor, &_i.unsafe_token.span)),
         block: _visitor.fold_block(_i.block),
     }
 }
@@ -1579,7 +1614,7 @@
     ExprWhile {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         label: (_i.label).map(|it| _visitor.fold_label(it)),
-        while_token: Token ! [ while ](tokens_helper(_visitor, &(_i.while_token).0)),
+        while_token: Token ! [ while ](tokens_helper(_visitor, &_i.while_token.span)),
         cond: Box::new(_visitor.fold_expr(*_i.cond)),
         body: _visitor.fold_block(_i.body),
     }
@@ -1590,10 +1625,10 @@
     ExprWhileLet {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         label: (_i.label).map(|it| _visitor.fold_label(it)),
-        while_token: Token ! [ while ](tokens_helper(_visitor, &(_i.while_token).0)),
-        let_token: Token ! [ let ](tokens_helper(_visitor, &(_i.let_token).0)),
+        while_token: Token ! [ while ](tokens_helper(_visitor, &_i.while_token.span)),
+        let_token: Token ! [ let ](tokens_helper(_visitor, &_i.let_token.span)),
         pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
         body: _visitor.fold_block(_i.body),
     }
@@ -1603,7 +1638,7 @@
 pub fn fold_expr_yield<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprYield) -> ExprYield {
     ExprYield {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        yield_token: Token![yield](tokens_helper(_visitor, &(_i.yield_token).0)),
+        yield_token: Token![yield](tokens_helper(_visitor, &_i.yield_token.span)),
         expr: (_i.expr).map(|it| Box::new(_visitor.fold_expr(*it))),
     }
 }
@@ -1613,7 +1648,7 @@
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
         ident: (_i.ident).map(|it| _visitor.fold_ident(it)),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         ty: _visitor.fold_type(_i.ty),
     }
 }
@@ -1623,7 +1658,7 @@
     FieldPat {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         member: _visitor.fold_member(_i.member),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         pat: Box::new(_visitor.fold_pat(*_i.pat)),
     }
 }
@@ -1633,7 +1668,7 @@
     FieldValue {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         member: _visitor.fold_member(_i.member),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         expr: _visitor.fold_expr(_i.expr),
     }
 }
@@ -1648,14 +1683,14 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_fields_named<V: Fold + ?Sized>(_visitor: &mut V, _i: FieldsNamed) -> FieldsNamed {
     FieldsNamed {
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         named: FoldHelper::lift(_i.named, |it| _visitor.fold_field(it)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_fields_unnamed<V: Fold + ?Sized>(_visitor: &mut V, _i: FieldsUnnamed) -> FieldsUnnamed {
     FieldsUnnamed {
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         unnamed: FoldHelper::lift(_i.unnamed, |it| _visitor.fold_field(it)),
     }
 }
@@ -1680,11 +1715,11 @@
 #[cfg(feature = "full")]
 pub fn fold_fn_decl<V: Fold + ?Sized>(_visitor: &mut V, _i: FnDecl) -> FnDecl {
     FnDecl {
-        fn_token: Token ! [ fn ](tokens_helper(_visitor, &(_i.fn_token).0)),
+        fn_token: Token ! [ fn ](tokens_helper(_visitor, &_i.fn_token.span)),
         generics: _visitor.fold_generics(_i.generics),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_fn_arg(it)),
-        variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &(it).0))),
+        variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &it.spans))),
         output: _visitor.fold_return_type(_i.output),
     }
 }
@@ -1698,6 +1733,9 @@
         ForeignItem::Type(_binding_0) => {
             ForeignItem::Type(_visitor.fold_foreign_item_type(_binding_0))
         }
+        ForeignItem::Macro(_binding_0) => {
+            ForeignItem::Macro(_visitor.fold_foreign_item_macro(_binding_0))
+        }
         ForeignItem::Verbatim(_binding_0) => {
             ForeignItem::Verbatim(_visitor.fold_foreign_item_verbatim(_binding_0))
         }
@@ -1713,7 +1751,18 @@
         vis: _visitor.fold_visibility(_i.vis),
         ident: _visitor.fold_ident(_i.ident),
         decl: Box::new(_visitor.fold_fn_decl(*_i.decl)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
+pub fn fold_foreign_item_macro<V: Fold + ?Sized>(
+    _visitor: &mut V,
+    _i: ForeignItemMacro,
+) -> ForeignItemMacro {
+    ForeignItemMacro {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        mac: _visitor.fold_macro(_i.mac),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -1724,12 +1773,12 @@
     ForeignItemStatic {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        static_token: Token ! [ static ](tokens_helper(_visitor, &(_i.static_token).0)),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        static_token: Token ! [ static ](tokens_helper(_visitor, &_i.static_token.span)),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -1740,9 +1789,9 @@
     ForeignItemType {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
         ident: _visitor.fold_ident(_i.ident),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -1800,9 +1849,9 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_generics<V: Fold + ?Sized>(_visitor: &mut V, _i: Generics) -> Generics {
     Generics {
-        lt_token: (_i.lt_token).map(|it| Token ! [ < ](tokens_helper(_visitor, &(it).0))),
+        lt_token: (_i.lt_token).map(|it| Token ! [ < ](tokens_helper(_visitor, &it.spans))),
         params: FoldHelper::lift(_i.params, |it| _visitor.fold_generic_param(it)),
-        gt_token: (_i.gt_token).map(|it| Token ! [ > ](tokens_helper(_visitor, &(it).0))),
+        gt_token: (_i.gt_token).map(|it| Token ! [ > ](tokens_helper(_visitor, &it.spans))),
         where_clause: (_i.where_clause).map(|it| _visitor.fold_where_clause(it)),
     }
 }
@@ -1820,6 +1869,9 @@
             ImplItem::Method(_visitor.fold_impl_item_method(_binding_0))
         }
         ImplItem::Type(_binding_0) => ImplItem::Type(_visitor.fold_impl_item_type(_binding_0)),
+        ImplItem::Existential(_binding_0) => {
+            ImplItem::Existential(_visitor.fold_impl_item_existential(_binding_0))
+        }
         ImplItem::Macro(_binding_0) => ImplItem::Macro(_visitor.fold_impl_item_macro(_binding_0)),
         ImplItem::Verbatim(_binding_0) => {
             ImplItem::Verbatim(_visitor.fold_impl_item_verbatim(_binding_0))
@@ -1834,14 +1886,30 @@
     ImplItemConst {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &(it).0))),
-        const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &it.span))),
+        const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: _visitor.fold_type(_i.ty),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         expr: _visitor.fold_expr(_i.expr),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
+pub fn fold_impl_item_existential<V: Fold + ?Sized>(
+    _visitor: &mut V,
+    _i: ImplItemExistential,
+) -> ImplItemExistential {
+    ImplItemExistential {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        existential_token: Token![existential](tokens_helper(_visitor, &_i.existential_token.span)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+        ident: _visitor.fold_ident(_i.ident),
+        generics: _visitor.fold_generics(_i.generics),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+        bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -1852,7 +1920,7 @@
     ImplItemMacro {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         mac: _visitor.fold_macro(_i.mac),
-        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -1863,7 +1931,7 @@
     ImplItemMethod {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &(it).0))),
+        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &it.span))),
         sig: _visitor.fold_method_sig(_i.sig),
         block: _visitor.fold_block(_i.block),
     }
@@ -1873,13 +1941,13 @@
     ImplItemType {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &(it).0))),
-        type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &it.span))),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         ty: _visitor.fold_type(_i.ty),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -1911,6 +1979,9 @@
             Item::ForeignMod(_visitor.fold_item_foreign_mod(_binding_0))
         }
         Item::Type(_binding_0) => Item::Type(_visitor.fold_item_type(_binding_0)),
+        Item::Existential(_binding_0) => {
+            Item::Existential(_visitor.fold_item_existential(_binding_0))
+        }
         Item::Struct(_binding_0) => Item::Struct(_visitor.fold_item_struct(_binding_0)),
         Item::Enum(_binding_0) => Item::Enum(_visitor.fold_item_enum(_binding_0)),
         Item::Union(_binding_0) => Item::Union(_visitor.fold_item_union(_binding_0)),
@@ -1926,13 +1997,13 @@
     ItemConst {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+        const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -1940,14 +2011,31 @@
     ItemEnum {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        enum_token: Token ! [ enum ](tokens_helper(_visitor, &(_i.enum_token).0)),
+        enum_token: Token ! [ enum ](tokens_helper(_visitor, &_i.enum_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         variants: FoldHelper::lift(_i.variants, |it| _visitor.fold_variant(it)),
     }
 }
 #[cfg(feature = "full")]
+pub fn fold_item_existential<V: Fold + ?Sized>(
+    _visitor: &mut V,
+    _i: ItemExistential,
+) -> ItemExistential {
+    ItemExistential {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        vis: _visitor.fold_visibility(_i.vis),
+        existential_token: Token![existential](tokens_helper(_visitor, &_i.existential_token.span)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+        ident: _visitor.fold_ident(_i.ident),
+        generics: _visitor.fold_generics(_i.generics),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+        bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
 pub fn fold_item_extern_crate<V: Fold + ?Sized>(
     _visitor: &mut V,
     _i: ItemExternCrate,
@@ -1955,16 +2043,16 @@
     ItemExternCrate {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        extern_token: Token![extern](tokens_helper(_visitor, &(_i.extern_token).0)),
-        crate_token: Token![crate](tokens_helper(_visitor, &(_i.crate_token).0)),
+        extern_token: Token![extern](tokens_helper(_visitor, &_i.extern_token.span)),
+        crate_token: Token![crate](tokens_helper(_visitor, &_i.crate_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         rename: (_i.rename).map(|it| {
             (
-                Token ! [ as ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ as ](tokens_helper(_visitor, &(it).0.span)),
                 _visitor.fold_ident((it).1),
             )
         }),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -1972,8 +2060,9 @@
     ItemFn {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &(it).0))),
-        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
+        constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &it.span))),
+        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+        asyncness: (_i.asyncness).map(|it| Token![async](tokens_helper(_visitor, &it.span))),
         abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
         ident: _visitor.fold_ident(_i.ident),
         decl: Box::new(_visitor.fold_fn_decl(*_i.decl)),
@@ -1988,7 +2077,7 @@
     ItemForeignMod {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         abi: _visitor.fold_abi(_i.abi),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         items: FoldHelper::lift(_i.items, |it| _visitor.fold_foreign_item(it)),
     }
 }
@@ -1996,19 +2085,19 @@
 pub fn fold_item_impl<V: Fold + ?Sized>(_visitor: &mut V, _i: ItemImpl) -> ItemImpl {
     ItemImpl {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &(it).0))),
-        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
-        impl_token: Token![impl ](tokens_helper(_visitor, &(_i.impl_token).0)),
+        defaultness: (_i.defaultness).map(|it| Token![default](tokens_helper(_visitor, &it.span))),
+        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+        impl_token: Token![impl ](tokens_helper(_visitor, &_i.impl_token.span)),
         generics: _visitor.fold_generics(_i.generics),
         trait_: (_i.trait_).map(|it| {
             (
-                ((it).0).map(|it| Token![!](tokens_helper(_visitor, &(it).0))),
+                ((it).0).map(|it| Token![!](tokens_helper(_visitor, &it.spans))),
                 _visitor.fold_path((it).1),
-                Token ! [ for ](tokens_helper(_visitor, &((it).2).0)),
+                Token ! [ for ](tokens_helper(_visitor, &(it).2.span)),
             )
         }),
         self_ty: Box::new(_visitor.fold_type(*_i.self_ty)),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         items: FoldHelper::lift(_i.items, |it| _visitor.fold_impl_item(it)),
     }
 }
@@ -2018,7 +2107,7 @@
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         ident: (_i.ident).map(|it| _visitor.fold_ident(it)),
         mac: _visitor.fold_macro(_i.mac),
-        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -2026,11 +2115,11 @@
     ItemMacro2 {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        macro_token: Token ! [ macro ](tokens_helper(_visitor, &(_i.macro_token).0)),
+        macro_token: Token ! [ macro ](tokens_helper(_visitor, &_i.macro_token.span)),
         ident: _visitor.fold_ident(_i.ident),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         args: _i.args,
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         body: _i.body,
     }
 }
@@ -2039,15 +2128,15 @@
     ItemMod {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        mod_token: Token ! [ mod ](tokens_helper(_visitor, &(_i.mod_token).0)),
+        mod_token: Token ! [ mod ](tokens_helper(_visitor, &_i.mod_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         content: (_i.content).map(|it| {
             (
-                Brace(tokens_helper(_visitor, &((it).0).0)),
+                Brace(tokens_helper(_visitor, &(it).0.span)),
                 FoldHelper::lift((it).1, |it| _visitor.fold_item(it)),
             )
         }),
-        semi: (_i.semi).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi: (_i.semi).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -2055,14 +2144,14 @@
     ItemStatic {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        static_token: Token ! [ static ](tokens_helper(_visitor, &(_i.static_token).0)),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        static_token: Token ! [ static ](tokens_helper(_visitor, &_i.static_token.span)),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         expr: Box::new(_visitor.fold_expr(*_i.expr)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -2070,11 +2159,11 @@
     ItemStruct {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        struct_token: Token ! [ struct ](tokens_helper(_visitor, &(_i.struct_token).0)),
+        struct_token: Token ! [ struct ](tokens_helper(_visitor, &_i.struct_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
         fields: _visitor.fold_fields(_i.fields),
-        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -2082,14 +2171,14 @@
     ItemTrait {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
-        auto_token: (_i.auto_token).map(|it| Token![auto](tokens_helper(_visitor, &(it).0))),
-        trait_token: Token ! [ trait ](tokens_helper(_visitor, &(_i.trait_token).0)),
+        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+        auto_token: (_i.auto_token).map(|it| Token![auto](tokens_helper(_visitor, &it.span))),
+        trait_token: Token ! [ trait ](tokens_helper(_visitor, &_i.trait_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         supertraits: FoldHelper::lift(_i.supertraits, |it| _visitor.fold_type_param_bound(it)),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         items: FoldHelper::lift(_i.items, |it| _visitor.fold_trait_item(it)),
     }
 }
@@ -2098,12 +2187,12 @@
     ItemType {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -2111,7 +2200,7 @@
     ItemUnion {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        union_token: Token![union](tokens_helper(_visitor, &(_i.union_token).0)),
+        union_token: Token![union](tokens_helper(_visitor, &_i.union_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
         fields: _visitor.fold_fields_named(_i.fields),
@@ -2122,11 +2211,11 @@
     ItemUse {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         vis: _visitor.fold_visibility(_i.vis),
-        use_token: Token ! [ use ](tokens_helper(_visitor, &(_i.use_token).0)),
+        use_token: Token ! [ use ](tokens_helper(_visitor, &_i.use_token.span)),
         leading_colon: (_i.leading_colon)
-            .map(|it| Token ! [ :: ](tokens_helper(_visitor, &(it).0))),
+            .map(|it| Token ! [ :: ](tokens_helper(_visitor, &it.spans))),
         tree: _visitor.fold_use_tree(_i.tree),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -2138,7 +2227,7 @@
 pub fn fold_label<V: Fold + ?Sized>(_visitor: &mut V, _i: Label) -> Label {
     Label {
         name: _visitor.fold_lifetime(_i.name),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2153,7 +2242,7 @@
     LifetimeDef {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         lifetime: _visitor.fold_lifetime(_i.lifetime),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_lifetime(it)),
     }
 }
@@ -2186,28 +2275,28 @@
 pub fn fold_local<V: Fold + ?Sized>(_visitor: &mut V, _i: Local) -> Local {
     Local {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        let_token: Token ! [ let ](tokens_helper(_visitor, &(_i.let_token).0)),
+        let_token: Token ! [ let ](tokens_helper(_visitor, &_i.let_token.span)),
         pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
         ty: (_i.ty).map(|it| {
             (
-                Token ! [ : ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ : ](tokens_helper(_visitor, &(it).0.spans)),
                 Box::new(_visitor.fold_type(*(it).1)),
             )
         }),
         init: (_i.init).map(|it| {
             (
-                Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
                 Box::new(_visitor.fold_expr(*(it).1)),
             )
         }),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_macro<V: Fold + ?Sized>(_visitor: &mut V, _i: Macro) -> Macro {
     Macro {
         path: _visitor.fold_path(_i.path),
-        bang_token: Token![!](tokens_helper(_visitor, &(_i.bang_token).0)),
+        bang_token: Token![!](tokens_helper(_visitor, &_i.bang_token.spans)),
         delimiter: _visitor.fold_macro_delimiter(_i.delimiter),
         tts: _i.tts,
     }
@@ -2219,13 +2308,13 @@
 ) -> MacroDelimiter {
     match _i {
         MacroDelimiter::Paren(_binding_0) => {
-            MacroDelimiter::Paren(Paren(tokens_helper(_visitor, &(_binding_0).0)))
+            MacroDelimiter::Paren(Paren(tokens_helper(_visitor, &_binding_0.span)))
         }
         MacroDelimiter::Brace(_binding_0) => {
-            MacroDelimiter::Brace(Brace(tokens_helper(_visitor, &(_binding_0).0)))
+            MacroDelimiter::Brace(Brace(tokens_helper(_visitor, &_binding_0.span)))
         }
         MacroDelimiter::Bracket(_binding_0) => {
-            MacroDelimiter::Bracket(Bracket(tokens_helper(_visitor, &(_binding_0).0)))
+            MacroDelimiter::Bracket(Bracket(tokens_helper(_visitor, &_binding_0.span)))
         }
     }
 }
@@ -2248,7 +2337,7 @@
 pub fn fold_meta_list<V: Fold + ?Sized>(_visitor: &mut V, _i: MetaList) -> MetaList {
     MetaList {
         ident: _visitor.fold_ident(_i.ident),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         nested: FoldHelper::lift(_i.nested, |it| _visitor.fold_nested_meta(it)),
     }
 }
@@ -2259,15 +2348,16 @@
 ) -> MetaNameValue {
     MetaNameValue {
         ident: _visitor.fold_ident(_i.ident),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         lit: _visitor.fold_lit(_i.lit),
     }
 }
 #[cfg(feature = "full")]
 pub fn fold_method_sig<V: Fold + ?Sized>(_visitor: &mut V, _i: MethodSig) -> MethodSig {
     MethodSig {
-        constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &(it).0))),
-        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
+        constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &it.span))),
+        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+        asyncness: (_i.asyncness).map(|it| Token![async](tokens_helper(_visitor, &it.span))),
         abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
         ident: _visitor.fold_ident(_i.ident),
         decl: _visitor.fold_fn_decl(_i.decl),
@@ -2280,10 +2370,10 @@
     _i: MethodTurbofish,
 ) -> MethodTurbofish {
     MethodTurbofish {
-        colon2_token: Token ! [ :: ](tokens_helper(_visitor, &(_i.colon2_token).0)),
-        lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+        colon2_token: Token ! [ :: ](tokens_helper(_visitor, &_i.colon2_token.spans)),
+        lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
         args: FoldHelper::lift(_i.args, |it| _visitor.fold_generic_method_argument(it)),
-        gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+        gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2299,7 +2389,7 @@
     _i: ParenthesizedGenericArguments,
 ) -> ParenthesizedGenericArguments {
     ParenthesizedGenericArguments {
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_type(it)),
         output: _visitor.fold_return_type(_i.output),
     }
@@ -2329,7 +2419,7 @@
 #[cfg(feature = "full")]
 pub fn fold_pat_box<V: Fold + ?Sized>(_visitor: &mut V, _i: PatBox) -> PatBox {
     PatBox {
-        box_token: Token ! [ box ](tokens_helper(_visitor, &(_i.box_token).0)),
+        box_token: Token ! [ box ](tokens_helper(_visitor, &_i.box_token.span)),
         pat: Box::new(_visitor.fold_pat(*_i.pat)),
     }
 }
@@ -2337,12 +2427,12 @@
 #[cfg(feature = "full")]
 pub fn fold_pat_ident<V: Fold + ?Sized>(_visitor: &mut V, _i: PatIdent) -> PatIdent {
     PatIdent {
-        by_ref: (_i.by_ref).map(|it| Token ! [ ref ](tokens_helper(_visitor, &(it).0))),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        by_ref: (_i.by_ref).map(|it| Token ! [ ref ](tokens_helper(_visitor, &it.span))),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         ident: _visitor.fold_ident(_i.ident),
         subpat: (_i.subpat).map(|it| {
             (
-                Token ! [ @ ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ @ ](tokens_helper(_visitor, &(it).0.spans)),
                 Box::new(_visitor.fold_pat(*(it).1)),
             )
         }),
@@ -2383,8 +2473,8 @@
 #[cfg(feature = "full")]
 pub fn fold_pat_ref<V: Fold + ?Sized>(_visitor: &mut V, _i: PatRef) -> PatRef {
     PatRef {
-        and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         pat: Box::new(_visitor.fold_pat(*_i.pat)),
     }
 }
@@ -2392,11 +2482,11 @@
 #[cfg(feature = "full")]
 pub fn fold_pat_slice<V: Fold + ?Sized>(_visitor: &mut V, _i: PatSlice) -> PatSlice {
     PatSlice {
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         front: FoldHelper::lift(_i.front, |it| _visitor.fold_pat(it)),
         middle: (_i.middle).map(|it| Box::new(_visitor.fold_pat(*it))),
-        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &(it).0))),
-        comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &(it).0))),
+        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &it.spans))),
+        comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &it.spans))),
         back: FoldHelper::lift(_i.back, |it| _visitor.fold_pat(it)),
     }
 }
@@ -2405,19 +2495,19 @@
 pub fn fold_pat_struct<V: Fold + ?Sized>(_visitor: &mut V, _i: PatStruct) -> PatStruct {
     PatStruct {
         path: _visitor.fold_path(_i.path),
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         fields: FoldHelper::lift(_i.fields, |it| _visitor.fold_field_pat(it)),
-        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &(it).0))),
+        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn fold_pat_tuple<V: Fold + ?Sized>(_visitor: &mut V, _i: PatTuple) -> PatTuple {
     PatTuple {
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         front: FoldHelper::lift(_i.front, |it| _visitor.fold_pat(it)),
-        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &(it).0))),
-        comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &(it).0))),
+        dot2_token: (_i.dot2_token).map(|it| Token![..](tokens_helper(_visitor, &it.spans))),
+        comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &it.spans))),
         back: FoldHelper::lift(_i.back, |it| _visitor.fold_pat(it)),
     }
 }
@@ -2441,14 +2531,14 @@
 #[cfg(feature = "full")]
 pub fn fold_pat_wild<V: Fold + ?Sized>(_visitor: &mut V, _i: PatWild) -> PatWild {
     PatWild {
-        underscore_token: Token![_](tokens_helper(_visitor, &(_i.underscore_token).0)),
+        underscore_token: Token![_](tokens_helper(_visitor, &_i.underscore_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_path<V: Fold + ?Sized>(_visitor: &mut V, _i: Path) -> Path {
     Path {
         leading_colon: (_i.leading_colon)
-            .map(|it| Token ! [ :: ](tokens_helper(_visitor, &(it).0))),
+            .map(|it| Token ! [ :: ](tokens_helper(_visitor, &it.spans))),
         segments: FoldHelper::lift(_i.segments, |it| _visitor.fold_path_segment(it)),
     }
 }
@@ -2475,7 +2565,7 @@
 pub fn fold_predicate_eq<V: Fold + ?Sized>(_visitor: &mut V, _i: PredicateEq) -> PredicateEq {
     PredicateEq {
         lhs_ty: _visitor.fold_type(_i.lhs_ty),
-        eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+        eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
         rhs_ty: _visitor.fold_type(_i.rhs_ty),
     }
 }
@@ -2486,7 +2576,7 @@
 ) -> PredicateLifetime {
     PredicateLifetime {
         lifetime: _visitor.fold_lifetime(_i.lifetime),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_lifetime(it)),
     }
 }
@@ -2495,18 +2585,18 @@
     PredicateType {
         lifetimes: (_i.lifetimes).map(|it| _visitor.fold_bound_lifetimes(it)),
         bounded_ty: _visitor.fold_type(_i.bounded_ty),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_qself<V: Fold + ?Sized>(_visitor: &mut V, _i: QSelf) -> QSelf {
     QSelf {
-        lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+        lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
         ty: Box::new(_visitor.fold_type(*_i.ty)),
         position: _i.position,
-        as_token: (_i.as_token).map(|it| Token ! [ as ](tokens_helper(_visitor, &(it).0))),
-        gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+        as_token: (_i.as_token).map(|it| Token ! [ as ](tokens_helper(_visitor, &it.span))),
+        gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2514,10 +2604,10 @@
 pub fn fold_range_limits<V: Fold + ?Sized>(_visitor: &mut V, _i: RangeLimits) -> RangeLimits {
     match _i {
         RangeLimits::HalfOpen(_binding_0) => {
-            RangeLimits::HalfOpen(Token![..](tokens_helper(_visitor, &(_binding_0).0)))
+            RangeLimits::HalfOpen(Token![..](tokens_helper(_visitor, &_binding_0.spans)))
         }
         RangeLimits::Closed(_binding_0) => {
-            RangeLimits::Closed(Token ! [ ..= ](tokens_helper(_visitor, &(_binding_0).0)))
+            RangeLimits::Closed(Token ! [ ..= ](tokens_helper(_visitor, &_binding_0.spans)))
         }
     }
 }
@@ -2526,7 +2616,7 @@
     match _i {
         ReturnType::Default => ReturnType::Default,
         ReturnType::Type(_binding_0, _binding_1) => ReturnType::Type(
-            Token ! [ -> ](tokens_helper(_visitor, &(_binding_0).0)),
+            Token ! [ -> ](tokens_helper(_visitor, &_binding_0.spans)),
             Box::new(_visitor.fold_type(*_binding_1)),
         ),
     }
@@ -2543,14 +2633,14 @@
         Stmt::Expr(_binding_0) => Stmt::Expr(_visitor.fold_expr(_binding_0)),
         Stmt::Semi(_binding_0, _binding_1) => Stmt::Semi(
             _visitor.fold_expr(_binding_0),
-            Token ! [ ; ](tokens_helper(_visitor, &(_binding_1).0)),
+            Token ! [ ; ](tokens_helper(_visitor, &_binding_1.spans)),
         ),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_trait_bound<V: Fold + ?Sized>(_visitor: &mut V, _i: TraitBound) -> TraitBound {
     TraitBound {
-        paren_token: (_i.paren_token).map(|it| Paren(tokens_helper(_visitor, &(it).0))),
+        paren_token: (_i.paren_token).map(|it| Paren(tokens_helper(_visitor, &it.span))),
         modifier: _visitor.fold_trait_bound_modifier(_i.modifier),
         lifetimes: (_i.lifetimes).map(|it| _visitor.fold_bound_lifetimes(it)),
         path: _visitor.fold_path(_i.path),
@@ -2564,7 +2654,7 @@
     match _i {
         TraitBoundModifier::None => TraitBoundModifier::None,
         TraitBoundModifier::Maybe(_binding_0) => {
-            TraitBoundModifier::Maybe(Token ! [ ? ](tokens_helper(_visitor, &(_binding_0).0)))
+            TraitBoundModifier::Maybe(Token ! [ ? ](tokens_helper(_visitor, &_binding_0.spans)))
         }
     }
 }
@@ -2593,17 +2683,17 @@
 ) -> TraitItemConst {
     TraitItemConst {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+        const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+        colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
         ty: _visitor.fold_type(_i.ty),
         default: (_i.default).map(|it| {
             (
-                Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
                 _visitor.fold_expr((it).1),
             )
         }),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -2614,7 +2704,7 @@
     TraitItemMacro {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         mac: _visitor.fold_macro(_i.mac),
-        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -2626,7 +2716,7 @@
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         sig: _visitor.fold_method_sig(_i.sig),
         default: (_i.default).map(|it| _visitor.fold_block(it)),
-        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+        semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
     }
 }
 #[cfg(feature = "full")]
@@ -2636,18 +2726,18 @@
 ) -> TraitItemType {
     TraitItemType {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
-        type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
         ident: _visitor.fold_ident(_i.ident),
         generics: _visitor.fold_generics(_i.generics),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
         default: (_i.default).map(|it| {
             (
-                Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
                 _visitor.fold_type((it).1),
             )
         }),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
     }
 }
 #[cfg(feature = "full")]
@@ -2682,29 +2772,29 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_array<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeArray) -> TypeArray {
     TypeArray {
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         elem: Box::new(_visitor.fold_type(*_i.elem)),
-        semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
         len: _visitor.fold_expr(_i.len),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_bare_fn<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeBareFn) -> TypeBareFn {
     TypeBareFn {
-        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
-        abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
-        fn_token: Token ! [ fn ](tokens_helper(_visitor, &(_i.fn_token).0)),
         lifetimes: (_i.lifetimes).map(|it| _visitor.fold_bound_lifetimes(it)),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+        abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
+        fn_token: Token ! [ fn ](tokens_helper(_visitor, &_i.fn_token.span)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_bare_fn_arg(it)),
-        variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &(it).0))),
+        variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &it.spans))),
         output: _visitor.fold_return_type(_i.output),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_group<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeGroup) -> TypeGroup {
     TypeGroup {
-        group_token: Group(tokens_helper(_visitor, &(_i.group_token).0)),
+        group_token: Group(tokens_helper(_visitor, &_i.group_token.span)),
         elem: Box::new(_visitor.fold_type(*_i.elem)),
     }
 }
@@ -2714,14 +2804,14 @@
     _i: TypeImplTrait,
 ) -> TypeImplTrait {
     TypeImplTrait {
-        impl_token: Token![impl ](tokens_helper(_visitor, &(_i.impl_token).0)),
+        impl_token: Token![impl ](tokens_helper(_visitor, &_i.impl_token.span)),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_infer<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeInfer) -> TypeInfer {
     TypeInfer {
-        underscore_token: Token![_](tokens_helper(_visitor, &(_i.underscore_token).0)),
+        underscore_token: Token![_](tokens_helper(_visitor, &_i.underscore_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2733,7 +2823,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_never<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeNever) -> TypeNever {
     TypeNever {
-        bang_token: Token![!](tokens_helper(_visitor, &(_i.bang_token).0)),
+        bang_token: Token![!](tokens_helper(_visitor, &_i.bang_token.spans)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2741,9 +2831,9 @@
     TypeParam {
         attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
         ident: _visitor.fold_ident(_i.ident),
-        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
-        eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &(it).0))),
+        eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &it.spans))),
         default: (_i.default).map(|it| _visitor.fold_type(it)),
     }
 }
@@ -2764,7 +2854,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_paren<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeParen) -> TypeParen {
     TypeParen {
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         elem: Box::new(_visitor.fold_type(*_i.elem)),
     }
 }
@@ -2778,25 +2868,26 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_ptr<V: Fold + ?Sized>(_visitor: &mut V, _i: TypePtr) -> TypePtr {
     TypePtr {
-        star_token: Token ! [ * ](tokens_helper(_visitor, &(_i.star_token).0)),
-        const_token: (_i.const_token).map(|it| Token ! [ const ](tokens_helper(_visitor, &(it).0))),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        star_token: Token ! [ * ](tokens_helper(_visitor, &_i.star_token.spans)),
+        const_token: (_i.const_token)
+            .map(|it| Token ! [ const ](tokens_helper(_visitor, &it.span))),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         elem: Box::new(_visitor.fold_type(*_i.elem)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_reference<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeReference) -> TypeReference {
     TypeReference {
-        and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
+        and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
         lifetime: (_i.lifetime).map(|it| _visitor.fold_lifetime(it)),
-        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+        mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
         elem: Box::new(_visitor.fold_type(*_i.elem)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_slice<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeSlice) -> TypeSlice {
     TypeSlice {
-        bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+        bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
         elem: Box::new(_visitor.fold_type(*_i.elem)),
     }
 }
@@ -2806,14 +2897,14 @@
     _i: TypeTraitObject,
 ) -> TypeTraitObject {
     TypeTraitObject {
-        dyn_token: (_i.dyn_token).map(|it| Token![dyn](tokens_helper(_visitor, &(it).0))),
+        dyn_token: (_i.dyn_token).map(|it| Token![dyn](tokens_helper(_visitor, &it.span))),
         bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_type_tuple<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeTuple) -> TypeTuple {
     TypeTuple {
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
         elems: FoldHelper::lift(_i.elems, |it| _visitor.fold_type(it)),
     }
 }
@@ -2825,22 +2916,24 @@
 pub fn fold_un_op<V: Fold + ?Sized>(_visitor: &mut V, _i: UnOp) -> UnOp {
     match _i {
         UnOp::Deref(_binding_0) => {
-            UnOp::Deref(Token ! [ * ](tokens_helper(_visitor, &(_binding_0).0)))
+            UnOp::Deref(Token ! [ * ](tokens_helper(_visitor, &_binding_0.spans)))
         }
-        UnOp::Not(_binding_0) => UnOp::Not(Token![!](tokens_helper(_visitor, &(_binding_0).0))),
-        UnOp::Neg(_binding_0) => UnOp::Neg(Token ! [ - ](tokens_helper(_visitor, &(_binding_0).0))),
+        UnOp::Not(_binding_0) => UnOp::Not(Token![!](tokens_helper(_visitor, &_binding_0.spans))),
+        UnOp::Neg(_binding_0) => {
+            UnOp::Neg(Token ! [ - ](tokens_helper(_visitor, &_binding_0.spans)))
+        }
     }
 }
 #[cfg(feature = "full")]
 pub fn fold_use_glob<V: Fold + ?Sized>(_visitor: &mut V, _i: UseGlob) -> UseGlob {
     UseGlob {
-        star_token: Token ! [ * ](tokens_helper(_visitor, &(_i.star_token).0)),
+        star_token: Token ! [ * ](tokens_helper(_visitor, &_i.star_token.spans)),
     }
 }
 #[cfg(feature = "full")]
 pub fn fold_use_group<V: Fold + ?Sized>(_visitor: &mut V, _i: UseGroup) -> UseGroup {
     UseGroup {
-        brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+        brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
         items: FoldHelper::lift(_i.items, |it| _visitor.fold_use_tree(it)),
     }
 }
@@ -2854,7 +2947,7 @@
 pub fn fold_use_path<V: Fold + ?Sized>(_visitor: &mut V, _i: UsePath) -> UsePath {
     UsePath {
         ident: _visitor.fold_ident(_i.ident),
-        colon2_token: Token ! [ :: ](tokens_helper(_visitor, &(_i.colon2_token).0)),
+        colon2_token: Token ! [ :: ](tokens_helper(_visitor, &_i.colon2_token.spans)),
         tree: Box::new(_visitor.fold_use_tree(*_i.tree)),
     }
 }
@@ -2862,7 +2955,7 @@
 pub fn fold_use_rename<V: Fold + ?Sized>(_visitor: &mut V, _i: UseRename) -> UseRename {
     UseRename {
         ident: _visitor.fold_ident(_i.ident),
-        as_token: Token ! [ as ](tokens_helper(_visitor, &(_i.as_token).0)),
+        as_token: Token ! [ as ](tokens_helper(_visitor, &_i.as_token.span)),
         rename: _visitor.fold_ident(_i.rename),
     }
 }
@@ -2884,7 +2977,7 @@
         fields: _visitor.fold_fields(_i.fields),
         discriminant: (_i.discriminant).map(|it| {
             (
-                Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+                Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
                 _visitor.fold_expr((it).1),
             )
         }),
@@ -2893,21 +2986,21 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_vis_crate<V: Fold + ?Sized>(_visitor: &mut V, _i: VisCrate) -> VisCrate {
     VisCrate {
-        crate_token: Token![crate](tokens_helper(_visitor, &(_i.crate_token).0)),
+        crate_token: Token![crate](tokens_helper(_visitor, &_i.crate_token.span)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_vis_public<V: Fold + ?Sized>(_visitor: &mut V, _i: VisPublic) -> VisPublic {
     VisPublic {
-        pub_token: Token ! [ pub ](tokens_helper(_visitor, &(_i.pub_token).0)),
+        pub_token: Token ! [ pub ](tokens_helper(_visitor, &_i.pub_token.span)),
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_vis_restricted<V: Fold + ?Sized>(_visitor: &mut V, _i: VisRestricted) -> VisRestricted {
     VisRestricted {
-        pub_token: Token ! [ pub ](tokens_helper(_visitor, &(_i.pub_token).0)),
-        paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
-        in_token: (_i.in_token).map(|it| Token ! [ in ](tokens_helper(_visitor, &(it).0))),
+        pub_token: Token ! [ pub ](tokens_helper(_visitor, &_i.pub_token.span)),
+        paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
+        in_token: (_i.in_token).map(|it| Token ! [ in ](tokens_helper(_visitor, &it.span))),
         path: Box::new(_visitor.fold_path(*_i.path)),
     }
 }
@@ -2925,7 +3018,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn fold_where_clause<V: Fold + ?Sized>(_visitor: &mut V, _i: WhereClause) -> WhereClause {
     WhereClause {
-        where_token: Token ! [ where ](tokens_helper(_visitor, &(_i.where_token).0)),
+        where_token: Token ! [ where ](tokens_helper(_visitor, &_i.where_token.span)),
         predicates: FoldHelper::lift(_i.predicates, |it| _visitor.fold_where_predicate(it)),
     }
 }
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index d501ac6..6bf7a68 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -132,6 +132,11 @@
     fn visit_expr_assign_op(&mut self, i: &'ast ExprAssignOp) {
         visit_expr_assign_op(self, i)
     }
+    #[cfg(feature = "full")]
+    #[cfg(any(feature = "full", feature = "derive"))]
+    fn visit_expr_async(&mut self, i: &'ast ExprAsync) {
+        visit_expr_async(self, i)
+    }
     #[cfg(any(feature = "full", feature = "derive"))]
     fn visit_expr_binary(&mut self, i: &'ast ExprBinary) {
         visit_expr_binary(self, i)
@@ -161,11 +166,6 @@
     }
     #[cfg(feature = "full")]
     #[cfg(any(feature = "full", feature = "derive"))]
-    fn visit_expr_catch(&mut self, i: &'ast ExprCatch) {
-        visit_expr_catch(self, i)
-    }
-    #[cfg(feature = "full")]
-    #[cfg(any(feature = "full", feature = "derive"))]
     fn visit_expr_closure(&mut self, i: &'ast ExprClosure) {
         visit_expr_closure(self, i)
     }
@@ -271,6 +271,11 @@
     }
     #[cfg(feature = "full")]
     #[cfg(any(feature = "full", feature = "derive"))]
+    fn visit_expr_try_block(&mut self, i: &'ast ExprTryBlock) {
+        visit_expr_try_block(self, i)
+    }
+    #[cfg(feature = "full")]
+    #[cfg(any(feature = "full", feature = "derive"))]
     fn visit_expr_tuple(&mut self, i: &'ast ExprTuple) {
         visit_expr_tuple(self, i)
     }
@@ -354,6 +359,10 @@
         visit_foreign_item_fn(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_foreign_item_macro(&mut self, i: &'ast ForeignItemMacro) {
+        visit_foreign_item_macro(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_foreign_item_static(&mut self, i: &'ast ForeignItemStatic) {
         visit_foreign_item_static(self, i)
     }
@@ -394,6 +403,10 @@
         visit_impl_item_const(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_impl_item_existential(&mut self, i: &'ast ImplItemExistential) {
+        visit_impl_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_impl_item_macro(&mut self, i: &'ast ImplItemMacro) {
         visit_impl_item_macro(self, i)
     }
@@ -426,6 +439,10 @@
         visit_item_enum(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_item_existential(&mut self, i: &'ast ItemExistential) {
+        visit_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_item_extern_crate(&mut self, i: &'ast ItemExternCrate) {
         visit_item_extern_crate(self, i)
     }
@@ -854,7 +871,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_abi<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Abi) {
-    tokens_helper(_visitor, &(_i.extern_token).0);
+    tokens_helper(_visitor, &_i.extern_token.span);
     if let Some(ref it) = _i.name {
         _visitor.visit_lit_str(it)
     };
@@ -865,38 +882,38 @@
     _i: &'ast AngleBracketedGenericArguments,
 ) {
     if let Some(ref it) = _i.colon2_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
-    tokens_helper(_visitor, &(_i.lt_token).0);
+    tokens_helper(_visitor, &_i.lt_token.spans);
     for el in Punctuated::pairs(&_i.args) {
         let it = el.value();
         _visitor.visit_generic_argument(it)
     }
-    tokens_helper(_visitor, &(_i.gt_token).0);
+    tokens_helper(_visitor, &_i.gt_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_arg_captured<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ArgCaptured) {
     _visitor.visit_pat(&_i.pat);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&_i.ty);
 }
 #[cfg(feature = "full")]
 pub fn visit_arg_self<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ArgSelf) {
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.self_token).0);
+    tokens_helper(_visitor, &_i.self_token.span);
 }
 #[cfg(feature = "full")]
 pub fn visit_arg_self_ref<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ArgSelfRef) {
-    tokens_helper(_visitor, &(_i.and_token).0);
+    tokens_helper(_visitor, &_i.and_token.spans);
     if let Some(ref it) = _i.lifetime {
         _visitor.visit_lifetime(it)
     };
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.self_token).0);
+    tokens_helper(_visitor, &_i.self_token.span);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
@@ -905,20 +922,20 @@
         _visitor.visit_attribute(it)
     }
     if let Some(ref it) = _i.leading_vert {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.pats) {
         let it = el.value();
         _visitor.visit_pat(it)
     }
     if let Some(ref it) = _i.guard {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.span);
         _visitor.visit_expr(&*(it).1);
     };
-    tokens_helper(_visitor, &(_i.fat_arrow_token).0);
+    tokens_helper(_visitor, &_i.fat_arrow_token.spans);
     _visitor.visit_expr(&*_i.body);
     if let Some(ref it) = _i.comma {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -926,24 +943,23 @@
     match *_i {
         AttrStyle::Outer => {}
         AttrStyle::Inner(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_attribute<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Attribute) {
-    tokens_helper(_visitor, &(_i.pound_token).0);
+    tokens_helper(_visitor, &_i.pound_token.spans);
     _visitor.visit_attr_style(&_i.style);
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     _visitor.visit_path(&_i.path);
     skip!(_i.tts);
-    skip!(_i.is_sugared_doc);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_bare_fn_arg<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast BareFnArg) {
     if let Some(ref it) = _i.name {
         _visitor.visit_bare_fn_arg_name(&(it).0);
-        tokens_helper(_visitor, &((it).1).0);
+        tokens_helper(_visitor, &(it).1.spans);
     };
     _visitor.visit_type(&_i.ty);
 }
@@ -957,7 +973,7 @@
             _visitor.visit_ident(_binding_0);
         }
         BareFnArgName::Wild(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
     }
 }
@@ -965,101 +981,101 @@
 pub fn visit_bin_op<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast BinOp) {
     match *_i {
         BinOp::Add(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Sub(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Mul(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Div(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Rem(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::And(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Or(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::BitXor(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::BitAnd(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::BitOr(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Shl(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Shr(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Eq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Lt(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Le(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Ne(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Ge(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::Gt(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::AddEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::SubEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::MulEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::DivEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::RemEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::BitXorEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::BitAndEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::BitOrEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::ShlEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         BinOp::ShrEq(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_binding<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Binding) {
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_type(&_i.ty);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_block<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Block) {
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for it in &_i.stmts {
         _visitor.visit_stmt(it)
     }
@@ -1069,25 +1085,25 @@
     _visitor: &mut V,
     _i: &'ast BoundLifetimes,
 ) {
-    tokens_helper(_visitor, &(_i.for_token).0);
-    tokens_helper(_visitor, &(_i.lt_token).0);
+    tokens_helper(_visitor, &_i.for_token.span);
+    tokens_helper(_visitor, &_i.lt_token.spans);
     for el in Punctuated::pairs(&_i.lifetimes) {
         let it = el.value();
         _visitor.visit_lifetime_def(it)
     }
-    tokens_helper(_visitor, &(_i.gt_token).0);
+    tokens_helper(_visitor, &_i.gt_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_const_param<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ConstParam) {
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.const_token).0);
+    tokens_helper(_visitor, &_i.const_token.span);
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&_i.ty);
     if let Some(ref it) = _i.eq_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     if let Some(ref it) = _i.default {
         _visitor.visit_expr(it)
@@ -1109,8 +1125,8 @@
 }
 #[cfg(feature = "derive")]
 pub fn visit_data_enum<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast DataEnum) {
-    tokens_helper(_visitor, &(_i.enum_token).0);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.enum_token.span);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for el in Punctuated::pairs(&_i.variants) {
         let it = el.value();
         _visitor.visit_variant(it)
@@ -1118,15 +1134,15 @@
 }
 #[cfg(feature = "derive")]
 pub fn visit_data_struct<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast DataStruct) {
-    tokens_helper(_visitor, &(_i.struct_token).0);
+    tokens_helper(_visitor, &_i.struct_token.span);
     _visitor.visit_fields(&_i.fields);
     if let Some(ref it) = _i.semi_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "derive")]
 pub fn visit_data_union<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast DataUnion) {
-    tokens_helper(_visitor, &(_i.union_token).0);
+    tokens_helper(_visitor, &_i.union_token.span);
     _visitor.visit_fields_named(&_i.fields);
 }
 #[cfg(feature = "derive")]
@@ -1253,8 +1269,11 @@
         Expr::Try(ref _binding_0) => {
             full!(_visitor.visit_expr_try(_binding_0));
         }
-        Expr::Catch(ref _binding_0) => {
-            full!(_visitor.visit_expr_catch(_binding_0));
+        Expr::Async(ref _binding_0) => {
+            full!(_visitor.visit_expr_async(_binding_0));
+        }
+        Expr::TryBlock(ref _binding_0) => {
+            full!(_visitor.visit_expr_try_block(_binding_0));
         }
         Expr::Yield(ref _binding_0) => {
             full!(_visitor.visit_expr_yield(_binding_0));
@@ -1270,7 +1289,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     for el in Punctuated::pairs(&_i.elems) {
         let it = el.value();
         _visitor.visit_expr(it)
@@ -1283,7 +1302,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.left);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_expr(&*_i.right);
 }
 #[cfg(feature = "full")]
@@ -1299,6 +1318,18 @@
     _visitor.visit_bin_op(&_i.op);
     _visitor.visit_expr(&*_i.right);
 }
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_async<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprAsync) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    tokens_helper(_visitor, &_i.async_token.span);
+    if let Some(ref it) = _i.capture {
+        tokens_helper(_visitor, &it.span)
+    };
+    _visitor.visit_block(&_i.block);
+}
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_expr_binary<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprBinary) {
     for it in &_i.attrs {
@@ -1314,6 +1345,9 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
+    if let Some(ref it) = _i.label {
+        _visitor.visit_label(it)
+    };
     _visitor.visit_block(&_i.block);
 }
 #[cfg(feature = "full")]
@@ -1322,7 +1356,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.box_token).0);
+    tokens_helper(_visitor, &_i.box_token.span);
     _visitor.visit_expr(&*_i.expr);
 }
 #[cfg(feature = "full")]
@@ -1331,7 +1365,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.break_token).0);
+    tokens_helper(_visitor, &_i.break_token.span);
     if let Some(ref it) = _i.label {
         _visitor.visit_lifetime(it)
     };
@@ -1345,7 +1379,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.func);
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.args) {
         let it = el.value();
         _visitor.visit_expr(it)
@@ -1357,37 +1391,30 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.as_token).0);
+    tokens_helper(_visitor, &_i.as_token.span);
     _visitor.visit_type(&*_i.ty);
 }
 #[cfg(feature = "full")]
 #[cfg(any(feature = "full", feature = "derive"))]
-pub fn visit_expr_catch<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprCatch) {
-    for it in &_i.attrs {
-        _visitor.visit_attribute(it)
-    }
-    tokens_helper(_visitor, &(_i.do_token).0);
-    tokens_helper(_visitor, &(_i.catch_token).0);
-    _visitor.visit_block(&_i.block);
-}
-#[cfg(feature = "full")]
-#[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_expr_closure<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprClosure) {
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
+    if let Some(ref it) = _i.asyncness {
+        tokens_helper(_visitor, &it.span)
+    };
     if let Some(ref it) = _i.movability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.capture {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.or1_token).0);
+    tokens_helper(_visitor, &_i.or1_token.spans);
     for el in Punctuated::pairs(&_i.inputs) {
         let it = el.value();
         _visitor.visit_fn_arg(it)
     }
-    tokens_helper(_visitor, &(_i.or2_token).0);
+    tokens_helper(_visitor, &_i.or2_token.spans);
     _visitor.visit_return_type(&_i.output);
     _visitor.visit_expr(&*_i.body);
 }
@@ -1400,7 +1427,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.continue_token).0);
+    tokens_helper(_visitor, &_i.continue_token.span);
     if let Some(ref it) = _i.label {
         _visitor.visit_lifetime(it)
     };
@@ -1411,7 +1438,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.base);
-    tokens_helper(_visitor, &(_i.dot_token).0);
+    tokens_helper(_visitor, &_i.dot_token.spans);
     _visitor.visit_member(&_i.member);
 }
 #[cfg(feature = "full")]
@@ -1423,9 +1450,9 @@
     if let Some(ref it) = _i.label {
         _visitor.visit_label(it)
     };
-    tokens_helper(_visitor, &(_i.for_token).0);
+    tokens_helper(_visitor, &_i.for_token.span);
     _visitor.visit_pat(&*_i.pat);
-    tokens_helper(_visitor, &(_i.in_token).0);
+    tokens_helper(_visitor, &_i.in_token.span);
     _visitor.visit_expr(&*_i.expr);
     _visitor.visit_block(&_i.body);
 }
@@ -1435,7 +1462,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.group_token).0);
+    tokens_helper(_visitor, &_i.group_token.span);
     _visitor.visit_expr(&*_i.expr);
 }
 #[cfg(feature = "full")]
@@ -1444,11 +1471,11 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.if_token).0);
+    tokens_helper(_visitor, &_i.if_token.span);
     _visitor.visit_expr(&*_i.cond);
     _visitor.visit_block(&_i.then_branch);
     if let Some(ref it) = _i.else_branch {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.span);
         _visitor.visit_expr(&*(it).1);
     };
 }
@@ -1458,17 +1485,17 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.if_token).0);
-    tokens_helper(_visitor, &(_i.let_token).0);
+    tokens_helper(_visitor, &_i.if_token.span);
+    tokens_helper(_visitor, &_i.let_token.span);
     for el in Punctuated::pairs(&_i.pats) {
         let it = el.value();
         _visitor.visit_pat(it)
     }
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_expr(&*_i.expr);
     _visitor.visit_block(&_i.then_branch);
     if let Some(ref it) = _i.else_branch {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.span);
         _visitor.visit_expr(&*(it).1);
     };
 }
@@ -1479,7 +1506,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.place);
-    tokens_helper(_visitor, &(_i.arrow_token).0);
+    tokens_helper(_visitor, &_i.arrow_token.spans);
     _visitor.visit_expr(&*_i.value);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1488,7 +1515,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     _visitor.visit_expr(&*_i.index);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1507,7 +1534,7 @@
     if let Some(ref it) = _i.label {
         _visitor.visit_label(it)
     };
-    tokens_helper(_visitor, &(_i.loop_token).0);
+    tokens_helper(_visitor, &_i.loop_token.span);
     _visitor.visit_block(&_i.body);
 }
 #[cfg(feature = "full")]
@@ -1524,9 +1551,9 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.match_token).0);
+    tokens_helper(_visitor, &_i.match_token.span);
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for it in &_i.arms {
         _visitor.visit_arm(it)
     }
@@ -1541,12 +1568,12 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.receiver);
-    tokens_helper(_visitor, &(_i.dot_token).0);
+    tokens_helper(_visitor, &_i.dot_token.spans);
     _visitor.visit_ident(&_i.method);
     if let Some(ref it) = _i.turbofish {
         _visitor.visit_method_turbofish(it)
     };
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.args) {
         let it = el.value();
         _visitor.visit_expr(it)
@@ -1557,7 +1584,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     _visitor.visit_expr(&*_i.expr);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1593,9 +1620,9 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.and_token).0);
+    tokens_helper(_visitor, &_i.and_token.spans);
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_expr(&*_i.expr);
 }
@@ -1605,9 +1632,9 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
     _visitor.visit_expr(&*_i.len);
 }
 #[cfg(feature = "full")]
@@ -1616,7 +1643,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.return_token).0);
+    tokens_helper(_visitor, &_i.return_token.span);
     if let Some(ref it) = _i.expr {
         _visitor.visit_expr(&**it)
     };
@@ -1628,13 +1655,13 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_path(&_i.path);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for el in Punctuated::pairs(&_i.fields) {
         let it = el.value();
         _visitor.visit_field_value(it)
     }
     if let Some(ref it) = _i.dot2_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     if let Some(ref it) = _i.rest {
         _visitor.visit_expr(&**it)
@@ -1647,7 +1674,19 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.question_token).0);
+    tokens_helper(_visitor, &_i.question_token.spans);
+}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_try_block<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast ExprTryBlock,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    tokens_helper(_visitor, &_i.try_token.span);
+    _visitor.visit_block(&_i.block);
 }
 #[cfg(feature = "full")]
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1655,7 +1694,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.elems) {
         let it = el.value();
         _visitor.visit_expr(it)
@@ -1668,7 +1707,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&*_i.ty);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1685,7 +1724,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.unsafe_token).0);
+    tokens_helper(_visitor, &_i.unsafe_token.span);
     _visitor.visit_block(&_i.block);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1704,7 +1743,7 @@
     if let Some(ref it) = _i.label {
         _visitor.visit_label(it)
     };
-    tokens_helper(_visitor, &(_i.while_token).0);
+    tokens_helper(_visitor, &_i.while_token.span);
     _visitor.visit_expr(&*_i.cond);
     _visitor.visit_block(&_i.body);
 }
@@ -1720,13 +1759,13 @@
     if let Some(ref it) = _i.label {
         _visitor.visit_label(it)
     };
-    tokens_helper(_visitor, &(_i.while_token).0);
-    tokens_helper(_visitor, &(_i.let_token).0);
+    tokens_helper(_visitor, &_i.while_token.span);
+    tokens_helper(_visitor, &_i.let_token.span);
     for el in Punctuated::pairs(&_i.pats) {
         let it = el.value();
         _visitor.visit_pat(it)
     }
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_expr(&*_i.expr);
     _visitor.visit_block(&_i.body);
 }
@@ -1736,7 +1775,7 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.yield_token).0);
+    tokens_helper(_visitor, &_i.yield_token.span);
     if let Some(ref it) = _i.expr {
         _visitor.visit_expr(&**it)
     };
@@ -1751,7 +1790,7 @@
         _visitor.visit_ident(it)
     };
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     _visitor.visit_type(&_i.ty);
 }
@@ -1763,7 +1802,7 @@
     }
     _visitor.visit_member(&_i.member);
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     _visitor.visit_pat(&*_i.pat);
 }
@@ -1775,7 +1814,7 @@
     }
     _visitor.visit_member(&_i.member);
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     _visitor.visit_expr(&_i.expr);
 }
@@ -1793,7 +1832,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_fields_named<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast FieldsNamed) {
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for el in Punctuated::pairs(&_i.named) {
         let it = el.value();
         _visitor.visit_field(it)
@@ -1804,7 +1843,7 @@
     _visitor: &mut V,
     _i: &'ast FieldsUnnamed,
 ) {
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.unnamed) {
         let it = el.value();
         _visitor.visit_field(it)
@@ -1842,15 +1881,15 @@
 }
 #[cfg(feature = "full")]
 pub fn visit_fn_decl<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast FnDecl) {
-    tokens_helper(_visitor, &(_i.fn_token).0);
+    tokens_helper(_visitor, &_i.fn_token.span);
     _visitor.visit_generics(&_i.generics);
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.inputs) {
         let it = el.value();
         _visitor.visit_fn_arg(it)
     }
     if let Some(ref it) = _i.variadic {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     _visitor.visit_return_type(&_i.output);
 }
@@ -1866,6 +1905,9 @@
         ForeignItem::Type(ref _binding_0) => {
             _visitor.visit_foreign_item_type(_binding_0);
         }
+        ForeignItem::Macro(ref _binding_0) => {
+            _visitor.visit_foreign_item_macro(_binding_0);
+        }
         ForeignItem::Verbatim(ref _binding_0) => {
             _visitor.visit_foreign_item_verbatim(_binding_0);
         }
@@ -1882,7 +1924,20 @@
     _visitor.visit_visibility(&_i.vis);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_fn_decl(&*_i.decl);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_foreign_item_macro<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast ForeignItemMacro,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    _visitor.visit_macro(&_i.mac);
+    if let Some(ref it) = _i.semi_token {
+        tokens_helper(_visitor, &it.spans)
+    };
 }
 #[cfg(feature = "full")]
 pub fn visit_foreign_item_static<'ast, V: Visit<'ast> + ?Sized>(
@@ -1893,14 +1948,14 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.static_token).0);
+    tokens_helper(_visitor, &_i.static_token.span);
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&*_i.ty);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_foreign_item_type<'ast, V: Visit<'ast> + ?Sized>(
@@ -1911,9 +1966,9 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.type_token).0);
+    tokens_helper(_visitor, &_i.type_token.span);
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_foreign_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -1977,14 +2032,14 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_generics<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Generics) {
     if let Some(ref it) = _i.lt_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.params) {
         let it = el.value();
         _visitor.visit_generic_param(it)
     }
     if let Some(ref it) = _i.gt_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     if let Some(ref it) = _i.where_clause {
         _visitor.visit_where_clause(it)
@@ -2003,6 +2058,9 @@
         ImplItem::Type(ref _binding_0) => {
             _visitor.visit_impl_item_type(_binding_0);
         }
+        ImplItem::Existential(ref _binding_0) => {
+            _visitor.visit_impl_item_existential(_binding_0);
+        }
         ImplItem::Macro(ref _binding_0) => {
             _visitor.visit_impl_item_macro(_binding_0);
         }
@@ -2021,15 +2079,36 @@
     }
     _visitor.visit_visibility(&_i.vis);
     if let Some(ref it) = _i.defaultness {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.const_token).0);
+    tokens_helper(_visitor, &_i.const_token.span);
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&_i.ty);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_expr(&_i.expr);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_impl_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast ImplItemExistential,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    tokens_helper(_visitor, &_i.existential_token.span);
+    tokens_helper(_visitor, &_i.type_token.span);
+    _visitor.visit_ident(&_i.ident);
+    _visitor.visit_generics(&_i.generics);
+    if let Some(ref it) = _i.colon_token {
+        tokens_helper(_visitor, &it.spans)
+    };
+    for el in Punctuated::pairs(&_i.bounds) {
+        let it = el.value();
+        _visitor.visit_type_param_bound(it)
+    }
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_impl_item_macro<'ast, V: Visit<'ast> + ?Sized>(
@@ -2041,7 +2120,7 @@
     }
     _visitor.visit_macro(&_i.mac);
     if let Some(ref it) = _i.semi_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2054,7 +2133,7 @@
     }
     _visitor.visit_visibility(&_i.vis);
     if let Some(ref it) = _i.defaultness {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_method_sig(&_i.sig);
     _visitor.visit_block(&_i.block);
@@ -2069,14 +2148,14 @@
     }
     _visitor.visit_visibility(&_i.vis);
     if let Some(ref it) = _i.defaultness {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.type_token).0);
+    tokens_helper(_visitor, &_i.type_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_type(&_i.ty);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_impl_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -2117,6 +2196,9 @@
         Item::Type(ref _binding_0) => {
             _visitor.visit_item_type(_binding_0);
         }
+        Item::Existential(ref _binding_0) => {
+            _visitor.visit_item_existential(_binding_0);
+        }
         Item::Struct(ref _binding_0) => {
             _visitor.visit_item_struct(_binding_0);
         }
@@ -2149,13 +2231,13 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.const_token).0);
+    tokens_helper(_visitor, &_i.const_token.span);
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&*_i.ty);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_enum<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemEnum) {
@@ -2163,16 +2245,38 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.enum_token).0);
+    tokens_helper(_visitor, &_i.enum_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for el in Punctuated::pairs(&_i.variants) {
         let it = el.value();
         _visitor.visit_variant(it)
     }
 }
 #[cfg(feature = "full")]
+pub fn visit_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast ItemExistential,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    _visitor.visit_visibility(&_i.vis);
+    tokens_helper(_visitor, &_i.existential_token.span);
+    tokens_helper(_visitor, &_i.type_token.span);
+    _visitor.visit_ident(&_i.ident);
+    _visitor.visit_generics(&_i.generics);
+    if let Some(ref it) = _i.colon_token {
+        tokens_helper(_visitor, &it.spans)
+    };
+    for el in Punctuated::pairs(&_i.bounds) {
+        let it = el.value();
+        _visitor.visit_type_param_bound(it)
+    }
+    tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_item_extern_crate<'ast, V: Visit<'ast> + ?Sized>(
     _visitor: &mut V,
     _i: &'ast ItemExternCrate,
@@ -2181,14 +2285,14 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.extern_token).0);
-    tokens_helper(_visitor, &(_i.crate_token).0);
+    tokens_helper(_visitor, &_i.extern_token.span);
+    tokens_helper(_visitor, &_i.crate_token.span);
     _visitor.visit_ident(&_i.ident);
     if let Some(ref it) = _i.rename {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.span);
         _visitor.visit_ident(&(it).1);
     };
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_fn<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemFn) {
@@ -2197,10 +2301,13 @@
     }
     _visitor.visit_visibility(&_i.vis);
     if let Some(ref it) = _i.constness {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.unsafety {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
+    };
+    if let Some(ref it) = _i.asyncness {
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.abi {
         _visitor.visit_abi(it)
@@ -2218,7 +2325,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_abi(&_i.abi);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for it in &_i.items {
         _visitor.visit_foreign_item(it)
     }
@@ -2229,22 +2336,22 @@
         _visitor.visit_attribute(it)
     }
     if let Some(ref it) = _i.defaultness {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.unsafety {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.impl_token).0);
+    tokens_helper(_visitor, &_i.impl_token.span);
     _visitor.visit_generics(&_i.generics);
     if let Some(ref it) = _i.trait_ {
         if let Some(ref it) = (it).0 {
-            tokens_helper(_visitor, &(it).0)
+            tokens_helper(_visitor, &it.spans)
         };
         _visitor.visit_path(&(it).1);
-        tokens_helper(_visitor, &((it).2).0);
+        tokens_helper(_visitor, &(it).2.span);
     };
     _visitor.visit_type(&*_i.self_ty);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for it in &_i.items {
         _visitor.visit_impl_item(it)
     }
@@ -2259,7 +2366,7 @@
     };
     _visitor.visit_macro(&_i.mac);
     if let Some(ref it) = _i.semi_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2268,11 +2375,11 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.macro_token).0);
+    tokens_helper(_visitor, &_i.macro_token.span);
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     skip!(_i.args);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     skip!(_i.body);
 }
 #[cfg(feature = "full")]
@@ -2281,16 +2388,16 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.mod_token).0);
+    tokens_helper(_visitor, &_i.mod_token.span);
     _visitor.visit_ident(&_i.ident);
     if let Some(ref it) = _i.content {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.span);
         for it in &(it).1 {
             _visitor.visit_item(it)
         }
     };
     if let Some(ref it) = _i.semi {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2299,16 +2406,16 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.static_token).0);
+    tokens_helper(_visitor, &_i.static_token.span);
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&*_i.ty);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_expr(&*_i.expr);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_struct<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemStruct) {
@@ -2316,12 +2423,12 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.struct_token).0);
+    tokens_helper(_visitor, &_i.struct_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
     _visitor.visit_fields(&_i.fields);
     if let Some(ref it) = _i.semi_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2331,22 +2438,22 @@
     }
     _visitor.visit_visibility(&_i.vis);
     if let Some(ref it) = _i.unsafety {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.auto_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.trait_token).0);
+    tokens_helper(_visitor, &_i.trait_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.supertraits) {
         let it = el.value();
         _visitor.visit_type_param_bound(it)
     }
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for it in &_i.items {
         _visitor.visit_trait_item(it)
     }
@@ -2357,12 +2464,12 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.type_token).0);
+    tokens_helper(_visitor, &_i.type_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_type(&*_i.ty);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_union<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemUnion) {
@@ -2370,7 +2477,7 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.union_token).0);
+    tokens_helper(_visitor, &_i.union_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
     _visitor.visit_fields_named(&_i.fields);
@@ -2381,12 +2488,12 @@
         _visitor.visit_attribute(it)
     }
     _visitor.visit_visibility(&_i.vis);
-    tokens_helper(_visitor, &(_i.use_token).0);
+    tokens_helper(_visitor, &_i.use_token.span);
     if let Some(ref it) = _i.leading_colon {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     _visitor.visit_use_tree(&_i.tree);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -2399,7 +2506,7 @@
 #[cfg(feature = "full")]
 pub fn visit_label<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Label) {
     _visitor.visit_lifetime(&_i.name);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_lifetime<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Lifetime) {
@@ -2413,7 +2520,7 @@
     }
     _visitor.visit_lifetime(&_i.lifetime);
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
@@ -2488,25 +2595,25 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.let_token).0);
+    tokens_helper(_visitor, &_i.let_token.span);
     for el in Punctuated::pairs(&_i.pats) {
         let it = el.value();
         _visitor.visit_pat(it)
     }
     if let Some(ref it) = _i.ty {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.spans);
         _visitor.visit_type(&*(it).1);
     };
     if let Some(ref it) = _i.init {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.spans);
         _visitor.visit_expr(&*(it).1);
     };
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_macro<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Macro) {
     _visitor.visit_path(&_i.path);
-    tokens_helper(_visitor, &(_i.bang_token).0);
+    tokens_helper(_visitor, &_i.bang_token.spans);
     _visitor.visit_macro_delimiter(&_i.delimiter);
     skip!(_i.tts);
 }
@@ -2517,13 +2624,13 @@
 ) {
     match *_i {
         MacroDelimiter::Paren(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.span);
         }
         MacroDelimiter::Brace(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.span);
         }
         MacroDelimiter::Bracket(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.span);
         }
     }
 }
@@ -2555,7 +2662,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_meta_list<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast MetaList) {
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.nested) {
         let it = el.value();
         _visitor.visit_nested_meta(it)
@@ -2567,16 +2674,19 @@
     _i: &'ast MetaNameValue,
 ) {
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_lit(&_i.lit);
 }
 #[cfg(feature = "full")]
 pub fn visit_method_sig<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast MethodSig) {
     if let Some(ref it) = _i.constness {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.unsafety {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
+    };
+    if let Some(ref it) = _i.asyncness {
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.abi {
         _visitor.visit_abi(it)
@@ -2590,13 +2700,13 @@
     _visitor: &mut V,
     _i: &'ast MethodTurbofish,
 ) {
-    tokens_helper(_visitor, &(_i.colon2_token).0);
-    tokens_helper(_visitor, &(_i.lt_token).0);
+    tokens_helper(_visitor, &_i.colon2_token.spans);
+    tokens_helper(_visitor, &_i.lt_token.spans);
     for el in Punctuated::pairs(&_i.args) {
         let it = el.value();
         _visitor.visit_generic_method_argument(it)
     }
-    tokens_helper(_visitor, &(_i.gt_token).0);
+    tokens_helper(_visitor, &_i.gt_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_nested_meta<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast NestedMeta) {
@@ -2614,7 +2724,7 @@
     _visitor: &mut V,
     _i: &'ast ParenthesizedGenericArguments,
 ) {
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.inputs) {
         let it = el.value();
         _visitor.visit_type(it)
@@ -2669,21 +2779,21 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_box<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatBox) {
-    tokens_helper(_visitor, &(_i.box_token).0);
+    tokens_helper(_visitor, &_i.box_token.span);
     _visitor.visit_pat(&*_i.pat);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_ident<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatIdent) {
     if let Some(ref it) = _i.by_ref {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_ident(&_i.ident);
     if let Some(ref it) = _i.subpat {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.spans);
         _visitor.visit_pat(&*(it).1);
     };
 }
@@ -2715,16 +2825,16 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_ref<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatRef) {
-    tokens_helper(_visitor, &(_i.and_token).0);
+    tokens_helper(_visitor, &_i.and_token.spans);
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_pat(&*_i.pat);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_slice<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatSlice) {
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     for el in Punctuated::pairs(&_i.front) {
         let it = el.value();
         _visitor.visit_pat(it)
@@ -2733,10 +2843,10 @@
         _visitor.visit_pat(&**it)
     };
     if let Some(ref it) = _i.dot2_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     if let Some(ref it) = _i.comma_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.back) {
         let it = el.value();
@@ -2747,28 +2857,28 @@
 #[cfg(feature = "full")]
 pub fn visit_pat_struct<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatStruct) {
     _visitor.visit_path(&_i.path);
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for el in Punctuated::pairs(&_i.fields) {
         let it = el.value();
         _visitor.visit_field_pat(it)
     }
     if let Some(ref it) = _i.dot2_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_tuple<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatTuple) {
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.front) {
         let it = el.value();
         _visitor.visit_pat(it)
     }
     if let Some(ref it) = _i.dot2_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     if let Some(ref it) = _i.comma_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.back) {
         let it = el.value();
@@ -2792,12 +2902,12 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_wild<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatWild) {
-    tokens_helper(_visitor, &(_i.underscore_token).0);
+    tokens_helper(_visitor, &_i.underscore_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_path<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Path) {
     if let Some(ref it) = _i.leading_colon {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.segments) {
         let it = el.value();
@@ -2827,7 +2937,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_predicate_eq<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PredicateEq) {
     _visitor.visit_type(&_i.lhs_ty);
-    tokens_helper(_visitor, &(_i.eq_token).0);
+    tokens_helper(_visitor, &_i.eq_token.spans);
     _visitor.visit_type(&_i.rhs_ty);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2836,9 +2946,7 @@
     _i: &'ast PredicateLifetime,
 ) {
     _visitor.visit_lifetime(&_i.lifetime);
-    if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
-    };
+    tokens_helper(_visitor, &_i.colon_token.spans);
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
         _visitor.visit_lifetime(it)
@@ -2853,7 +2961,7 @@
         _visitor.visit_bound_lifetimes(it)
     };
     _visitor.visit_type(&_i.bounded_ty);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
         _visitor.visit_type_param_bound(it)
@@ -2861,23 +2969,23 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_qself<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast QSelf) {
-    tokens_helper(_visitor, &(_i.lt_token).0);
+    tokens_helper(_visitor, &_i.lt_token.spans);
     _visitor.visit_type(&*_i.ty);
     skip!(_i.position);
     if let Some(ref it) = _i.as_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
-    tokens_helper(_visitor, &(_i.gt_token).0);
+    tokens_helper(_visitor, &_i.gt_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_range_limits<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast RangeLimits) {
     match *_i {
         RangeLimits::HalfOpen(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         RangeLimits::Closed(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
     }
 }
@@ -2886,7 +2994,7 @@
     match *_i {
         ReturnType::Default => {}
         ReturnType::Type(ref _binding_0, ref _binding_1) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
             _visitor.visit_type(&**_binding_1);
         }
     }
@@ -2907,14 +3015,14 @@
         }
         Stmt::Semi(ref _binding_0, ref _binding_1) => {
             _visitor.visit_expr(_binding_0);
-            tokens_helper(_visitor, &(_binding_1).0);
+            tokens_helper(_visitor, &_binding_1.spans);
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_trait_bound<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TraitBound) {
     if let Some(ref it) = _i.paren_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_trait_bound_modifier(&_i.modifier);
     if let Some(ref it) = _i.lifetimes {
@@ -2930,7 +3038,7 @@
     match *_i {
         TraitBoundModifier::None => {}
         TraitBoundModifier::Maybe(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
     }
 }
@@ -2962,15 +3070,15 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.const_token).0);
+    tokens_helper(_visitor, &_i.const_token.span);
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon_token).0);
+    tokens_helper(_visitor, &_i.colon_token.spans);
     _visitor.visit_type(&_i.ty);
     if let Some(ref it) = _i.default {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.spans);
         _visitor.visit_expr(&(it).1);
     };
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_trait_item_macro<'ast, V: Visit<'ast> + ?Sized>(
@@ -2982,7 +3090,7 @@
     }
     _visitor.visit_macro(&_i.mac);
     if let Some(ref it) = _i.semi_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2998,7 +3106,7 @@
         _visitor.visit_block(it)
     };
     if let Some(ref it) = _i.semi_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -3009,21 +3117,21 @@
     for it in &_i.attrs {
         _visitor.visit_attribute(it)
     }
-    tokens_helper(_visitor, &(_i.type_token).0);
+    tokens_helper(_visitor, &_i.type_token.span);
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_generics(&_i.generics);
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
         _visitor.visit_type_param_bound(it)
     }
     if let Some(ref it) = _i.default {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.spans);
         _visitor.visit_type(&(it).1);
     };
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_trait_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -3084,36 +3192,36 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_array<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeArray) {
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     _visitor.visit_type(&*_i.elem);
-    tokens_helper(_visitor, &(_i.semi_token).0);
+    tokens_helper(_visitor, &_i.semi_token.spans);
     _visitor.visit_expr(&_i.len);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_bare_fn<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeBareFn) {
+    if let Some(ref it) = _i.lifetimes {
+        _visitor.visit_bound_lifetimes(it)
+    };
     if let Some(ref it) = _i.unsafety {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.abi {
         _visitor.visit_abi(it)
     };
-    tokens_helper(_visitor, &(_i.fn_token).0);
-    if let Some(ref it) = _i.lifetimes {
-        _visitor.visit_bound_lifetimes(it)
-    };
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.fn_token.span);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.inputs) {
         let it = el.value();
         _visitor.visit_bare_fn_arg(it)
     }
     if let Some(ref it) = _i.variadic {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     _visitor.visit_return_type(&_i.output);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_group<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeGroup) {
-    tokens_helper(_visitor, &(_i.group_token).0);
+    tokens_helper(_visitor, &_i.group_token.span);
     _visitor.visit_type(&*_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -3121,7 +3229,7 @@
     _visitor: &mut V,
     _i: &'ast TypeImplTrait,
 ) {
-    tokens_helper(_visitor, &(_i.impl_token).0);
+    tokens_helper(_visitor, &_i.impl_token.span);
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
         _visitor.visit_type_param_bound(it)
@@ -3129,7 +3237,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_infer<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeInfer) {
-    tokens_helper(_visitor, &(_i.underscore_token).0);
+    tokens_helper(_visitor, &_i.underscore_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_macro<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeMacro) {
@@ -3137,7 +3245,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_never<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeNever) {
-    tokens_helper(_visitor, &(_i.bang_token).0);
+    tokens_helper(_visitor, &_i.bang_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_param<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeParam) {
@@ -3146,14 +3254,14 @@
     }
     _visitor.visit_ident(&_i.ident);
     if let Some(ref it) = _i.colon_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
         _visitor.visit_type_param_bound(it)
     }
     if let Some(ref it) = _i.eq_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.spans)
     };
     if let Some(ref it) = _i.default {
         _visitor.visit_type(it)
@@ -3175,7 +3283,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_paren<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeParen) {
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     _visitor.visit_type(&*_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -3187,12 +3295,12 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_ptr<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypePtr) {
-    tokens_helper(_visitor, &(_i.star_token).0);
+    tokens_helper(_visitor, &_i.star_token.spans);
     if let Some(ref it) = _i.const_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_type(&*_i.elem);
 }
@@ -3201,18 +3309,18 @@
     _visitor: &mut V,
     _i: &'ast TypeReference,
 ) {
-    tokens_helper(_visitor, &(_i.and_token).0);
+    tokens_helper(_visitor, &_i.and_token.spans);
     if let Some(ref it) = _i.lifetime {
         _visitor.visit_lifetime(it)
     };
     if let Some(ref it) = _i.mutability {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_type(&*_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_slice<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeSlice) {
-    tokens_helper(_visitor, &(_i.bracket_token).0);
+    tokens_helper(_visitor, &_i.bracket_token.span);
     _visitor.visit_type(&*_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -3221,7 +3329,7 @@
     _i: &'ast TypeTraitObject,
 ) {
     if let Some(ref it) = _i.dyn_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     for el in Punctuated::pairs(&_i.bounds) {
         let it = el.value();
@@ -3230,7 +3338,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_tuple<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeTuple) {
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.paren_token.span);
     for el in Punctuated::pairs(&_i.elems) {
         let it = el.value();
         _visitor.visit_type(it)
@@ -3247,23 +3355,23 @@
 pub fn visit_un_op<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UnOp) {
     match *_i {
         UnOp::Deref(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         UnOp::Not(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
         UnOp::Neg(ref _binding_0) => {
-            tokens_helper(_visitor, &(_binding_0).0);
+            tokens_helper(_visitor, &_binding_0.spans);
         }
     }
 }
 #[cfg(feature = "full")]
 pub fn visit_use_glob<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseGlob) {
-    tokens_helper(_visitor, &(_i.star_token).0);
+    tokens_helper(_visitor, &_i.star_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_use_group<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseGroup) {
-    tokens_helper(_visitor, &(_i.brace_token).0);
+    tokens_helper(_visitor, &_i.brace_token.span);
     for el in Punctuated::pairs(&_i.items) {
         let it = el.value();
         _visitor.visit_use_tree(it)
@@ -3276,13 +3384,13 @@
 #[cfg(feature = "full")]
 pub fn visit_use_path<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UsePath) {
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.colon2_token).0);
+    tokens_helper(_visitor, &_i.colon2_token.spans);
     _visitor.visit_use_tree(&*_i.tree);
 }
 #[cfg(feature = "full")]
 pub fn visit_use_rename<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseRename) {
     _visitor.visit_ident(&_i.ident);
-    tokens_helper(_visitor, &(_i.as_token).0);
+    tokens_helper(_visitor, &_i.as_token.span);
     _visitor.visit_ident(&_i.rename);
 }
 #[cfg(feature = "full")]
@@ -3313,27 +3421,27 @@
     _visitor.visit_ident(&_i.ident);
     _visitor.visit_fields(&_i.fields);
     if let Some(ref it) = _i.discriminant {
-        tokens_helper(_visitor, &((it).0).0);
+        tokens_helper(_visitor, &(it).0.spans);
         _visitor.visit_expr(&(it).1);
     };
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_vis_crate<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast VisCrate) {
-    tokens_helper(_visitor, &(_i.crate_token).0);
+    tokens_helper(_visitor, &_i.crate_token.span);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_vis_public<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast VisPublic) {
-    tokens_helper(_visitor, &(_i.pub_token).0);
+    tokens_helper(_visitor, &_i.pub_token.span);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_vis_restricted<'ast, V: Visit<'ast> + ?Sized>(
     _visitor: &mut V,
     _i: &'ast VisRestricted,
 ) {
-    tokens_helper(_visitor, &(_i.pub_token).0);
-    tokens_helper(_visitor, &(_i.paren_token).0);
+    tokens_helper(_visitor, &_i.pub_token.span);
+    tokens_helper(_visitor, &_i.paren_token.span);
     if let Some(ref it) = _i.in_token {
-        tokens_helper(_visitor, &(it).0)
+        tokens_helper(_visitor, &it.span)
     };
     _visitor.visit_path(&*_i.path);
 }
@@ -3354,7 +3462,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_where_clause<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast WhereClause) {
-    tokens_helper(_visitor, &(_i.where_token).0);
+    tokens_helper(_visitor, &_i.where_token.span);
     for el in Punctuated::pairs(&_i.predicates) {
         let it = el.value();
         _visitor.visit_where_predicate(it)
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 14a7970..2b445c7 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -136,6 +136,11 @@
     fn visit_expr_assign_op_mut(&mut self, i: &mut ExprAssignOp) {
         visit_expr_assign_op_mut(self, i)
     }
+    #[cfg(feature = "full")]
+    #[cfg(any(feature = "full", feature = "derive"))]
+    fn visit_expr_async_mut(&mut self, i: &mut ExprAsync) {
+        visit_expr_async_mut(self, i)
+    }
     #[cfg(any(feature = "full", feature = "derive"))]
     fn visit_expr_binary_mut(&mut self, i: &mut ExprBinary) {
         visit_expr_binary_mut(self, i)
@@ -165,11 +170,6 @@
     }
     #[cfg(feature = "full")]
     #[cfg(any(feature = "full", feature = "derive"))]
-    fn visit_expr_catch_mut(&mut self, i: &mut ExprCatch) {
-        visit_expr_catch_mut(self, i)
-    }
-    #[cfg(feature = "full")]
-    #[cfg(any(feature = "full", feature = "derive"))]
     fn visit_expr_closure_mut(&mut self, i: &mut ExprClosure) {
         visit_expr_closure_mut(self, i)
     }
@@ -275,6 +275,11 @@
     }
     #[cfg(feature = "full")]
     #[cfg(any(feature = "full", feature = "derive"))]
+    fn visit_expr_try_block_mut(&mut self, i: &mut ExprTryBlock) {
+        visit_expr_try_block_mut(self, i)
+    }
+    #[cfg(feature = "full")]
+    #[cfg(any(feature = "full", feature = "derive"))]
     fn visit_expr_tuple_mut(&mut self, i: &mut ExprTuple) {
         visit_expr_tuple_mut(self, i)
     }
@@ -358,6 +363,10 @@
         visit_foreign_item_fn_mut(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_foreign_item_macro_mut(&mut self, i: &mut ForeignItemMacro) {
+        visit_foreign_item_macro_mut(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_foreign_item_static_mut(&mut self, i: &mut ForeignItemStatic) {
         visit_foreign_item_static_mut(self, i)
     }
@@ -398,6 +407,10 @@
         visit_impl_item_const_mut(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_impl_item_existential_mut(&mut self, i: &mut ImplItemExistential) {
+        visit_impl_item_existential_mut(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_impl_item_macro_mut(&mut self, i: &mut ImplItemMacro) {
         visit_impl_item_macro_mut(self, i)
     }
@@ -430,6 +443,10 @@
         visit_item_enum_mut(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_item_existential_mut(&mut self, i: &mut ItemExistential) {
+        visit_item_existential_mut(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_item_extern_crate_mut(&mut self, i: &mut ItemExternCrate) {
         visit_item_extern_crate_mut(self, i)
     }
@@ -858,7 +875,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_abi_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Abi) {
-    tokens_helper(_visitor, &mut (_i.extern_token).0);
+    tokens_helper(_visitor, &mut _i.extern_token.span);
     if let Some(ref mut it) = _i.name {
         _visitor.visit_lit_str_mut(it)
     };
@@ -869,38 +886,38 @@
     _i: &mut AngleBracketedGenericArguments,
 ) {
     if let Some(ref mut it) = _i.colon2_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
-    tokens_helper(_visitor, &mut (_i.lt_token).0);
+    tokens_helper(_visitor, &mut _i.lt_token.spans);
     for mut el in Punctuated::pairs_mut(&mut _i.args) {
         let it = el.value_mut();
         _visitor.visit_generic_argument_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.gt_token).0);
+    tokens_helper(_visitor, &mut _i.gt_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_arg_captured_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ArgCaptured) {
     _visitor.visit_pat_mut(&mut _i.pat);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut _i.ty);
 }
 #[cfg(feature = "full")]
 pub fn visit_arg_self_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ArgSelf) {
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.self_token).0);
+    tokens_helper(_visitor, &mut _i.self_token.span);
 }
 #[cfg(feature = "full")]
 pub fn visit_arg_self_ref_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ArgSelfRef) {
-    tokens_helper(_visitor, &mut (_i.and_token).0);
+    tokens_helper(_visitor, &mut _i.and_token.spans);
     if let Some(ref mut it) = _i.lifetime {
         _visitor.visit_lifetime_mut(it)
     };
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.self_token).0);
+    tokens_helper(_visitor, &mut _i.self_token.span);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
@@ -909,20 +926,20 @@
         _visitor.visit_attribute_mut(it)
     }
     if let Some(ref mut it) = _i.leading_vert {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.pats) {
         let it = el.value_mut();
         _visitor.visit_pat_mut(it)
     }
     if let Some(ref mut it) = _i.guard {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.span);
         _visitor.visit_expr_mut(&mut *(it).1);
     };
-    tokens_helper(_visitor, &mut (_i.fat_arrow_token).0);
+    tokens_helper(_visitor, &mut _i.fat_arrow_token.spans);
     _visitor.visit_expr_mut(&mut *_i.body);
     if let Some(ref mut it) = _i.comma {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -930,24 +947,23 @@
     match *_i {
         AttrStyle::Outer => {}
         AttrStyle::Inner(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_attribute_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Attribute) {
-    tokens_helper(_visitor, &mut (_i.pound_token).0);
+    tokens_helper(_visitor, &mut _i.pound_token.spans);
     _visitor.visit_attr_style_mut(&mut _i.style);
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     _visitor.visit_path_mut(&mut _i.path);
     skip!(_i.tts);
-    skip!(_i.is_sugared_doc);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_bare_fn_arg_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut BareFnArg) {
     if let Some(ref mut it) = _i.name {
         _visitor.visit_bare_fn_arg_name_mut(&mut (it).0);
-        tokens_helper(_visitor, &mut ((it).1).0);
+        tokens_helper(_visitor, &mut (it).1.spans);
     };
     _visitor.visit_type_mut(&mut _i.ty);
 }
@@ -958,7 +974,7 @@
             _visitor.visit_ident_mut(_binding_0);
         }
         BareFnArgName::Wild(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
     }
 }
@@ -966,126 +982,126 @@
 pub fn visit_bin_op_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut BinOp) {
     match *_i {
         BinOp::Add(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Sub(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Mul(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Div(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Rem(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::And(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Or(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::BitXor(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::BitAnd(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::BitOr(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Shl(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Shr(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Eq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Lt(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Le(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Ne(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Ge(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::Gt(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::AddEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::SubEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::MulEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::DivEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::RemEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::BitXorEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::BitAndEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::BitOrEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::ShlEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         BinOp::ShrEq(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_binding_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Binding) {
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_type_mut(&mut _i.ty);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_block_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Block) {
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for it in &mut _i.stmts {
         _visitor.visit_stmt_mut(it)
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_bound_lifetimes_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut BoundLifetimes) {
-    tokens_helper(_visitor, &mut (_i.for_token).0);
-    tokens_helper(_visitor, &mut (_i.lt_token).0);
+    tokens_helper(_visitor, &mut _i.for_token.span);
+    tokens_helper(_visitor, &mut _i.lt_token.spans);
     for mut el in Punctuated::pairs_mut(&mut _i.lifetimes) {
         let it = el.value_mut();
         _visitor.visit_lifetime_def_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.gt_token).0);
+    tokens_helper(_visitor, &mut _i.gt_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_const_param_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ConstParam) {
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.const_token).0);
+    tokens_helper(_visitor, &mut _i.const_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut _i.ty);
     if let Some(ref mut it) = _i.eq_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     if let Some(ref mut it) = _i.default {
         _visitor.visit_expr_mut(it)
@@ -1107,8 +1123,8 @@
 }
 #[cfg(feature = "derive")]
 pub fn visit_data_enum_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut DataEnum) {
-    tokens_helper(_visitor, &mut (_i.enum_token).0);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.enum_token.span);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.variants) {
         let it = el.value_mut();
         _visitor.visit_variant_mut(it)
@@ -1116,15 +1132,15 @@
 }
 #[cfg(feature = "derive")]
 pub fn visit_data_struct_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut DataStruct) {
-    tokens_helper(_visitor, &mut (_i.struct_token).0);
+    tokens_helper(_visitor, &mut _i.struct_token.span);
     _visitor.visit_fields_mut(&mut _i.fields);
     if let Some(ref mut it) = _i.semi_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "derive")]
 pub fn visit_data_union_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut DataUnion) {
-    tokens_helper(_visitor, &mut (_i.union_token).0);
+    tokens_helper(_visitor, &mut _i.union_token.span);
     _visitor.visit_fields_named_mut(&mut _i.fields);
 }
 #[cfg(feature = "derive")]
@@ -1251,8 +1267,11 @@
         Expr::Try(ref mut _binding_0) => {
             full!(_visitor.visit_expr_try_mut(_binding_0));
         }
-        Expr::Catch(ref mut _binding_0) => {
-            full!(_visitor.visit_expr_catch_mut(_binding_0));
+        Expr::Async(ref mut _binding_0) => {
+            full!(_visitor.visit_expr_async_mut(_binding_0));
+        }
+        Expr::TryBlock(ref mut _binding_0) => {
+            full!(_visitor.visit_expr_try_block_mut(_binding_0));
         }
         Expr::Yield(ref mut _binding_0) => {
             full!(_visitor.visit_expr_yield_mut(_binding_0));
@@ -1268,7 +1287,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.elems) {
         let it = el.value_mut();
         _visitor.visit_expr_mut(it)
@@ -1281,7 +1300,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.left);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_expr_mut(&mut *_i.right);
 }
 #[cfg(feature = "full")]
@@ -1294,6 +1313,18 @@
     _visitor.visit_bin_op_mut(&mut _i.op);
     _visitor.visit_expr_mut(&mut *_i.right);
 }
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_async_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprAsync) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.async_token.span);
+    if let Some(ref mut it) = _i.capture {
+        tokens_helper(_visitor, &mut it.span)
+    };
+    _visitor.visit_block_mut(&mut _i.block);
+}
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_expr_binary_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprBinary) {
     for it in &mut _i.attrs {
@@ -1309,6 +1340,9 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
+    if let Some(ref mut it) = _i.label {
+        _visitor.visit_label_mut(it)
+    };
     _visitor.visit_block_mut(&mut _i.block);
 }
 #[cfg(feature = "full")]
@@ -1317,7 +1351,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.box_token).0);
+    tokens_helper(_visitor, &mut _i.box_token.span);
     _visitor.visit_expr_mut(&mut *_i.expr);
 }
 #[cfg(feature = "full")]
@@ -1326,7 +1360,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.break_token).0);
+    tokens_helper(_visitor, &mut _i.break_token.span);
     if let Some(ref mut it) = _i.label {
         _visitor.visit_lifetime_mut(it)
     };
@@ -1340,7 +1374,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.func);
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.args) {
         let it = el.value_mut();
         _visitor.visit_expr_mut(it)
@@ -1352,37 +1386,30 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.as_token).0);
+    tokens_helper(_visitor, &mut _i.as_token.span);
     _visitor.visit_type_mut(&mut *_i.ty);
 }
 #[cfg(feature = "full")]
 #[cfg(any(feature = "full", feature = "derive"))]
-pub fn visit_expr_catch_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprCatch) {
-    for it in &mut _i.attrs {
-        _visitor.visit_attribute_mut(it)
-    }
-    tokens_helper(_visitor, &mut (_i.do_token).0);
-    tokens_helper(_visitor, &mut (_i.catch_token).0);
-    _visitor.visit_block_mut(&mut _i.block);
-}
-#[cfg(feature = "full")]
-#[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_expr_closure_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprClosure) {
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
+    if let Some(ref mut it) = _i.asyncness {
+        tokens_helper(_visitor, &mut it.span)
+    };
     if let Some(ref mut it) = _i.movability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.capture {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.or1_token).0);
+    tokens_helper(_visitor, &mut _i.or1_token.spans);
     for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
         let it = el.value_mut();
         _visitor.visit_fn_arg_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.or2_token).0);
+    tokens_helper(_visitor, &mut _i.or2_token.spans);
     _visitor.visit_return_type_mut(&mut _i.output);
     _visitor.visit_expr_mut(&mut *_i.body);
 }
@@ -1392,7 +1419,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.continue_token).0);
+    tokens_helper(_visitor, &mut _i.continue_token.span);
     if let Some(ref mut it) = _i.label {
         _visitor.visit_lifetime_mut(it)
     };
@@ -1403,7 +1430,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.base);
-    tokens_helper(_visitor, &mut (_i.dot_token).0);
+    tokens_helper(_visitor, &mut _i.dot_token.spans);
     _visitor.visit_member_mut(&mut _i.member);
 }
 #[cfg(feature = "full")]
@@ -1415,9 +1442,9 @@
     if let Some(ref mut it) = _i.label {
         _visitor.visit_label_mut(it)
     };
-    tokens_helper(_visitor, &mut (_i.for_token).0);
+    tokens_helper(_visitor, &mut _i.for_token.span);
     _visitor.visit_pat_mut(&mut *_i.pat);
-    tokens_helper(_visitor, &mut (_i.in_token).0);
+    tokens_helper(_visitor, &mut _i.in_token.span);
     _visitor.visit_expr_mut(&mut *_i.expr);
     _visitor.visit_block_mut(&mut _i.body);
 }
@@ -1427,7 +1454,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.group_token).0);
+    tokens_helper(_visitor, &mut _i.group_token.span);
     _visitor.visit_expr_mut(&mut *_i.expr);
 }
 #[cfg(feature = "full")]
@@ -1436,11 +1463,11 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.if_token).0);
+    tokens_helper(_visitor, &mut _i.if_token.span);
     _visitor.visit_expr_mut(&mut *_i.cond);
     _visitor.visit_block_mut(&mut _i.then_branch);
     if let Some(ref mut it) = _i.else_branch {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.span);
         _visitor.visit_expr_mut(&mut *(it).1);
     };
 }
@@ -1450,17 +1477,17 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.if_token).0);
-    tokens_helper(_visitor, &mut (_i.let_token).0);
+    tokens_helper(_visitor, &mut _i.if_token.span);
+    tokens_helper(_visitor, &mut _i.let_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.pats) {
         let it = el.value_mut();
         _visitor.visit_pat_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_expr_mut(&mut *_i.expr);
     _visitor.visit_block_mut(&mut _i.then_branch);
     if let Some(ref mut it) = _i.else_branch {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.span);
         _visitor.visit_expr_mut(&mut *(it).1);
     };
 }
@@ -1471,7 +1498,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.place);
-    tokens_helper(_visitor, &mut (_i.arrow_token).0);
+    tokens_helper(_visitor, &mut _i.arrow_token.spans);
     _visitor.visit_expr_mut(&mut *_i.value);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1480,7 +1507,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     _visitor.visit_expr_mut(&mut *_i.index);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1499,7 +1526,7 @@
     if let Some(ref mut it) = _i.label {
         _visitor.visit_label_mut(it)
     };
-    tokens_helper(_visitor, &mut (_i.loop_token).0);
+    tokens_helper(_visitor, &mut _i.loop_token.span);
     _visitor.visit_block_mut(&mut _i.body);
 }
 #[cfg(feature = "full")]
@@ -1516,9 +1543,9 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.match_token).0);
+    tokens_helper(_visitor, &mut _i.match_token.span);
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for it in &mut _i.arms {
         _visitor.visit_arm_mut(it)
     }
@@ -1530,12 +1557,12 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.receiver);
-    tokens_helper(_visitor, &mut (_i.dot_token).0);
+    tokens_helper(_visitor, &mut _i.dot_token.spans);
     _visitor.visit_ident_mut(&mut _i.method);
     if let Some(ref mut it) = _i.turbofish {
         _visitor.visit_method_turbofish_mut(it)
     };
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.args) {
         let it = el.value_mut();
         _visitor.visit_expr_mut(it)
@@ -1546,7 +1573,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     _visitor.visit_expr_mut(&mut *_i.expr);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1579,9 +1606,9 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.and_token).0);
+    tokens_helper(_visitor, &mut _i.and_token.spans);
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_expr_mut(&mut *_i.expr);
 }
@@ -1591,9 +1618,9 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
     _visitor.visit_expr_mut(&mut *_i.len);
 }
 #[cfg(feature = "full")]
@@ -1602,7 +1629,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.return_token).0);
+    tokens_helper(_visitor, &mut _i.return_token.span);
     if let Some(ref mut it) = _i.expr {
         _visitor.visit_expr_mut(&mut **it)
     };
@@ -1614,13 +1641,13 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_path_mut(&mut _i.path);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.fields) {
         let it = el.value_mut();
         _visitor.visit_field_value_mut(it)
     }
     if let Some(ref mut it) = _i.dot2_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     if let Some(ref mut it) = _i.rest {
         _visitor.visit_expr_mut(&mut **it)
@@ -1633,7 +1660,16 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.question_token).0);
+    tokens_helper(_visitor, &mut _i.question_token.spans);
+}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_try_block_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprTryBlock) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.try_token.span);
+    _visitor.visit_block_mut(&mut _i.block);
 }
 #[cfg(feature = "full")]
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1641,7 +1677,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.elems) {
         let it = el.value_mut();
         _visitor.visit_expr_mut(it)
@@ -1654,7 +1690,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut *_i.ty);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1671,7 +1707,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.unsafe_token).0);
+    tokens_helper(_visitor, &mut _i.unsafe_token.span);
     _visitor.visit_block_mut(&mut _i.block);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -1687,7 +1723,7 @@
     if let Some(ref mut it) = _i.label {
         _visitor.visit_label_mut(it)
     };
-    tokens_helper(_visitor, &mut (_i.while_token).0);
+    tokens_helper(_visitor, &mut _i.while_token.span);
     _visitor.visit_expr_mut(&mut *_i.cond);
     _visitor.visit_block_mut(&mut _i.body);
 }
@@ -1700,13 +1736,13 @@
     if let Some(ref mut it) = _i.label {
         _visitor.visit_label_mut(it)
     };
-    tokens_helper(_visitor, &mut (_i.while_token).0);
-    tokens_helper(_visitor, &mut (_i.let_token).0);
+    tokens_helper(_visitor, &mut _i.while_token.span);
+    tokens_helper(_visitor, &mut _i.let_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.pats) {
         let it = el.value_mut();
         _visitor.visit_pat_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_expr_mut(&mut *_i.expr);
     _visitor.visit_block_mut(&mut _i.body);
 }
@@ -1716,7 +1752,7 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.yield_token).0);
+    tokens_helper(_visitor, &mut _i.yield_token.span);
     if let Some(ref mut it) = _i.expr {
         _visitor.visit_expr_mut(&mut **it)
     };
@@ -1731,7 +1767,7 @@
         _visitor.visit_ident_mut(it)
     };
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     _visitor.visit_type_mut(&mut _i.ty);
 }
@@ -1743,7 +1779,7 @@
     }
     _visitor.visit_member_mut(&mut _i.member);
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     _visitor.visit_pat_mut(&mut *_i.pat);
 }
@@ -1755,7 +1791,7 @@
     }
     _visitor.visit_member_mut(&mut _i.member);
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     _visitor.visit_expr_mut(&mut _i.expr);
 }
@@ -1773,7 +1809,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_fields_named_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut FieldsNamed) {
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.named) {
         let it = el.value_mut();
         _visitor.visit_field_mut(it)
@@ -1781,7 +1817,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_fields_unnamed_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut FieldsUnnamed) {
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.unnamed) {
         let it = el.value_mut();
         _visitor.visit_field_mut(it)
@@ -1819,15 +1855,15 @@
 }
 #[cfg(feature = "full")]
 pub fn visit_fn_decl_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut FnDecl) {
-    tokens_helper(_visitor, &mut (_i.fn_token).0);
+    tokens_helper(_visitor, &mut _i.fn_token.span);
     _visitor.visit_generics_mut(&mut _i.generics);
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
         let it = el.value_mut();
         _visitor.visit_fn_arg_mut(it)
     }
     if let Some(ref mut it) = _i.variadic {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     _visitor.visit_return_type_mut(&mut _i.output);
 }
@@ -1843,6 +1879,9 @@
         ForeignItem::Type(ref mut _binding_0) => {
             _visitor.visit_foreign_item_type_mut(_binding_0);
         }
+        ForeignItem::Macro(ref mut _binding_0) => {
+            _visitor.visit_foreign_item_macro_mut(_binding_0);
+        }
         ForeignItem::Verbatim(ref mut _binding_0) => {
             _visitor.visit_foreign_item_verbatim_mut(_binding_0);
         }
@@ -1856,7 +1895,20 @@
     _visitor.visit_visibility_mut(&mut _i.vis);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_fn_decl_mut(&mut *_i.decl);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_foreign_item_macro_mut<V: VisitMut + ?Sized>(
+    _visitor: &mut V,
+    _i: &mut ForeignItemMacro,
+) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    _visitor.visit_macro_mut(&mut _i.mac);
+    if let Some(ref mut it) = _i.semi_token {
+        tokens_helper(_visitor, &mut it.spans)
+    };
 }
 #[cfg(feature = "full")]
 pub fn visit_foreign_item_static_mut<V: VisitMut + ?Sized>(
@@ -1867,14 +1919,14 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.static_token).0);
+    tokens_helper(_visitor, &mut _i.static_token.span);
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut *_i.ty);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_foreign_item_type_mut<V: VisitMut + ?Sized>(
@@ -1885,9 +1937,9 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.type_token).0);
+    tokens_helper(_visitor, &mut _i.type_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_foreign_item_verbatim_mut<V: VisitMut + ?Sized>(
@@ -1948,14 +2000,14 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_generics_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Generics) {
     if let Some(ref mut it) = _i.lt_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.params) {
         let it = el.value_mut();
         _visitor.visit_generic_param_mut(it)
     }
     if let Some(ref mut it) = _i.gt_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     if let Some(ref mut it) = _i.where_clause {
         _visitor.visit_where_clause_mut(it)
@@ -1974,6 +2026,9 @@
         ImplItem::Type(ref mut _binding_0) => {
             _visitor.visit_impl_item_type_mut(_binding_0);
         }
+        ImplItem::Existential(ref mut _binding_0) => {
+            _visitor.visit_impl_item_existential_mut(_binding_0);
+        }
         ImplItem::Macro(ref mut _binding_0) => {
             _visitor.visit_impl_item_macro_mut(_binding_0);
         }
@@ -1989,15 +2044,36 @@
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
     if let Some(ref mut it) = _i.defaultness {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.const_token).0);
+    tokens_helper(_visitor, &mut _i.const_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut _i.ty);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_expr_mut(&mut _i.expr);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_impl_item_existential_mut<V: VisitMut + ?Sized>(
+    _visitor: &mut V,
+    _i: &mut ImplItemExistential,
+) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.existential_token.span);
+    tokens_helper(_visitor, &mut _i.type_token.span);
+    _visitor.visit_ident_mut(&mut _i.ident);
+    _visitor.visit_generics_mut(&mut _i.generics);
+    if let Some(ref mut it) = _i.colon_token {
+        tokens_helper(_visitor, &mut it.spans)
+    };
+    for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+        let it = el.value_mut();
+        _visitor.visit_type_param_bound_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_impl_item_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ImplItemMacro) {
@@ -2006,7 +2082,7 @@
     }
     _visitor.visit_macro_mut(&mut _i.mac);
     if let Some(ref mut it) = _i.semi_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2016,7 +2092,7 @@
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
     if let Some(ref mut it) = _i.defaultness {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_method_sig_mut(&mut _i.sig);
     _visitor.visit_block_mut(&mut _i.block);
@@ -2028,14 +2104,14 @@
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
     if let Some(ref mut it) = _i.defaultness {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.type_token).0);
+    tokens_helper(_visitor, &mut _i.type_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_type_mut(&mut _i.ty);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_impl_item_verbatim_mut<V: VisitMut + ?Sized>(
@@ -2076,6 +2152,9 @@
         Item::Type(ref mut _binding_0) => {
             _visitor.visit_item_type_mut(_binding_0);
         }
+        Item::Existential(ref mut _binding_0) => {
+            _visitor.visit_item_existential_mut(_binding_0);
+        }
         Item::Struct(ref mut _binding_0) => {
             _visitor.visit_item_struct_mut(_binding_0);
         }
@@ -2108,13 +2187,13 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.const_token).0);
+    tokens_helper(_visitor, &mut _i.const_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut *_i.ty);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_enum_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemEnum) {
@@ -2122,16 +2201,38 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.enum_token).0);
+    tokens_helper(_visitor, &mut _i.enum_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.variants) {
         let it = el.value_mut();
         _visitor.visit_variant_mut(it)
     }
 }
 #[cfg(feature = "full")]
+pub fn visit_item_existential_mut<V: VisitMut + ?Sized>(
+    _visitor: &mut V,
+    _i: &mut ItemExistential,
+) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    _visitor.visit_visibility_mut(&mut _i.vis);
+    tokens_helper(_visitor, &mut _i.existential_token.span);
+    tokens_helper(_visitor, &mut _i.type_token.span);
+    _visitor.visit_ident_mut(&mut _i.ident);
+    _visitor.visit_generics_mut(&mut _i.generics);
+    if let Some(ref mut it) = _i.colon_token {
+        tokens_helper(_visitor, &mut it.spans)
+    };
+    for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+        let it = el.value_mut();
+        _visitor.visit_type_param_bound_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_item_extern_crate_mut<V: VisitMut + ?Sized>(
     _visitor: &mut V,
     _i: &mut ItemExternCrate,
@@ -2140,14 +2241,14 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.extern_token).0);
-    tokens_helper(_visitor, &mut (_i.crate_token).0);
+    tokens_helper(_visitor, &mut _i.extern_token.span);
+    tokens_helper(_visitor, &mut _i.crate_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     if let Some(ref mut it) = _i.rename {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.span);
         _visitor.visit_ident_mut(&mut (it).1);
     };
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_fn_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemFn) {
@@ -2156,10 +2257,13 @@
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
     if let Some(ref mut it) = _i.constness {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.unsafety {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
+    };
+    if let Some(ref mut it) = _i.asyncness {
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.abi {
         _visitor.visit_abi_mut(it)
@@ -2174,7 +2278,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_abi_mut(&mut _i.abi);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for it in &mut _i.items {
         _visitor.visit_foreign_item_mut(it)
     }
@@ -2185,22 +2289,22 @@
         _visitor.visit_attribute_mut(it)
     }
     if let Some(ref mut it) = _i.defaultness {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.unsafety {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.impl_token).0);
+    tokens_helper(_visitor, &mut _i.impl_token.span);
     _visitor.visit_generics_mut(&mut _i.generics);
     if let Some(ref mut it) = _i.trait_ {
         if let Some(ref mut it) = (it).0 {
-            tokens_helper(_visitor, &mut (it).0)
+            tokens_helper(_visitor, &mut it.spans)
         };
         _visitor.visit_path_mut(&mut (it).1);
-        tokens_helper(_visitor, &mut ((it).2).0);
+        tokens_helper(_visitor, &mut (it).2.span);
     };
     _visitor.visit_type_mut(&mut *_i.self_ty);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for it in &mut _i.items {
         _visitor.visit_impl_item_mut(it)
     }
@@ -2215,7 +2319,7 @@
     };
     _visitor.visit_macro_mut(&mut _i.mac);
     if let Some(ref mut it) = _i.semi_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2224,11 +2328,11 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.macro_token).0);
+    tokens_helper(_visitor, &mut _i.macro_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     skip!(_i.args);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     skip!(_i.body);
 }
 #[cfg(feature = "full")]
@@ -2237,16 +2341,16 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.mod_token).0);
+    tokens_helper(_visitor, &mut _i.mod_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     if let Some(ref mut it) = _i.content {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.span);
         for it in &mut (it).1 {
             _visitor.visit_item_mut(it)
         }
     };
     if let Some(ref mut it) = _i.semi {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2255,16 +2359,16 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.static_token).0);
+    tokens_helper(_visitor, &mut _i.static_token.span);
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut *_i.ty);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_expr_mut(&mut *_i.expr);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_struct_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemStruct) {
@@ -2272,12 +2376,12 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.struct_token).0);
+    tokens_helper(_visitor, &mut _i.struct_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
     _visitor.visit_fields_mut(&mut _i.fields);
     if let Some(ref mut it) = _i.semi_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2287,22 +2391,22 @@
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
     if let Some(ref mut it) = _i.unsafety {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.auto_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.trait_token).0);
+    tokens_helper(_visitor, &mut _i.trait_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.supertraits) {
         let it = el.value_mut();
         _visitor.visit_type_param_bound_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for it in &mut _i.items {
         _visitor.visit_trait_item_mut(it)
     }
@@ -2313,12 +2417,12 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.type_token).0);
+    tokens_helper(_visitor, &mut _i.type_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_type_mut(&mut *_i.ty);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_union_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemUnion) {
@@ -2326,7 +2430,7 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.union_token).0);
+    tokens_helper(_visitor, &mut _i.union_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
     _visitor.visit_fields_named_mut(&mut _i.fields);
@@ -2337,12 +2441,12 @@
         _visitor.visit_attribute_mut(it)
     }
     _visitor.visit_visibility_mut(&mut _i.vis);
-    tokens_helper(_visitor, &mut (_i.use_token).0);
+    tokens_helper(_visitor, &mut _i.use_token.span);
     if let Some(ref mut it) = _i.leading_colon {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     _visitor.visit_use_tree_mut(&mut _i.tree);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_item_verbatim_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemVerbatim) {
@@ -2352,7 +2456,7 @@
 #[cfg(feature = "full")]
 pub fn visit_label_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Label) {
     _visitor.visit_lifetime_mut(&mut _i.name);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_lifetime_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Lifetime) {
@@ -2366,7 +2470,7 @@
     }
     _visitor.visit_lifetime_mut(&mut _i.lifetime);
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
@@ -2441,25 +2545,25 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.let_token).0);
+    tokens_helper(_visitor, &mut _i.let_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.pats) {
         let it = el.value_mut();
         _visitor.visit_pat_mut(it)
     }
     if let Some(ref mut it) = _i.ty {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.spans);
         _visitor.visit_type_mut(&mut *(it).1);
     };
     if let Some(ref mut it) = _i.init {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.spans);
         _visitor.visit_expr_mut(&mut *(it).1);
     };
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Macro) {
     _visitor.visit_path_mut(&mut _i.path);
-    tokens_helper(_visitor, &mut (_i.bang_token).0);
+    tokens_helper(_visitor, &mut _i.bang_token.spans);
     _visitor.visit_macro_delimiter_mut(&mut _i.delimiter);
     skip!(_i.tts);
 }
@@ -2467,13 +2571,13 @@
 pub fn visit_macro_delimiter_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MacroDelimiter) {
     match *_i {
         MacroDelimiter::Paren(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.span);
         }
         MacroDelimiter::Brace(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.span);
         }
         MacroDelimiter::Bracket(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.span);
         }
     }
 }
@@ -2505,7 +2609,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_meta_list_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MetaList) {
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.nested) {
         let it = el.value_mut();
         _visitor.visit_nested_meta_mut(it)
@@ -2514,16 +2618,19 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_meta_name_value_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MetaNameValue) {
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_lit_mut(&mut _i.lit);
 }
 #[cfg(feature = "full")]
 pub fn visit_method_sig_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MethodSig) {
     if let Some(ref mut it) = _i.constness {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.unsafety {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
+    };
+    if let Some(ref mut it) = _i.asyncness {
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.abi {
         _visitor.visit_abi_mut(it)
@@ -2537,13 +2644,13 @@
     _visitor: &mut V,
     _i: &mut MethodTurbofish,
 ) {
-    tokens_helper(_visitor, &mut (_i.colon2_token).0);
-    tokens_helper(_visitor, &mut (_i.lt_token).0);
+    tokens_helper(_visitor, &mut _i.colon2_token.spans);
+    tokens_helper(_visitor, &mut _i.lt_token.spans);
     for mut el in Punctuated::pairs_mut(&mut _i.args) {
         let it = el.value_mut();
         _visitor.visit_generic_method_argument_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.gt_token).0);
+    tokens_helper(_visitor, &mut _i.gt_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_nested_meta_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut NestedMeta) {
@@ -2561,7 +2668,7 @@
     _visitor: &mut V,
     _i: &mut ParenthesizedGenericArguments,
 ) {
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
         let it = el.value_mut();
         _visitor.visit_type_mut(it)
@@ -2616,21 +2723,21 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_box_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatBox) {
-    tokens_helper(_visitor, &mut (_i.box_token).0);
+    tokens_helper(_visitor, &mut _i.box_token.span);
     _visitor.visit_pat_mut(&mut *_i.pat);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_ident_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatIdent) {
     if let Some(ref mut it) = _i.by_ref {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_ident_mut(&mut _i.ident);
     if let Some(ref mut it) = _i.subpat {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.spans);
         _visitor.visit_pat_mut(&mut *(it).1);
     };
 }
@@ -2662,16 +2769,16 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_ref_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatRef) {
-    tokens_helper(_visitor, &mut (_i.and_token).0);
+    tokens_helper(_visitor, &mut _i.and_token.spans);
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_pat_mut(&mut *_i.pat);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_slice_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatSlice) {
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.front) {
         let it = el.value_mut();
         _visitor.visit_pat_mut(it)
@@ -2680,10 +2787,10 @@
         _visitor.visit_pat_mut(&mut **it)
     };
     if let Some(ref mut it) = _i.dot2_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     if let Some(ref mut it) = _i.comma_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.back) {
         let it = el.value_mut();
@@ -2694,28 +2801,28 @@
 #[cfg(feature = "full")]
 pub fn visit_pat_struct_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatStruct) {
     _visitor.visit_path_mut(&mut _i.path);
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.fields) {
         let it = el.value_mut();
         _visitor.visit_field_pat_mut(it)
     }
     if let Some(ref mut it) = _i.dot2_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_tuple_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatTuple) {
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.front) {
         let it = el.value_mut();
         _visitor.visit_pat_mut(it)
     }
     if let Some(ref mut it) = _i.dot2_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     if let Some(ref mut it) = _i.comma_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.back) {
         let it = el.value_mut();
@@ -2736,12 +2843,12 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_pat_wild_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatWild) {
-    tokens_helper(_visitor, &mut (_i.underscore_token).0);
+    tokens_helper(_visitor, &mut _i.underscore_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_path_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Path) {
     if let Some(ref mut it) = _i.leading_colon {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.segments) {
         let it = el.value_mut();
@@ -2768,7 +2875,7 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_predicate_eq_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PredicateEq) {
     _visitor.visit_type_mut(&mut _i.lhs_ty);
-    tokens_helper(_visitor, &mut (_i.eq_token).0);
+    tokens_helper(_visitor, &mut _i.eq_token.spans);
     _visitor.visit_type_mut(&mut _i.rhs_ty);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -2777,9 +2884,7 @@
     _i: &mut PredicateLifetime,
 ) {
     _visitor.visit_lifetime_mut(&mut _i.lifetime);
-    if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
-    };
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
         _visitor.visit_lifetime_mut(it)
@@ -2791,7 +2896,7 @@
         _visitor.visit_bound_lifetimes_mut(it)
     };
     _visitor.visit_type_mut(&mut _i.bounded_ty);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
         _visitor.visit_type_param_bound_mut(it)
@@ -2799,23 +2904,23 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_qself_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut QSelf) {
-    tokens_helper(_visitor, &mut (_i.lt_token).0);
+    tokens_helper(_visitor, &mut _i.lt_token.spans);
     _visitor.visit_type_mut(&mut *_i.ty);
     skip!(_i.position);
     if let Some(ref mut it) = _i.as_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
-    tokens_helper(_visitor, &mut (_i.gt_token).0);
+    tokens_helper(_visitor, &mut _i.gt_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 #[cfg(feature = "full")]
 pub fn visit_range_limits_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut RangeLimits) {
     match *_i {
         RangeLimits::HalfOpen(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         RangeLimits::Closed(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
     }
 }
@@ -2824,7 +2929,7 @@
     match *_i {
         ReturnType::Default => {}
         ReturnType::Type(ref mut _binding_0, ref mut _binding_1) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
             _visitor.visit_type_mut(&mut **_binding_1);
         }
     }
@@ -2845,14 +2950,14 @@
         }
         Stmt::Semi(ref mut _binding_0, ref mut _binding_1) => {
             _visitor.visit_expr_mut(_binding_0);
-            tokens_helper(_visitor, &mut (_binding_1).0);
+            tokens_helper(_visitor, &mut _binding_1.spans);
         }
     }
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_trait_bound_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TraitBound) {
     if let Some(ref mut it) = _i.paren_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_trait_bound_modifier_mut(&mut _i.modifier);
     if let Some(ref mut it) = _i.lifetimes {
@@ -2868,7 +2973,7 @@
     match *_i {
         TraitBoundModifier::None => {}
         TraitBoundModifier::Maybe(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
     }
 }
@@ -2897,15 +3002,15 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.const_token).0);
+    tokens_helper(_visitor, &mut _i.const_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon_token).0);
+    tokens_helper(_visitor, &mut _i.colon_token.spans);
     _visitor.visit_type_mut(&mut _i.ty);
     if let Some(ref mut it) = _i.default {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.spans);
         _visitor.visit_expr_mut(&mut (it).1);
     };
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_trait_item_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemMacro) {
@@ -2914,7 +3019,7 @@
     }
     _visitor.visit_macro_mut(&mut _i.mac);
     if let Some(ref mut it) = _i.semi_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2930,7 +3035,7 @@
         _visitor.visit_block_mut(it)
     };
     if let Some(ref mut it) = _i.semi_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
 }
 #[cfg(feature = "full")]
@@ -2938,21 +3043,21 @@
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
     }
-    tokens_helper(_visitor, &mut (_i.type_token).0);
+    tokens_helper(_visitor, &mut _i.type_token.span);
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_generics_mut(&mut _i.generics);
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
         _visitor.visit_type_param_bound_mut(it)
     }
     if let Some(ref mut it) = _i.default {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.spans);
         _visitor.visit_type_mut(&mut (it).1);
     };
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_trait_item_verbatim_mut<V: VisitMut + ?Sized>(
@@ -3013,41 +3118,41 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_array_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeArray) {
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     _visitor.visit_type_mut(&mut *_i.elem);
-    tokens_helper(_visitor, &mut (_i.semi_token).0);
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
     _visitor.visit_expr_mut(&mut _i.len);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_bare_fn_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeBareFn) {
+    if let Some(ref mut it) = _i.lifetimes {
+        _visitor.visit_bound_lifetimes_mut(it)
+    };
     if let Some(ref mut it) = _i.unsafety {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.abi {
         _visitor.visit_abi_mut(it)
     };
-    tokens_helper(_visitor, &mut (_i.fn_token).0);
-    if let Some(ref mut it) = _i.lifetimes {
-        _visitor.visit_bound_lifetimes_mut(it)
-    };
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.fn_token.span);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
         let it = el.value_mut();
         _visitor.visit_bare_fn_arg_mut(it)
     }
     if let Some(ref mut it) = _i.variadic {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     _visitor.visit_return_type_mut(&mut _i.output);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_group_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeGroup) {
-    tokens_helper(_visitor, &mut (_i.group_token).0);
+    tokens_helper(_visitor, &mut _i.group_token.span);
     _visitor.visit_type_mut(&mut *_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_impl_trait_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeImplTrait) {
-    tokens_helper(_visitor, &mut (_i.impl_token).0);
+    tokens_helper(_visitor, &mut _i.impl_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
         _visitor.visit_type_param_bound_mut(it)
@@ -3055,7 +3160,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_infer_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeInfer) {
-    tokens_helper(_visitor, &mut (_i.underscore_token).0);
+    tokens_helper(_visitor, &mut _i.underscore_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeMacro) {
@@ -3063,7 +3168,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_never_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeNever) {
-    tokens_helper(_visitor, &mut (_i.bang_token).0);
+    tokens_helper(_visitor, &mut _i.bang_token.spans);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_param_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeParam) {
@@ -3072,14 +3177,14 @@
     }
     _visitor.visit_ident_mut(&mut _i.ident);
     if let Some(ref mut it) = _i.colon_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
         _visitor.visit_type_param_bound_mut(it)
     }
     if let Some(ref mut it) = _i.eq_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.spans)
     };
     if let Some(ref mut it) = _i.default {
         _visitor.visit_type_mut(it)
@@ -3098,7 +3203,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_paren_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeParen) {
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     _visitor.visit_type_mut(&mut *_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -3110,29 +3215,29 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_ptr_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypePtr) {
-    tokens_helper(_visitor, &mut (_i.star_token).0);
+    tokens_helper(_visitor, &mut _i.star_token.spans);
     if let Some(ref mut it) = _i.const_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_type_mut(&mut *_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_reference_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeReference) {
-    tokens_helper(_visitor, &mut (_i.and_token).0);
+    tokens_helper(_visitor, &mut _i.and_token.spans);
     if let Some(ref mut it) = _i.lifetime {
         _visitor.visit_lifetime_mut(it)
     };
     if let Some(ref mut it) = _i.mutability {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_type_mut(&mut *_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_slice_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeSlice) {
-    tokens_helper(_visitor, &mut (_i.bracket_token).0);
+    tokens_helper(_visitor, &mut _i.bracket_token.span);
     _visitor.visit_type_mut(&mut *_i.elem);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
@@ -3141,7 +3246,7 @@
     _i: &mut TypeTraitObject,
 ) {
     if let Some(ref mut it) = _i.dyn_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
         let it = el.value_mut();
@@ -3150,7 +3255,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_type_tuple_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeTuple) {
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.elems) {
         let it = el.value_mut();
         _visitor.visit_type_mut(it)
@@ -3164,23 +3269,23 @@
 pub fn visit_un_op_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UnOp) {
     match *_i {
         UnOp::Deref(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         UnOp::Not(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
         UnOp::Neg(ref mut _binding_0) => {
-            tokens_helper(_visitor, &mut (_binding_0).0);
+            tokens_helper(_visitor, &mut _binding_0.spans);
         }
     }
 }
 #[cfg(feature = "full")]
 pub fn visit_use_glob_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseGlob) {
-    tokens_helper(_visitor, &mut (_i.star_token).0);
+    tokens_helper(_visitor, &mut _i.star_token.spans);
 }
 #[cfg(feature = "full")]
 pub fn visit_use_group_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseGroup) {
-    tokens_helper(_visitor, &mut (_i.brace_token).0);
+    tokens_helper(_visitor, &mut _i.brace_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.items) {
         let it = el.value_mut();
         _visitor.visit_use_tree_mut(it)
@@ -3193,13 +3298,13 @@
 #[cfg(feature = "full")]
 pub fn visit_use_path_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UsePath) {
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.colon2_token).0);
+    tokens_helper(_visitor, &mut _i.colon2_token.spans);
     _visitor.visit_use_tree_mut(&mut *_i.tree);
 }
 #[cfg(feature = "full")]
 pub fn visit_use_rename_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseRename) {
     _visitor.visit_ident_mut(&mut _i.ident);
-    tokens_helper(_visitor, &mut (_i.as_token).0);
+    tokens_helper(_visitor, &mut _i.as_token.span);
     _visitor.visit_ident_mut(&mut _i.rename);
 }
 #[cfg(feature = "full")]
@@ -3230,24 +3335,24 @@
     _visitor.visit_ident_mut(&mut _i.ident);
     _visitor.visit_fields_mut(&mut _i.fields);
     if let Some(ref mut it) = _i.discriminant {
-        tokens_helper(_visitor, &mut ((it).0).0);
+        tokens_helper(_visitor, &mut (it).0.spans);
         _visitor.visit_expr_mut(&mut (it).1);
     };
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_vis_crate_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut VisCrate) {
-    tokens_helper(_visitor, &mut (_i.crate_token).0);
+    tokens_helper(_visitor, &mut _i.crate_token.span);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_vis_public_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut VisPublic) {
-    tokens_helper(_visitor, &mut (_i.pub_token).0);
+    tokens_helper(_visitor, &mut _i.pub_token.span);
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_vis_restricted_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut VisRestricted) {
-    tokens_helper(_visitor, &mut (_i.pub_token).0);
-    tokens_helper(_visitor, &mut (_i.paren_token).0);
+    tokens_helper(_visitor, &mut _i.pub_token.span);
+    tokens_helper(_visitor, &mut _i.paren_token.span);
     if let Some(ref mut it) = _i.in_token {
-        tokens_helper(_visitor, &mut (it).0)
+        tokens_helper(_visitor, &mut it.span)
     };
     _visitor.visit_path_mut(&mut *_i.path);
 }
@@ -3268,7 +3373,7 @@
 }
 #[cfg(any(feature = "full", feature = "derive"))]
 pub fn visit_where_clause_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut WhereClause) {
-    tokens_helper(_visitor, &mut (_i.where_token).0);
+    tokens_helper(_visitor, &mut _i.where_token.span);
     for mut el in Punctuated::pairs_mut(&mut _i.predicates) {
         let it = el.value_mut();
         _visitor.visit_where_predicate_mut(it)
diff --git a/src/generics.rs b/src/generics.rs
index d1f4fa2..7d96e78 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -166,7 +166,6 @@
     type Item = &'a TypeParam;
 
     fn next(&mut self) -> Option<Self::Item> {
-        // FIXME: Remove this when ? on Option is stable
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
@@ -185,7 +184,6 @@
     type Item = &'a mut TypeParam;
 
     fn next(&mut self) -> Option<Self::Item> {
-        // FIXME: Remove this when ? on Option is stable
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
@@ -204,7 +202,6 @@
     type Item = &'a LifetimeDef;
 
     fn next(&mut self) -> Option<Self::Item> {
-        // FIXME: Remove this when ? on Option is stable
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
@@ -223,7 +220,6 @@
     type Item = &'a mut LifetimeDef;
 
     fn next(&mut self) -> Option<Self::Item> {
-        // FIXME: Remove this when ? on Option is stable
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
@@ -242,7 +238,6 @@
     type Item = &'a ConstParam;
 
     fn next(&mut self) -> Option<Self::Item> {
-        // FIXME: Remove this when ? on Option is stable
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
@@ -261,7 +256,6 @@
     type Item = &'a mut ConstParam;
 
     fn next(&mut self) -> Option<Self::Item> {
-        // FIXME: Remove this when ? on Option is stable
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
@@ -468,7 +462,7 @@
         /// `"full"` feature.*
         pub Lifetime(PredicateLifetime {
             pub lifetime: Lifetime,
-            pub colon_token: Option<Token![:]>,
+            pub colon_token: Token![:],
             pub bounds: Punctuated<Lifetime, Token![+]>,
         }),
 
@@ -488,263 +482,371 @@
 pub mod parsing {
     use super::*;
 
-    use punctuated::Pair;
+    use parse::{Parse, ParseStream, Result};
     use synom::Synom;
 
-    impl Synom for Generics {
-        named!(parse -> Self, map!(
-            alt!(
-                do_parse!(
-                    lt: punct!(<) >>
-                    lifetimes: call!(Punctuated::<LifetimeDef, Token![,]>::parse_terminated) >>
-                    ty_params: cond!(
-                        lifetimes.empty_or_trailing(),
-                        Punctuated::<TypeParam, Token![,]>::parse_terminated
-                    ) >>
-                    gt: punct!(>) >>
-                    (lifetimes, ty_params, Some(lt), Some(gt))
-                )
-                |
-                epsilon!() => { |_| (Punctuated::new(), None, None, None) }
-            ),
-            |(lifetimes, ty_params, lt, gt)| Generics {
-                lt_token: lt,
-                params: lifetimes.into_pairs()
-                    .map(Pair::into_tuple)
-                    .map(|(life, comma)| Pair::new(GenericParam::Lifetime(life), comma))
-                    .chain(ty_params.unwrap_or_default()
-                        .into_pairs()
-                        .map(Pair::into_tuple)
-                        .map(|(ty, comma)| Pair::new(GenericParam::Type(ty), comma)))
-                    .collect(),
-                gt_token: gt,
-                where_clause: None,
+    impl Parse for Generics {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let mut params = Punctuated::new();
+
+            if !input.peek(Token![<]) {
+                return Ok(Generics {
+                    lt_token: None,
+                    params: params,
+                    gt_token: None,
+                    where_clause: None,
+                });
             }
-        ));
 
-        fn description() -> Option<&'static str> {
-            Some("generic parameters in declaration")
-        }
-    }
+            let lt_token: Token![<] = input.parse()?;
 
-    impl Synom for GenericParam {
-        named!(parse -> Self, alt!(
-            syn!(TypeParam) => { GenericParam::Type }
-            |
-            syn!(LifetimeDef) => { GenericParam::Lifetime }
-            |
-            syn!(ConstParam) => { GenericParam::Const }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("generic parameter")
-        }
-    }
-
-    impl Synom for LifetimeDef {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            life: syn!(Lifetime) >>
-            colon: option!(punct!(:)) >>
-            bounds: cond!(
-                colon.is_some(),
-                Punctuated::parse_separated_nonempty
-            ) >>
-            (LifetimeDef {
-                attrs: attrs,
-                lifetime: life,
-                bounds: bounds.unwrap_or_default(),
-                colon_token: colon,
-            })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("lifetime definition")
-        }
-    }
-
-    impl Synom for BoundLifetimes {
-        named!(parse -> Self, do_parse!(
-            for_: keyword!(for) >>
-            lt: punct!(<) >>
-            lifetimes: call!(Punctuated::parse_terminated) >>
-            gt: punct!(>) >>
-            (BoundLifetimes {
-                for_token: for_,
-                lt_token: lt,
-                gt_token: gt,
-                lifetimes: lifetimes,
-            })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("bound lifetimes")
-        }
-    }
-
-    impl Synom for TypeParam {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            id: syn!(Ident) >>
-            colon: option!(punct!(:)) >>
-            bounds: cond!(
-                colon.is_some(),
-                Punctuated::parse_separated_nonempty
-            ) >>
-            default: option!(do_parse!(
-                eq: punct!(=) >>
-                ty: syn!(Type) >>
-                (eq, ty)
-            )) >>
-            (TypeParam {
-                attrs: attrs,
-                ident: id,
-                bounds: bounds.unwrap_or_default(),
-                colon_token: colon,
-                eq_token: default.as_ref().map(|d| Token![=]((d.0).0)),
-                default: default.map(|d| d.1),
-            })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("type parameter")
-        }
-    }
-
-    impl Synom for TypeParamBound {
-        named!(parse -> Self, alt!(
-            syn!(Lifetime) => { TypeParamBound::Lifetime }
-            |
-            syn!(TraitBound) => { TypeParamBound::Trait }
-            |
-            parens!(syn!(TraitBound)) => {|(parens, mut bound)| {
-                bound.paren_token = Some(parens);
-                TypeParamBound::Trait(bound)
-            }}
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("type parameter bound")
-        }
-    }
-
-    impl Synom for TraitBound {
-        named!(parse -> Self, do_parse!(
-            modifier: syn!(TraitBoundModifier) >>
-            lifetimes: option!(syn!(BoundLifetimes)) >>
-            mut path: syn!(Path) >>
-            parenthesized: option!(cond_reduce!(
-                path.segments.last().unwrap().value().arguments.is_empty(),
-                syn!(ParenthesizedGenericArguments)
-            )) >>
-            ({
-                if let Some(parenthesized) = parenthesized {
-                    let parenthesized = PathArguments::Parenthesized(parenthesized);
-                    path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
+            let mut has_type_param = false;
+            loop {
+                if input.peek(Token![>]) {
+                    break;
                 }
-                TraitBound {
-                    paren_token: None,
-                    modifier: modifier,
-                    lifetimes: lifetimes,
-                    path: path,
+
+                let attrs = input.call(Attribute::parse_outer)?;
+                let lookahead = input.lookahead1();
+                if !has_type_param && lookahead.peek(Lifetime) {
+                    params.push_value(GenericParam::Lifetime(LifetimeDef {
+                        attrs: attrs,
+                        ..input.parse()?
+                    }));
+                } else if lookahead.peek(Ident) {
+                    has_type_param = true;
+                    params.push_value(GenericParam::Type(TypeParam {
+                        attrs: attrs,
+                        ..input.parse()?
+                    }));
+                } else {
+                    return Err(lookahead.error());
                 }
+
+                if input.peek(Token![>]) {
+                    break;
+                }
+                let punct = input.parse()?;
+                params.push_punct(punct);
+            }
+
+            let gt_token: Token![>] = input.parse()?;
+
+            Ok(Generics {
+                lt_token: Some(lt_token),
+                params: params,
+                gt_token: Some(gt_token),
+                where_clause: None,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("trait bound")
         }
     }
 
-    impl Synom for TraitBoundModifier {
-        named!(parse -> Self, alt!(
-            punct!(?) => { TraitBoundModifier::Maybe }
-            |
-            epsilon!() => { |_| TraitBoundModifier::None }
-        ));
+    impl Parse for GenericParam {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
 
-        fn description() -> Option<&'static str> {
-            Some("trait bound modifier")
-        }
-    }
-
-    impl Synom for ConstParam {
-        named!(parse -> Self, do_parse!(
-            attrs: many0!(Attribute::parse_outer) >>
-            const_: keyword!(const) >>
-            ident: syn!(Ident) >>
-            colon: punct!(:) >>
-            ty: syn!(Type) >>
-            eq_def: option!(tuple!(punct!(=), syn!(Expr))) >>
-            ({
-                let (eq_token, default) = match eq_def {
-                    Some((eq_token, default)) => (Some(eq_token), Some(default)),
-                    None => (None, None),
-                };
-                ConstParam {
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Ident) {
+                Ok(GenericParam::Type(TypeParam {
                     attrs: attrs,
-                    const_token: const_,
-                    ident: ident,
-                    colon_token: colon,
-                    ty: ty,
-                    eq_token: eq_token,
-                    default: default,
-                }
-            })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("generic `const` parameter")
+                    ..input.parse()?
+                }))
+            } else if lookahead.peek(Lifetime) {
+                Ok(GenericParam::Lifetime(LifetimeDef {
+                    attrs: attrs,
+                    ..input.parse()?
+                }))
+            } else if lookahead.peek(Token![const]) {
+                Ok(GenericParam::Const(ConstParam {
+                    attrs: attrs,
+                    ..input.parse()?
+                }))
+            } else {
+                Err(lookahead.error())
+            }
         }
     }
 
-    impl Synom for WhereClause {
-        named!(parse -> Self, do_parse!(
-            where_: keyword!(where) >>
-            predicates: call!(Punctuated::parse_terminated) >>
-            (WhereClause {
-                predicates: predicates,
-                where_token: where_,
+    impl Parse for LifetimeDef {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let has_colon;
+            Ok(LifetimeDef {
+                attrs: input.call(Attribute::parse_outer)?,
+                lifetime: input.parse()?,
+                colon_token: {
+                    if input.peek(Token![:]) {
+                        has_colon = true;
+                        Some(input.parse()?)
+                    } else {
+                        has_colon = false;
+                        None
+                    }
+                },
+                bounds: {
+                    let mut bounds = Punctuated::new();
+                    if has_colon {
+                        loop {
+                            if input.peek(Token![,]) || input.peek(Token![>]) {
+                                break;
+                            }
+                            let value = input.parse()?;
+                            bounds.push_value(value);
+                            if !input.peek(Token![+]) {
+                                break;
+                            }
+                            let punct = input.parse()?;
+                            bounds.push_punct(punct);
+                        }
+                    }
+                    bounds
+                },
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("where clause")
         }
     }
 
-    impl Synom for WherePredicate {
-        named!(parse -> Self, alt!(
-            do_parse!(
-                ident: syn!(Lifetime) >>
-                colon: option!(punct!(:)) >>
-                bounds: cond!(
-                    colon.is_some(),
-                    Punctuated::parse_separated
-                ) >>
-                (WherePredicate::Lifetime(PredicateLifetime {
-                    lifetime: ident,
-                    bounds: bounds.unwrap_or_default(),
-                    colon_token: colon,
-                }))
-            )
-            |
-            do_parse!(
-                lifetimes: option!(syn!(BoundLifetimes)) >>
-                bounded_ty: syn!(Type) >>
-                colon: punct!(:) >>
-                bounds: call!(Punctuated::parse_separated_nonempty) >>
-                (WherePredicate::Type(PredicateType {
-                    lifetimes: lifetimes,
-                    bounded_ty: bounded_ty,
-                    bounds: bounds,
-                    colon_token: colon,
-                }))
-            )
-        ));
+    impl Parse for BoundLifetimes {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(BoundLifetimes {
+                for_token: input.parse()?,
+                lt_token: input.parse()?,
+                lifetimes: input.parse_synom(Punctuated::parse_terminated)?,
+                gt_token: input.parse()?,
+            })
+        }
+    }
 
-        fn description() -> Option<&'static str> {
-            Some("predicate in where clause")
+    impl Parse for Option<BoundLifetimes> {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![for]) {
+                input.parse().map(Some)
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    impl Parse for TypeParam {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let has_colon;
+            let has_default;
+            Ok(TypeParam {
+                attrs: input.call(Attribute::parse_outer)?,
+                ident: input.parse()?,
+                colon_token: {
+                    if input.peek(Token![:]) {
+                        has_colon = true;
+                        Some(input.parse()?)
+                    } else {
+                        has_colon = false;
+                        None
+                    }
+                },
+                bounds: {
+                    let mut bounds = Punctuated::new();
+                    if has_colon {
+                        loop {
+                            if input.peek(Token![,]) || input.peek(Token![>]) {
+                                break;
+                            }
+                            let value = input.parse()?;
+                            bounds.push_value(value);
+                            if !input.peek(Token![+]) {
+                                break;
+                            }
+                            let punct = input.parse()?;
+                            bounds.push_punct(punct);
+                        }
+                    }
+                    bounds
+                },
+                eq_token: {
+                    if input.peek(Token![=]) {
+                        has_default = true;
+                        Some(input.parse()?)
+                    } else {
+                        has_default = false;
+                        None
+                    }
+                },
+                default: {
+                    if has_default {
+                        Some(input.parse()?)
+                    } else {
+                        None
+                    }
+                },
+            })
+        }
+    }
+
+    impl Parse for TypeParamBound {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Lifetime) {
+                return input.parse().map(TypeParamBound::Lifetime);
+            }
+
+            if input.peek(token::Paren) {
+                let content;
+                let paren_token = parenthesized!(content in input);
+                let mut bound: TraitBound = content.parse()?;
+                bound.paren_token = Some(paren_token);
+                return Ok(TypeParamBound::Trait(bound));
+            }
+
+            input.parse().map(TypeParamBound::Trait)
+        }
+    }
+
+    impl Parse for TraitBound {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let modifier: TraitBoundModifier = input.parse()?;
+            let lifetimes: Option<BoundLifetimes> = input.parse()?;
+
+            let mut path: Path = input.parse()?;
+            if path.segments.last().unwrap().value().arguments.is_empty()
+                && input.peek(token::Paren)
+            {
+                let parenthesized = PathArguments::Parenthesized(input.parse()?);
+                path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
+            }
+
+            Ok(TraitBound {
+                paren_token: None,
+                modifier: modifier,
+                lifetimes: lifetimes,
+                path: path,
+            })
+        }
+    }
+
+    impl Parse for TraitBoundModifier {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![?]) {
+                input.parse().map(TraitBoundModifier::Maybe)
+            } else {
+                Ok(TraitBoundModifier::None)
+            }
+        }
+    }
+
+    impl Parse for ConstParam {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let mut default = None;
+            Ok(ConstParam {
+                attrs: input.call(Attribute::parse_outer)?,
+                const_token: input.parse()?,
+                ident: input.parse()?,
+                colon_token: input.parse()?,
+                ty: input.parse()?,
+                eq_token: {
+                    if input.peek(Token![=]) {
+                        let eq_token = input.parse()?;
+                        default = Some(input.parse_synom(Expr::parse)?);
+                        Some(eq_token)
+                    } else {
+                        None
+                    }
+                },
+                default: default,
+            })
+        }
+    }
+
+    impl Parse for WhereClause {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(WhereClause {
+                where_token: input.parse()?,
+                predicates: {
+                    let mut predicates = Punctuated::new();
+                    loop {
+                        if input.peek(token::Brace)
+                            || input.peek(Token![,])
+                            || input.peek(Token![;])
+                            || input.peek(Token![:]) && !input.peek(Token![::])
+                            || input.peek(Token![=])
+                        {
+                            break;
+                        }
+                        let value = input.parse()?;
+                        predicates.push_value(value);
+                        if !input.peek(Token![,]) {
+                            break;
+                        }
+                        let punct = input.parse()?;
+                        predicates.push_punct(punct);
+                    }
+                    predicates
+                },
+            })
+        }
+    }
+
+    impl Parse for Option<WhereClause> {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![where]) {
+                input.parse().map(Some)
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    impl Parse for WherePredicate {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Lifetime) && input.peek3(Token![:]) {
+                Ok(WherePredicate::Lifetime(PredicateLifetime {
+                    lifetime: input.parse()?,
+                    colon_token: input.parse()?,
+                    bounds: {
+                        let mut bounds = Punctuated::new();
+                        loop {
+                            if input.peek(token::Brace)
+                                || input.peek(Token![,])
+                                || input.peek(Token![;])
+                                || input.peek(Token![:])
+                                || input.peek(Token![=])
+                            {
+                                break;
+                            }
+                            let value = input.parse()?;
+                            bounds.push_value(value);
+                            if !input.peek(Token![+]) {
+                                break;
+                            }
+                            let punct = input.parse()?;
+                            bounds.push_punct(punct);
+                        }
+                        bounds
+                    },
+                }))
+            } else {
+                Ok(WherePredicate::Type(PredicateType {
+                    lifetimes: input.parse()?,
+                    bounded_ty: input.parse()?,
+                    colon_token: input.parse()?,
+                    bounds: {
+                        let mut bounds = Punctuated::new();
+                        loop {
+                            if input.peek(token::Brace)
+                                || input.peek(Token![,])
+                                || input.peek(Token![;])
+                                || input.peek(Token![:]) && !input.peek(Token![::])
+                                || input.peek(Token![=])
+                            {
+                                break;
+                            }
+                            let value = input.parse()?;
+                            bounds.push_value(value);
+                            if !input.peek(Token![+]) {
+                                break;
+                            }
+                            let punct = input.parse()?;
+                            bounds.push_punct(punct);
+                        }
+                        bounds
+                    },
+                }))
+            }
         }
     }
 }
@@ -998,10 +1100,8 @@
     impl ToTokens for PredicateLifetime {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.lifetime.to_tokens(tokens);
-            if !self.bounds.is_empty() {
-                TokensOrDefault(&self.colon_token).to_tokens(tokens);
-                self.bounds.to_tokens(tokens);
-            }
+            self.colon_token.to_tokens(tokens);
+            self.bounds.to_tokens(tokens);
         }
     }
 
diff --git a/src/group.rs b/src/group.rs
new file mode 100644
index 0000000..1f46f2b
--- /dev/null
+++ b/src/group.rs
@@ -0,0 +1,185 @@
+use proc_macro2::{Delimiter, Span};
+
+use error::Result;
+use parse::ParseBuffer;
+use token;
+
+pub struct Parens<'a> {
+    pub token: token::Paren,
+    pub content: ParseBuffer<'a>,
+}
+
+pub struct Braces<'a> {
+    pub token: token::Brace,
+    pub content: ParseBuffer<'a>,
+}
+
+pub struct Brackets<'a> {
+    pub token: token::Bracket,
+    pub content: ParseBuffer<'a>,
+}
+
+pub struct Group<'a> {
+    pub token: token::Group,
+    pub content: ParseBuffer<'a>,
+}
+
+impl<'a> ParseBuffer<'a> {
+    fn parse_delimited(&self, delimiter: Delimiter) -> Result<(Span, ParseBuffer<'a>)> {
+        self.step_cursor(|cursor| {
+            if let Some((content, span, rest)) = cursor.group(delimiter) {
+                let content =
+                    ParseBuffer::new(span, cursor.advance(content), self.get_unexpected());
+                Ok(((span, content), rest))
+            } else {
+                let message = match delimiter {
+                    Delimiter::Parenthesis => "expected parentheses",
+                    Delimiter::Brace => "expected curly braces",
+                    Delimiter::Bracket => "expected square brackets",
+                    Delimiter::None => "expected invisible group",
+                };
+                Err(cursor.error(message))
+            }
+        })
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_parens(&self) -> Result<Parens<'a>> {
+        self.parse_delimited(Delimiter::Parenthesis)
+            .map(|(span, content)| Parens {
+                token: token::Paren(span),
+                content: content,
+            })
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_braces(&self) -> Result<Braces<'a>> {
+        self.parse_delimited(Delimiter::Brace)
+            .map(|(span, content)| Braces {
+                token: token::Brace(span),
+                content: content,
+            })
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_brackets(&self) -> Result<Brackets<'a>> {
+        self.parse_delimited(Delimiter::Bracket)
+            .map(|(span, content)| Brackets {
+                token: token::Bracket(span),
+                content: content,
+            })
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_group(&self) -> Result<Group<'a>> {
+        self.parse_delimited(Delimiter::None)
+            .map(|(span, content)| Group {
+                token: token::Group(span),
+                content: content,
+            })
+    }
+}
+
+/// Parse a set of parentheses and expose their content to subsequent parsers.
+#[macro_export]
+macro_rules! parenthesized {
+    ($content:ident in $cursor:expr) => {
+        match $crate::parse::ParseBuffer::parse_parens(&$cursor) {
+            $crate::export::Ok(parens) => {
+                $content = parens.content;
+                parens.token
+            }
+            $crate::export::Err(error) => {
+                return $crate::export::Err(error);
+            }
+        }
+    };
+}
+
+/// Parse a set of curly braces and expose their content to subsequent parsers.
+///
+/// ```rust
+/// # extern crate syn;
+/// #
+/// use syn::{braced, token, Ident, Token};
+/// use syn::parse::{Parse, ParseStream, Result};
+/// use syn::punctuated::Punctuated;
+/// #
+/// # type Field = Ident;
+///
+/// // Parse a simplified struct syntax like:
+/// //
+/// //     struct S {
+/// //         a: A,
+/// //         b: B,
+/// //     }
+/// struct Struct {
+///     pub struct_token: Token![struct],
+///     pub ident: Ident,
+///     pub brace_token: token::Brace,
+///     pub fields: Punctuated<Field, Token![,]>,
+/// }
+///
+/// impl Parse for Struct {
+///     fn parse(input: ParseStream) -> Result<Self> {
+///         let content;
+///         Ok(Struct {
+///             struct_token: input.parse()?,
+///             ident: input.parse()?,
+///             brace_token: braced!(content in input),
+///             fields: content.parse_terminated(Field::parse)?,
+///         })
+///     }
+/// }
+/// ```
+#[macro_export]
+macro_rules! braced {
+    ($content:ident in $cursor:expr) => {
+        match $crate::parse::ParseBuffer::parse_braces(&$cursor) {
+            $crate::export::Ok(braces) => {
+                $content = braces.content;
+                braces.token
+            }
+            $crate::export::Err(error) => {
+                return $crate::export::Err(error);
+            }
+        }
+    };
+}
+
+/// Parse a set of square brackets and expose their content to subsequent
+/// parsers.
+#[macro_export]
+macro_rules! bracketed {
+    ($content:ident in $cursor:expr) => {
+        match $crate::parse::ParseBuffer::parse_brackets(&$cursor) {
+            $crate::export::Ok(brackets) => {
+                $content = brackets.content;
+                brackets.token
+            }
+            $crate::export::Err(error) => {
+                return $crate::export::Err(error);
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! grouped {
+    ($content:ident in $cursor:expr) => {
+        match $crate::parse::ParseBuffer::parse_group(&$cursor) {
+            $crate::export::Ok(group) => {
+                $content = group.content;
+                group.token
+            }
+            $crate::export::Err(error) => {
+                return $crate::export::Err(error);
+            }
+        }
+    };
+}
diff --git a/src/ident.rs b/src/ident.rs
new file mode 100644
index 0000000..df4386b
--- /dev/null
+++ b/src/ident.rs
@@ -0,0 +1,11 @@
+#[cfg(feature = "parsing")]
+use lookahead;
+
+pub use proc_macro2::Ident;
+
+#[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Ident(marker: lookahead::TokenMarker) -> Ident {
+    match marker {}
+}
diff --git a/src/item.rs b/src/item.rs
index 7e49a4a..2e14a49 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -93,6 +93,7 @@
             pub vis: Visibility,
             pub constness: Option<Token![const]>,
             pub unsafety: Option<Token![unsafe]>,
+            pub asyncness: Option<Token![async]>,
             pub abi: Option<Abi>,
             pub ident: Ident,
             pub decl: Box<FnDecl>,
@@ -135,6 +136,21 @@
             pub semi_token: Token![;],
         }),
 
+        /// An existential type: `existential type Iter: Iterator<Item = u8>`.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub Existential(ItemExistential {
+            pub attrs: Vec<Attribute>,
+            pub vis: Visibility,
+            pub existential_token: Token![existential],
+            pub type_token: Token![type],
+            pub ident: Ident,
+            pub generics: Generics,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Punctuated<TypeParamBound, Token![+]>,
+            pub semi_token: Token![;],
+        }),
+
         /// A struct definition: `struct Foo<A> { x: A }`.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
@@ -429,6 +445,15 @@
             pub semi_token: Token![;],
         }),
 
+        /// A macro invocation within an extern block.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub Macro(ForeignItemMacro {
+            pub attrs: Vec<Attribute>,
+            pub mac: Macro,
+            pub semi_token: Option<Token![;]>,
+        }),
+
         /// Tokens in an `extern` block not interpreted by Syn.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
@@ -597,6 +622,20 @@
             pub semi_token: Token![;],
         }),
 
+        /// An existential type within an impl block.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub Existential(ImplItemExistential {
+            pub attrs: Vec<Attribute>,
+            pub existential_token: Token![existential],
+            pub type_token: Token![type],
+            pub ident: Ident,
+            pub generics: Generics,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Punctuated<TypeParamBound, Token![+]>,
+            pub semi_token: Token![;],
+        }),
+
         /// A macro invocation within an impl block.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
@@ -643,6 +682,7 @@
     pub struct MethodSig {
         pub constness: Option<Token![const]>,
         pub unsafety: Option<Token![unsafe]>,
+        pub asyncness: Option<Token![async]>,
         pub abi: Option<Abi>,
         pub ident: Ident,
         pub decl: FnDecl,
@@ -714,6 +754,8 @@
 pub mod parsing {
     use super::*;
 
+    use parse::{Parse, ParseStream, Result};
+    use synom::ext::IdentExt;
     use synom::Synom;
 
     impl_synom!(Item "item" alt!(
@@ -727,15 +769,13 @@
         |
         syn!(ItemFn) => { Item::Fn }
         |
-        call!(unstable_async_fn) => { Item::Verbatim }
-        |
         syn!(ItemMod) => { Item::Mod }
         |
         syn!(ItemForeignMod) => { Item::ForeignMod }
         |
         syn!(ItemType) => { Item::Type }
         |
-        call!(unstable_existential_type) => { Item::Verbatim }
+        syn!(ItemExistential) => { Item::Existential }
         |
         syn!(ItemStruct) => { Item::Struct }
         |
@@ -752,367 +792,337 @@
         syn!(ItemMacro2) => { Item::Macro2 }
     ));
 
-    impl_synom!(ItemMacro "macro item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        what: call!(Path::parse_mod_style) >>
-        bang: punct!(!) >>
-        ident: option!(syn!(Ident)) >>
-        body: call!(tt::delimited) >>
-        semi: cond!(!is_brace(&body.0), punct!(;)) >>
-        (ItemMacro {
-            attrs: attrs,
-            ident: ident,
-            mac: Macro {
-                path: what,
-                bang_token: bang,
-                delimiter: body.0,
-                tts: body.1,
-            },
-            semi_token: semi,
-        })
-    ));
-
-    // TODO: figure out the actual grammar; is body required to be braced?
-    impl_synom!(ItemMacro2 "macro2 item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        macro_: keyword!(macro) >>
-        ident: syn!(Ident) >>
-        args: call!(tt::parenthesized) >>
-        body: call!(tt::braced) >>
-        (ItemMacro2 {
-            attrs: attrs,
-            vis: vis,
-            macro_token: macro_,
-            ident: ident,
-            paren_token: args.0,
-            args: args.1,
-            brace_token: body.0,
-            body: body.1,
-        })
-    ));
-
-    impl_synom!(ItemExternCrate "extern crate item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        extern_: keyword!(extern) >>
-        crate_: keyword!(crate) >>
-        ident: syn!(Ident) >>
-        rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
-        semi: punct!(;) >>
-        (ItemExternCrate {
-            attrs: attrs,
-            vis: vis,
-            extern_token: extern_,
-            crate_token: crate_,
-            ident: ident,
-            rename: rename,
-            semi_token: semi,
-        })
-    ));
-
-    impl_synom!(ItemUse "use item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        use_: keyword!(use) >>
-        leading_colon: option!(punct!(::)) >>
-        tree: syn!(UseTree) >>
-        semi: punct!(;) >>
-        (ItemUse {
-            attrs: attrs,
-            vis: vis,
-            use_token: use_,
-            leading_colon: leading_colon,
-            tree: tree,
-            semi_token: semi,
-        })
-    ));
-
-    named!(use_element -> Ident, alt!(
-        syn!(Ident)
-        |
-        keyword!(self) => { Into::into }
-        |
-        keyword!(super) => { Into::into }
-        |
-        keyword!(crate) => { Into::into }
-        |
-        keyword!(extern) => { Into::into }
-    ));
-
-    impl_synom!(UseTree "use tree" alt!(
-        syn!(UseRename) => { UseTree::Rename }
-        |
-        syn!(UsePath) => { UseTree::Path }
-        |
-        syn!(UseName) => { UseTree::Name }
-        |
-        syn!(UseGlob) => { UseTree::Glob }
-        |
-        syn!(UseGroup) => { UseTree::Group }
-    ));
-
-    impl_synom!(UsePath "use path" do_parse!(
-        ident: call!(use_element) >>
-        colon2_token: punct!(::) >>
-        tree: syn!(UseTree) >>
-        (UsePath {
-            ident: ident,
-            colon2_token: colon2_token,
-            tree: Box::new(tree),
-        })
-    ));
-
-    impl_synom!(UseName "use name" do_parse!(
-        ident: call!(use_element) >>
-        (UseName {
-            ident: ident,
-        })
-    ));
-
-    impl_synom!(UseRename "use rename" do_parse!(
-        ident: call!(use_element) >>
-        as_token: keyword!(as) >>
-        rename: syn!(Ident) >>
-        (UseRename {
-            ident: ident,
-            as_token: as_token,
-            rename: rename,
-        })
-    ));
-
-    impl_synom!(UseGlob "use glob" do_parse!(
-        star: punct!(*) >>
-        (UseGlob {
-            star_token: star,
-        })
-    ));
-
-    impl_synom!(UseGroup "use group" do_parse!(
-        list: braces!(Punctuated::parse_terminated) >>
-        (UseGroup {
-            brace_token: list.0,
-            items: list.1,
-        })
-    ));
-
-    impl_synom!(ItemStatic "static item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        static_: keyword!(static) >>
-        mutability: option!(keyword!(mut)) >>
-        ident: syn!(Ident) >>
-        colon: punct!(:) >>
-        ty: syn!(Type) >>
-        eq: punct!(=) >>
-        value: syn!(Expr) >>
-        semi: punct!(;) >>
-        (ItemStatic {
-            attrs: attrs,
-            vis: vis,
-            static_token: static_,
-            mutability: mutability,
-            ident: ident,
-            colon_token: colon,
-            ty: Box::new(ty),
-            eq_token: eq,
-            expr: Box::new(value),
-            semi_token: semi,
-        })
-    ));
-
-    impl_synom!(ItemConst "const item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        const_: keyword!(const) >>
-        ident: syn!(Ident) >>
-        colon: punct!(:) >>
-        ty: syn!(Type) >>
-        eq: punct!(=) >>
-        value: syn!(Expr) >>
-        semi: punct!(;) >>
-        (ItemConst {
-            attrs: attrs,
-            vis: vis,
-            const_token: const_,
-            ident: ident,
-            colon_token: colon,
-            ty: Box::new(ty),
-            eq_token: eq,
-            expr: Box::new(value),
-            semi_token: semi,
-        })
-    ));
-
-    impl_synom!(ItemFn "fn item" do_parse!(
-        outer_attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        constness: option!(keyword!(const)) >>
-        unsafety: option!(keyword!(unsafe)) >>
-        abi: option!(syn!(Abi)) >>
-        fn_: keyword!(fn) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        inputs: parens!(Punctuated::parse_terminated) >>
-        ret: syn!(ReturnType) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        inner_attrs_stmts: braces!(tuple!(
-            many0!(Attribute::parse_inner),
-            call!(Block::parse_within),
-        )) >>
-        (ItemFn {
-            attrs: {
-                let mut attrs = outer_attrs;
-                attrs.extend((inner_attrs_stmts.1).0);
-                attrs
-            },
-            vis: vis,
-            constness: constness,
-            unsafety: unsafety,
-            abi: abi,
-            decl: Box::new(FnDecl {
-                fn_token: fn_,
-                paren_token: inputs.0,
-                inputs: inputs.1,
-                output: ret,
-                variadic: None,
-                generics: Generics {
-                    where_clause: where_clause,
-                    ..generics
+    impl Parse for ItemMacro {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let path = input.call(Path::parse_mod_style)?;
+            let bang_token: Token![!] = input.parse()?;
+            let ident: Option<Ident> = input.parse()?;
+            let (delimiter, tts) = input.call(mac::parse_delimiter)?;
+            let semi_token: Option<Token![;]> = if !is_brace(&delimiter) {
+                Some(input.parse()?)
+            } else {
+                None
+            };
+            Ok(ItemMacro {
+                attrs: attrs,
+                ident: ident,
+                mac: Macro {
+                    path: path,
+                    bang_token: bang_token,
+                    delimiter: delimiter,
+                    tts: tts,
                 },
-            }),
-            ident: ident,
-            block: Box::new(Block {
-                brace_token: inner_attrs_stmts.0,
-                stmts: (inner_attrs_stmts.1).1,
-            }),
-        })
-    ));
-
-    named!(unstable_async_fn -> ItemVerbatim, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        syn!(Visibility) >>
-        option!(keyword!(const)) >>
-        option!(keyword!(unsafe)) >>
-        keyword!(async) >>
-        option!(syn!(Abi)) >>
-        keyword!(fn) >>
-        syn!(Ident) >>
-        syn!(Generics) >>
-        parens!(Punctuated::<FnArg, Token![,]>::parse_terminated) >>
-        syn!(ReturnType) >>
-        option!(syn!(WhereClause)) >>
-        braces!(tuple!(
-            many0!(Attribute::parse_inner),
-            call!(Block::parse_within),
-        )) >>
-        end: call!(verbatim::grab_cursor) >>
-        (ItemVerbatim {
-            tts: verbatim::token_range(begin..end),
-        })
-    ));
-
-    impl Synom for FnArg {
-        named!(parse -> Self, alt!(
-            do_parse!(
-                and: punct!(&) >>
-                lt: option!(syn!(Lifetime)) >>
-                mutability: option!(keyword!(mut)) >>
-                self_: keyword!(self) >>
-                not!(punct!(:)) >>
-                (ArgSelfRef {
-                    lifetime: lt,
-                    mutability: mutability,
-                    and_token: and,
-                    self_token: self_,
-                }.into())
-            )
-            |
-            do_parse!(
-                mutability: option!(keyword!(mut)) >>
-                self_: keyword!(self) >>
-                not!(punct!(:)) >>
-                (ArgSelf {
-                    mutability: mutability,
-                    self_token: self_,
-                }.into())
-            )
-            |
-            do_parse!(
-                pat: syn!(Pat) >>
-                colon: punct!(:) >>
-                ty: syn!(Type) >>
-                (ArgCaptured {
-                    pat: pat,
-                    ty: ty,
-                    colon_token: colon,
-                }.into())
-            )
-            |
-            syn!(Type) => { FnArg::Ignored }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("function argument")
+                semi_token: semi_token,
+            })
         }
     }
 
-    impl_synom!(ItemMod "mod item" do_parse!(
-        outer_attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        mod_: keyword!(mod) >>
-        ident: syn!(Ident) >>
-        content_semi: alt!(
-            punct!(;) => {|semi| (
-                Vec::new(),
-                None,
-                Some(semi),
-            )}
-            |
-            braces!(
-                tuple!(
-                    many0!(Attribute::parse_inner),
-                    many0!(Item::parse),
-                )
-            ) => {|(brace, (inner_attrs, items))| (
-                inner_attrs,
-                Some((brace, items)),
-                None,
-            )}
-        ) >>
-        (ItemMod {
-            attrs: {
-                let mut attrs = outer_attrs;
-                attrs.extend(content_semi.0);
-                attrs
-            },
-            vis: vis,
-            mod_token: mod_,
-            ident: ident,
-            content: content_semi.1,
-            semi: content_semi.2,
-        })
-    ));
+    // TODO: figure out the actual grammar; is body required to be braced?
+    impl Parse for ItemMacro2 {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let args;
+            let body;
+            Ok(ItemMacro2 {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                macro_token: input.parse()?,
+                ident: input.parse()?,
+                paren_token: parenthesized!(args in input),
+                args: args.parse()?,
+                brace_token: braced!(body in input),
+                body: body.parse()?,
+            })
+        }
+    }
 
-    impl_synom!(ItemForeignMod "foreign mod item" do_parse!(
-        outer_attrs: many0!(Attribute::parse_outer) >>
-        abi: syn!(Abi) >>
-        braced_content: braces!(tuple!(
-            many0!(Attribute::parse_inner),
-            many0!(ForeignItem::parse),
-        )) >>
-        (ItemForeignMod {
-            attrs: {
-                let mut attrs = outer_attrs;
-                attrs.extend((braced_content.1).0);
-                attrs
-            },
-            abi: abi,
-            brace_token: braced_content.0,
-            items: (braced_content.1).1,
+    impl Parse for ItemExternCrate {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ItemExternCrate {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                extern_token: input.parse()?,
+                crate_token: input.parse()?,
+                ident: input.parse()?,
+                rename: {
+                    if input.peek(Token![as]) {
+                        let as_token: Token![as] = input.parse()?;
+                        let rename: Ident = input.parse()?;
+                        Some((as_token, rename))
+                    } else {
+                        None
+                    }
+                },
+                semi_token: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for ItemUse {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ItemUse {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                use_token: input.parse()?,
+                leading_colon: input.parse()?,
+                tree: input.call(use_tree)?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
+
+    fn use_tree(input: ParseStream) -> Result<UseTree> {
+        let lookahead = input.lookahead1();
+        if lookahead.peek(Ident)
+            || lookahead.peek(Token![self])
+            || lookahead.peek(Token![super])
+            || lookahead.peek(Token![crate])
+            || lookahead.peek(Token![extern])
+        {
+            let ident = input.call(Ident::parse_any2)?;
+            if input.peek(Token![::]) {
+                Ok(UseTree::Path(UsePath {
+                    ident: ident,
+                    colon2_token: input.parse()?,
+                    tree: Box::new(input.call(use_tree)?),
+                }))
+            } else if input.peek(Token![as]) {
+                Ok(UseTree::Rename(UseRename {
+                    ident: ident,
+                    as_token: input.parse()?,
+                    rename: input.parse()?,
+                }))
+            } else {
+                Ok(UseTree::Name(UseName { ident: ident }))
+            }
+        } else if lookahead.peek(Token![*]) {
+            Ok(UseTree::Glob(UseGlob {
+                star_token: input.parse()?,
+            }))
+        } else if lookahead.peek(token::Brace) {
+            let content;
+            Ok(UseTree::Group(UseGroup {
+                brace_token: braced!(content in input),
+                items: content.parse_terminated(use_tree)?,
+            }))
+        } else {
+            Err(lookahead.error())
+        }
+    }
+
+    impl Parse for ItemStatic {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ItemStatic {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                static_token: input.parse()?,
+                mutability: input.parse()?,
+                ident: input.parse()?,
+                colon_token: input.parse()?,
+                ty: input.parse()?,
+                eq_token: input.parse()?,
+                expr: Box::new(input.parse_synom(Expr::parse)?),
+                semi_token: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for ItemConst {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ItemConst {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                const_token: input.parse()?,
+                ident: input.parse()?,
+                colon_token: input.parse()?,
+                ty: input.parse()?,
+                eq_token: input.parse()?,
+                expr: Box::new(input.parse_synom(Expr::parse)?),
+                semi_token: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for ItemFn {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let outer_attrs = input.call(Attribute::parse_outer)?;
+            let vis: Visibility = input.parse()?;
+            let constness: Option<Token![const]> = input.parse()?;
+            let unsafety: Option<Token![unsafe]> = input.parse()?;
+            let asyncness: Option<Token![async]> = input.parse()?;
+            let abi: Option<Abi> = input.parse()?;
+            let fn_token: Token![fn] = input.parse()?;
+            let ident: Ident = input.parse()?;
+            let generics: Generics = input.parse()?;
+
+            let content;
+            let paren_token = parenthesized!(content in input);
+            let inputs = content.parse_terminated(<FnArg as Parse>::parse)?;
+
+            let output: ReturnType = input.parse()?;
+            let where_clause: Option<WhereClause> = input.parse()?;
+
+            let content;
+            let brace_token = braced!(content in input);
+            let inner_attrs = content.call(Attribute::parse_inner)?;
+            let stmts = content.parse_synom(Block::parse_within)?;
+
+            Ok(ItemFn {
+                attrs: {
+                    let mut attrs = outer_attrs;
+                    attrs.extend(inner_attrs);
+                    attrs
+                },
+                vis: vis,
+                constness: constness,
+                unsafety: unsafety,
+                asyncness: asyncness,
+                abi: abi,
+                ident: ident,
+                decl: Box::new(FnDecl {
+                    fn_token: fn_token,
+                    paren_token: paren_token,
+                    inputs: inputs,
+                    output: output,
+                    variadic: None,
+                    generics: Generics {
+                        where_clause: where_clause,
+                        ..generics
+                    },
+                }),
+                block: Box::new(Block {
+                    brace_token: brace_token,
+                    stmts: stmts,
+                }),
+            })
+        }
+    }
+
+    impl Parse for FnArg {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![&]) {
+                let ahead = input.fork();
+                if ahead.call(arg_self_ref).is_ok() && !ahead.peek(Token![:]) {
+                    return input.call(arg_self_ref).map(FnArg::SelfRef);
+                }
+            }
+
+            if input.peek(Token![mut]) || input.peek(Token![self]) {
+                let ahead = input.fork();
+                if ahead.call(arg_self).is_ok() && !ahead.peek(Token![:]) {
+                    return input.call(arg_self).map(FnArg::SelfValue);
+                }
+            }
+
+            let ahead = input.fork();
+            let err = match ahead.call(arg_captured) {
+                Ok(_) => return input.call(arg_captured).map(FnArg::Captured),
+                Err(err) => err,
+            };
+
+            let ahead = input.fork();
+            if ahead.parse::<Type>().is_ok() {
+                return input.parse().map(FnArg::Ignored);
+            }
+
+            Err(err)
+        }
+    }
+
+    fn arg_self_ref(input: ParseStream) -> Result<ArgSelfRef> {
+        Ok(ArgSelfRef {
+            and_token: input.parse()?,
+            lifetime: input.parse()?,
+            mutability: input.parse()?,
+            self_token: input.parse()?,
         })
-    ));
+    }
+
+    fn arg_self(input: ParseStream) -> Result<ArgSelf> {
+        Ok(ArgSelf {
+            mutability: input.parse()?,
+            self_token: input.parse()?,
+        })
+    }
+
+    fn arg_captured(input: ParseStream) -> Result<ArgCaptured> {
+        Ok(ArgCaptured {
+            pat: input.parse_synom(Pat::parse)?,
+            colon_token: input.parse()?,
+            ty: input.parse()?,
+        })
+    }
+
+    impl Parse for ItemMod {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let outer_attrs = input.call(Attribute::parse_outer)?;
+            let vis: Visibility = input.parse()?;
+            let mod_token: Token![mod] = input.parse()?;
+            let ident: Ident = input.parse()?;
+
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Token![;]) {
+                Ok(ItemMod {
+                    attrs: outer_attrs,
+                    vis: vis,
+                    mod_token: mod_token,
+                    ident: ident,
+                    content: None,
+                    semi: Some(input.parse()?),
+                })
+            } else if lookahead.peek(token::Brace) {
+                let content;
+                let brace_token = braced!(content in input);
+                let inner_attrs = content.call(Attribute::parse_inner)?;
+
+                let mut items = Vec::new();
+                while !content.is_empty() {
+                    items.push(content.parse_synom(Item::parse)?);
+                }
+
+                Ok(ItemMod {
+                    attrs: {
+                        let mut attrs = outer_attrs;
+                        attrs.extend(inner_attrs);
+                        attrs
+                    },
+                    vis: vis,
+                    mod_token: mod_token,
+                    ident: ident,
+                    content: Some((brace_token, items)),
+                    semi: None,
+                })
+            } else {
+                Err(lookahead.error())
+            }
+        }
+    }
+
+    impl Parse for ItemForeignMod {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let outer_attrs = input.call(Attribute::parse_outer)?;
+            let abi: Abi = input.parse()?;
+
+            let content;
+            let brace_token = braced!(content in input);
+            let inner_attrs = content.call(Attribute::parse_inner)?;
+            let mut items = Vec::new();
+            while !content.is_empty() {
+                items.push(content.parse_synom(ForeignItem::parse)?);
+            }
+
+            Ok(ItemForeignMod {
+                attrs: {
+                    let mut attrs = outer_attrs;
+                    attrs.extend(inner_attrs);
+                    attrs
+                },
+                abi: abi,
+                brace_token: brace_token,
+                items: items,
+            })
+        }
+    }
 
     impl_synom!(ForeignItem "foreign item" alt!(
         syn!(ForeignItemFn) => { ForeignItem::Fn }
@@ -1121,140 +1131,132 @@
         |
         syn!(ForeignItemType) => { ForeignItem::Type }
         |
-        call!(foreign_item_macro) => { ForeignItem::Verbatim }
+        syn!(ForeignItemMacro) => { ForeignItem::Macro }
     ));
 
-    impl_synom!(ForeignItemFn "foreign function" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        fn_: keyword!(fn) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        inputs: parens!(do_parse!(
-            args: call!(Punctuated::parse_terminated) >>
-            variadic: option!(cond_reduce!(args.empty_or_trailing(), punct!(...))) >>
-            (args, variadic)
-        )) >>
-        ret: syn!(ReturnType) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        semi: punct!(;) >>
-        ({
-            let (parens, (inputs, variadic)) = inputs;
-            ForeignItemFn {
-                ident: ident,
+    impl Parse for ForeignItemFn {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let vis: Visibility = input.parse()?;
+            let fn_token: Token![fn] = input.parse()?;
+            let ident: Ident = input.parse()?;
+            let generics: Generics = input.parse()?;
+
+            let content;
+            let paren_token = parenthesized!(content in input);
+            let inputs = content.parse_synom(Punctuated::parse_terminated)?;
+            let variadic: Option<Token![...]> = if inputs.empty_or_trailing() {
+                content.parse()?
+            } else {
+                None
+            };
+
+            let output: ReturnType = input.parse()?;
+            let where_clause: Option<WhereClause> = input.parse()?;
+            let semi_token: Token![;] = input.parse()?;
+
+            Ok(ForeignItemFn {
                 attrs: attrs,
-                semi_token: semi,
+                vis: vis,
+                ident: ident,
                 decl: Box::new(FnDecl {
-                    fn_token: fn_,
-                    paren_token: parens,
+                    fn_token: fn_token,
+                    paren_token: paren_token,
                     inputs: inputs,
+                    output: output,
                     variadic: variadic,
-                    output: ret,
                     generics: Generics {
                         where_clause: where_clause,
                         ..generics
                     },
                 }),
-                vis: vis,
-            }
-        })
-    ));
+                semi_token: semi_token,
+            })
+        }
+    }
 
-    impl_synom!(ForeignItemStatic "foreign static" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        static_: keyword!(static) >>
-        mutability: option!(keyword!(mut)) >>
-        ident: syn!(Ident) >>
-        colon: punct!(:) >>
-        ty: syn!(Type) >>
-        semi: punct!(;) >>
-        (ForeignItemStatic {
-            ident: ident,
-            attrs: attrs,
-            semi_token: semi,
-            ty: Box::new(ty),
-            mutability: mutability,
-            static_token: static_,
-            colon_token: colon,
-            vis: vis,
-        })
-    ));
+    impl Parse for ForeignItemStatic {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ForeignItemStatic {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                static_token: input.parse()?,
+                mutability: input.parse()?,
+                ident: input.parse()?,
+                colon_token: input.parse()?,
+                ty: input.parse()?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
 
-    impl_synom!(ForeignItemType "foreign type" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        type_: keyword!(type) >>
-        ident: syn!(Ident) >>
-        semi: punct!(;) >>
-        (ForeignItemType {
-            attrs: attrs,
-            vis: vis,
-            type_token: type_,
-            ident: ident,
-            semi_token: semi,
-        })
-    ));
+    impl Parse for ForeignItemType {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ForeignItemType {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                type_token: input.parse()?,
+                ident: input.parse()?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
 
-    named!(foreign_item_macro -> ForeignItemVerbatim, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        mac: syn!(Macro) >>
-        cond!(!is_brace(&mac.delimiter), punct!(;)) >>
-        end: call!(verbatim::grab_cursor) >>
-        (ForeignItemVerbatim {
-            tts: verbatim::token_range(begin..end),
-        })
-    ));
+    impl Parse for ForeignItemMacro {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let mac: Macro = input.parse()?;
+            let semi_token: Option<Token![;]> = if is_brace(&mac.delimiter) {
+                None
+            } else {
+                Some(input.parse()?)
+            };
+            Ok(ForeignItemMacro {
+                attrs: attrs,
+                mac: mac,
+                semi_token: semi_token,
+            })
+        }
+    }
 
-    impl_synom!(ItemType "type item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        type_: keyword!(type) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        eq: punct!(=) >>
-        ty: syn!(Type) >>
-        semi: punct!(;) >>
-        (ItemType {
-            attrs: attrs,
-            vis: vis,
-            type_token: type_,
-            ident: ident,
-            generics: Generics {
-                where_clause: where_clause,
-                ..generics
-            },
-            eq_token: eq,
-            ty: Box::new(ty),
-            semi_token: semi,
-        })
-    ));
+    impl Parse for ItemType {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ItemType {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                type_token: input.parse()?,
+                ident: input.parse()?,
+                generics: {
+                    let mut generics: Generics = input.parse()?;
+                    generics.where_clause = input.parse()?;
+                    generics
+                },
+                eq_token: input.parse()?,
+                ty: input.parse()?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
 
-    named!(existential_type_helper(vis: bool) -> TokenStream, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        cond_reduce!(vis, syn!(Visibility)) >>
-        custom_keyword!(existential) >>
-        keyword!(type) >>
-        syn!(Ident) >>
-        syn!(Generics) >>
-        option!(syn!(WhereClause)) >>
-        colon: option!(punct!(:)) >>
-        cond!(
-            colon.is_some(),
-            Punctuated::<TypeParamBound, Token![+]>::parse_separated_nonempty
-        ) >>
-        punct!(;) >>
-        end: call!(verbatim::grab_cursor) >>
-        (verbatim::token_range(begin..end))
-    ));
-
-    named!(unstable_existential_type -> ItemVerbatim, map!(
-        call!(existential_type_helper, true),
-        |tts| ItemVerbatim { tts: tts }
-    ));
+    impl Parse for ItemExistential {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ItemExistential {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                existential_token: input.parse()?,
+                type_token: input.parse()?,
+                ident: input.parse()?,
+                generics: {
+                    let mut generics: Generics = input.parse()?;
+                    generics.where_clause = input.parse()?;
+                    generics
+                },
+                colon_token: Some(input.parse()?),
+                bounds: input.parse_synom(Punctuated::parse_separated_nonempty)?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
 
     impl_synom!(ItemStruct "struct item" switch!(
         map!(syn!(DeriveInput), Into::into),
@@ -1271,7 +1273,7 @@
     ));
 
     impl_synom!(ItemUnion "union item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         vis: syn!(Visibility) >>
         union_: keyword!(union) >>
         ident: syn!(Ident) >>
@@ -1292,7 +1294,7 @@
     ));
 
     impl_synom!(ItemTrait "trait item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         vis: syn!(Visibility) >>
         unsafety: option!(keyword!(unsafe)) >>
         auto_: option!(keyword!(auto)) >>
@@ -1328,13 +1330,11 @@
         |
         syn!(TraitItemType) => { TraitItem::Type }
         |
-        call!(unstable_trait_existential_type) => { TraitItem::Verbatim }
-        |
         syn!(TraitItemMacro) => { TraitItem::Macro }
     ));
 
     impl_synom!(TraitItemConst "const trait item" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         const_: keyword!(const) >>
         ident: syn!(Ident) >>
         colon: punct!(:) >>
@@ -1353,7 +1353,7 @@
     ));
 
     impl_synom!(TraitItemMethod "method trait item" do_parse!(
-        outer_attrs: many0!(Attribute::parse_outer) >>
+        outer_attrs: many0!(Attribute::old_parse_outer) >>
         constness: option!(keyword!(const)) >>
         unsafety: option!(keyword!(unsafe)) >>
         abi: option!(syn!(Abi)) >>
@@ -1364,7 +1364,7 @@
         ret: syn!(ReturnType) >>
         where_clause: option!(syn!(WhereClause)) >>
         body: option!(braces!(tuple!(
-            many0!(Attribute::parse_inner),
+            many0!(Attribute::old_parse_inner),
             call!(Block::parse_within),
         ))) >>
         semi: cond!(body.is_none(), punct!(;)) >>
@@ -1382,6 +1382,7 @@
                 sig: MethodSig {
                     constness: constness,
                     unsafety: unsafety,
+                    asyncness: None,
                     abi: abi,
                     ident: ident,
                     decl: FnDecl {
@@ -1408,7 +1409,7 @@
     ));
 
     impl_synom!(TraitItemType "trait item type" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         type_: keyword!(type) >>
         ident: syn!(Ident) >>
         generics: syn!(Generics) >>
@@ -1432,13 +1433,8 @@
         })
     ));
 
-    named!(unstable_trait_existential_type -> TraitItemVerbatim, map!(
-        call!(existential_type_helper, false),
-        |tts| TraitItemVerbatim { tts: tts }
-    ));
-
     impl_synom!(TraitItemMacro "trait item macro" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
+        attrs: many0!(Attribute::old_parse_outer) >>
         mac: syn!(Macro) >>
         semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
         (TraitItemMacro {
@@ -1449,7 +1445,7 @@
     ));
 
     impl_synom!(ItemImpl "impl item" do_parse!(
-        outer_attrs: many0!(Attribute::parse_outer) >>
+        outer_attrs: many0!(Attribute::old_parse_outer) >>
         defaultness: option!(keyword!(default)) >>
         unsafety: option!(keyword!(unsafe)) >>
         impl_: keyword!(impl) >>
@@ -1467,7 +1463,7 @@
         self_ty: syn!(Type) >>
         where_clause: option!(syn!(WhereClause)) >>
         inner: braces!(tuple!(
-            many0!(Attribute::parse_inner),
+            many0!(Attribute::old_parse_inner),
             many0!(ImplItem::parse),
         )) >>
         (ItemImpl {
@@ -1495,46 +1491,37 @@
         |
         syn!(ImplItemMethod) => { ImplItem::Method }
         |
-        call!(unstable_async_method) => { ImplItem::Verbatim }
-        |
         syn!(ImplItemType) => { ImplItem::Type }
         |
-        call!(unstable_impl_existential_type) => { ImplItem::Verbatim }
+        syn!(ImplItemExistential) => { ImplItem::Existential }
         |
         syn!(ImplItemMacro) => { ImplItem::Macro }
     ));
 
-    impl_synom!(ImplItemConst "const item in impl block" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        defaultness: option!(keyword!(default)) >>
-        const_: keyword!(const) >>
-        ident: syn!(Ident) >>
-        colon: punct!(:) >>
-        ty: syn!(Type) >>
-        eq: punct!(=) >>
-        value: syn!(Expr) >>
-        semi: punct!(;) >>
-        (ImplItemConst {
-            attrs: attrs,
-            vis: vis,
-            defaultness: defaultness,
-            const_token: const_,
-            ident: ident,
-            colon_token: colon,
-            ty: ty,
-            eq_token: eq,
-            expr: value,
-            semi_token: semi,
-        })
-    ));
+    impl Parse for ImplItemConst {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ImplItemConst {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                defaultness: input.parse()?,
+                const_token: input.parse()?,
+                ident: input.parse()?,
+                colon_token: input.parse()?,
+                ty: input.parse()?,
+                eq_token: input.parse()?,
+                expr: input.parse_synom(Expr::parse)?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
 
     impl_synom!(ImplItemMethod "method in impl block" do_parse!(
-        outer_attrs: many0!(Attribute::parse_outer) >>
+        outer_attrs: many0!(Attribute::old_parse_outer) >>
         vis: syn!(Visibility) >>
         defaultness: option!(keyword!(default)) >>
         constness: option!(keyword!(const)) >>
         unsafety: option!(keyword!(unsafe)) >>
+        asyncness: option!(keyword!(async)) >>
         abi: option!(syn!(Abi)) >>
         fn_: keyword!(fn) >>
         ident: syn!(Ident) >>
@@ -1543,7 +1530,7 @@
         ret: syn!(ReturnType) >>
         where_clause: option!(syn!(WhereClause)) >>
         inner_attrs_stmts: braces!(tuple!(
-            many0!(Attribute::parse_inner),
+            many0!(Attribute::old_parse_inner),
             call!(Block::parse_within),
         )) >>
         (ImplItemMethod {
@@ -1557,6 +1544,7 @@
             sig: MethodSig {
                 constness: constness,
                 unsafety: unsafety,
+                asyncness: asyncness,
                 abi: abi,
                 ident: ident,
                 decl: FnDecl {
@@ -1578,73 +1566,58 @@
         })
     ));
 
-    named!(unstable_async_method -> ImplItemVerbatim, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        syn!(Visibility) >>
-        option!(keyword!(default)) >>
-        option!(keyword!(const)) >>
-        option!(keyword!(unsafe)) >>
-        keyword!(async) >>
-        option!(syn!(Abi)) >>
-        keyword!(fn) >>
-        syn!(Ident) >>
-        syn!(Generics) >>
-        parens!(Punctuated::<FnArg, Token![,]>::parse_terminated) >>
-        syn!(ReturnType) >>
-        option!(syn!(WhereClause)) >>
-        braces!(tuple!(
-            many0!(Attribute::parse_inner),
-            call!(Block::parse_within),
-        )) >>
-        end: call!(verbatim::grab_cursor) >>
-        (ImplItemVerbatim {
-            tts: verbatim::token_range(begin..end),
-        })
-    ));
+    impl Parse for ImplItemType {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(ImplItemType {
+                attrs: input.call(Attribute::parse_outer)?,
+                vis: input.parse()?,
+                defaultness: input.parse()?,
+                type_token: input.parse()?,
+                ident: input.parse()?,
+                generics: {
+                    let mut generics: Generics = input.parse()?;
+                    generics.where_clause = input.parse()?;
+                    generics
+                },
+                eq_token: input.parse()?,
+                ty: input.parse()?,
+                semi_token: input.parse()?,
+            })
+        }
+    }
 
-    impl_synom!(ImplItemType "type in impl block" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        vis: syn!(Visibility) >>
-        defaultness: option!(keyword!(default)) >>
-        type_: keyword!(type) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        eq: punct!(=) >>
-        ty: syn!(Type) >>
-        semi: punct!(;) >>
-        (ImplItemType {
-            attrs: attrs,
-            vis: vis,
-            defaultness: defaultness,
-            type_token: type_,
-            ident: ident,
-            generics: Generics {
-                where_clause: where_clause,
-                ..generics
-            },
-            eq_token: eq,
-            ty: ty,
-            semi_token: semi,
-        })
-    ));
+    impl Parse for ImplItemExistential {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let ety: ItemExistential = input.parse()?;
+            Ok(ImplItemExistential {
+                attrs: ety.attrs,
+                existential_token: ety.existential_token,
+                type_token: ety.type_token,
+                ident: ety.ident,
+                generics: ety.generics,
+                colon_token: ety.colon_token,
+                bounds: ety.bounds,
+                semi_token: ety.semi_token,
+            })
+        }
+    }
 
-    named!(unstable_impl_existential_type -> ImplItemVerbatim, map!(
-        call!(existential_type_helper, true),
-        |tts| ImplItemVerbatim { tts: tts }
-    ));
-
-    impl_synom!(ImplItemMacro "macro in impl block" do_parse!(
-        attrs: many0!(Attribute::parse_outer) >>
-        mac: syn!(Macro) >>
-        semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
-        (ImplItemMacro {
-            attrs: attrs,
-            mac: mac,
-            semi_token: semi,
-        })
-    ));
+    impl Parse for ImplItemMacro {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let mac: Macro = input.parse()?;
+            let semi_token: Option<Token![;]> = if is_brace(&mac.delimiter) {
+                None
+            } else {
+                Some(input.parse()?)
+            };
+            Ok(ImplItemMacro {
+                attrs: attrs,
+                mac: mac,
+                semi_token: semi_token,
+            })
+        }
+    }
 
     fn is_brace(delimiter: &MacroDelimiter) -> bool {
         match *delimiter {
@@ -1722,6 +1695,7 @@
             self.vis.to_tokens(tokens);
             self.constness.to_tokens(tokens);
             self.unsafety.to_tokens(tokens);
+            self.asyncness.to_tokens(tokens);
             self.abi.to_tokens(tokens);
             NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
             self.block.brace_token.surround(tokens, |tokens| {
@@ -1773,6 +1747,23 @@
         }
     }
 
+    impl ToTokens for ItemExistential {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            tokens.append_all(self.attrs.outer());
+            self.vis.to_tokens(tokens);
+            self.existential_token.to_tokens(tokens);
+            self.type_token.to_tokens(tokens);
+            self.ident.to_tokens(tokens);
+            self.generics.to_tokens(tokens);
+            self.generics.where_clause.to_tokens(tokens);
+            if !self.bounds.is_empty() {
+                TokensOrDefault(&self.colon_token).to_tokens(tokens);
+                self.bounds.to_tokens(tokens);
+            }
+            self.semi_token.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for ItemEnum {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2052,6 +2043,22 @@
         }
     }
 
+    impl ToTokens for ImplItemExistential {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            tokens.append_all(self.attrs.outer());
+            self.existential_token.to_tokens(tokens);
+            self.type_token.to_tokens(tokens);
+            self.ident.to_tokens(tokens);
+            self.generics.to_tokens(tokens);
+            self.generics.where_clause.to_tokens(tokens);
+            if !self.bounds.is_empty() {
+                TokensOrDefault(&self.colon_token).to_tokens(tokens);
+                self.bounds.to_tokens(tokens);
+            }
+            self.semi_token.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for ImplItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2098,6 +2105,14 @@
         }
     }
 
+    impl ToTokens for ForeignItemMacro {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            tokens.append_all(self.attrs.outer());
+            self.mac.to_tokens(tokens);
+            self.semi_token.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for ForeignItemVerbatim {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.tts.to_tokens(tokens);
@@ -2108,6 +2123,7 @@
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.constness.to_tokens(tokens);
             self.unsafety.to_tokens(tokens);
+            self.asyncness.to_tokens(tokens);
             self.abi.to_tokens(tokens);
             NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
         }
diff --git a/src/lib.rs b/src/lib.rs
index debb5b0..62f76a1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -280,6 +280,7 @@
     allow(
         cast_possible_truncation,
         cast_possible_wrap,
+        empty_enum,
         if_not_else,
         indexing_slicing,
         items_after_statements,
@@ -315,7 +316,8 @@
 #[macro_use]
 pub mod token;
 
-pub use proc_macro2::Ident;
+mod ident;
+pub use ident::Ident;
 
 #[cfg(any(feature = "full", feature = "derive"))]
 mod attr;
@@ -334,12 +336,12 @@
 mod expr;
 #[cfg(any(feature = "full", feature = "derive"))]
 pub use expr::{
-    Expr, ExprArray, ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox, ExprBreak, ExprCall,
-    ExprCast, ExprCatch, ExprClosure, ExprContinue, ExprField, ExprForLoop, ExprGroup, ExprIf,
-    ExprIfLet, ExprInPlace, ExprIndex, ExprLit, ExprLoop, ExprMacro, ExprMatch, ExprMethodCall,
-    ExprParen, ExprPath, ExprRange, ExprReference, ExprRepeat, ExprReturn, ExprStruct, ExprTry,
-    ExprTuple, ExprType, ExprUnary, ExprUnsafe, ExprVerbatim, ExprWhile, ExprWhileLet, ExprYield,
-    Index, Member,
+    Expr, ExprArray, ExprAssign, ExprAssignOp, ExprAsync, ExprBinary, ExprBlock, ExprBox,
+    ExprBreak, ExprCall, ExprCast, ExprClosure, ExprContinue, ExprField, ExprForLoop, ExprGroup,
+    ExprIf, ExprIfLet, ExprInPlace, ExprIndex, ExprLit, ExprLoop, ExprMacro, ExprMatch,
+    ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprReference, ExprRepeat, ExprReturn,
+    ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprType, ExprUnary, ExprUnsafe, ExprVerbatim,
+    ExprWhile, ExprWhileLet, ExprYield, Index, Member,
 };
 
 #[cfg(feature = "full")]
@@ -367,13 +369,13 @@
 mod item;
 #[cfg(feature = "full")]
 pub use item::{
-    ArgCaptured, ArgSelf, ArgSelfRef, FnArg, FnDecl, ForeignItem, ForeignItemFn, ForeignItemStatic,
-    ForeignItemType, ForeignItemVerbatim, ImplItem, ImplItemConst, ImplItemMacro, ImplItemMethod,
-    ImplItemType, ImplItemVerbatim, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
-    ItemForeignMod, ItemImpl, ItemMacro, ItemMacro2, ItemMod, ItemStatic, ItemStruct, ItemTrait,
-    ItemType, ItemUnion, ItemUse, ItemVerbatim, MethodSig, TraitItem, TraitItemConst,
-    TraitItemMacro, TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName,
-    UsePath, UseRename, UseTree,
+    ArgCaptured, ArgSelf, ArgSelfRef, FnArg, FnDecl, ForeignItem, ForeignItemFn, ForeignItemMacro,
+    ForeignItemStatic, ForeignItemType, ForeignItemVerbatim, ImplItem, ImplItemConst,
+    ImplItemExistential, ImplItemMacro, ImplItemMethod, ImplItemType, ImplItemVerbatim, Item,
+    ItemConst, ItemEnum, ItemExistential, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl,
+    ItemMacro, ItemMacro2, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemType, ItemUnion,
+    ItemUse, ItemVerbatim, MethodSig, TraitItem, TraitItemConst, TraitItemMacro, TraitItemMethod,
+    TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree,
 };
 
 #[cfg(feature = "full")]
@@ -436,7 +438,10 @@
 pub mod punctuated;
 #[cfg(feature = "parsing")]
 pub mod synom;
-#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg(all(
+    any(feature = "full", feature = "derive"),
+    feature = "extra-traits"
+))]
 mod tt;
 
 // Not public API except the `parse_quote!` macro.
@@ -567,15 +572,36 @@
 }
 pub use gen::*;
 
+// Not public API.
+#[doc(hidden)]
+pub mod export;
+
+#[cfg(feature = "parsing")]
+pub mod next;
+
+#[cfg(feature = "parsing")]
+mod lookahead;
+
+#[cfg(feature = "parsing")]
+pub mod parse;
+
+#[cfg(feature = "parsing")]
+#[macro_use]
+mod group;
+
+mod span;
+
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "parsing")]
+use proc_macro2::Span;
+#[cfg(feature = "parsing")]
 use synom::{Parser, Synom};
 
 #[cfg(feature = "parsing")]
 mod error;
 #[cfg(feature = "parsing")]
-use error::ParseError;
+use error::Error;
 
 // Not public API.
 #[cfg(feature = "parsing")]
@@ -634,7 +660,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,
 {
@@ -654,13 +680,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,
     })
 }
@@ -694,10 +720,13 @@
 /// # 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",
+        )),
     }
 }
 
@@ -742,7 +771,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/lifetime.rs b/src/lifetime.rs
index 5ca876f..c8101eb 100644
--- a/src/lifetime.rs
+++ b/src/lifetime.rs
@@ -13,6 +13,8 @@
 use proc_macro2::{Ident, Span};
 use unicode_xid::UnicodeXID;
 
+#[cfg(feature = "parsing")]
+use lookahead;
 use token::Apostrophe;
 
 /// A Rust lifetime: `'a`.
@@ -107,30 +109,29 @@
 }
 
 #[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Lifetime(marker: lookahead::TokenMarker) -> Lifetime {
+    match marker {}
+}
+
+#[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use buffer::Cursor;
-    use parse_error;
-    use synom::PResult;
-    use synom::Synom;
+    use parse::{Error, Parse, ParseStream, Result};
+    use synom::ext::IdentExt;
 
-    impl Synom for Lifetime {
-        fn parse(input: Cursor) -> PResult<Self> {
-            let (apostrophe, rest) = Apostrophe::parse(input)?;
-            let (ident, rest) = match rest.ident() {
-                Some(pair) => pair,
-                None => return parse_error(),
-            };
-
-            let ret = Lifetime {
-                ident: ident,
-                apostrophe: apostrophe,
-            };
-            Ok((ret, rest))
-        }
-
-        fn description() -> Option<&'static str> {
-            Some("lifetime")
+    impl Parse for Lifetime {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(Lifetime {
+                apostrophe: match input.parse() {
+                    Ok(apostrophe) => apostrophe,
+                    Err(err) => {
+                        return Err(Error::new(err.span(), "expected lifetime"));
+                    }
+                },
+                ident: input.call(Ident::parse_any2)?,
+            })
         }
     }
 }
diff --git a/src/lit.rs b/src/lit.rs
index 47555d4..908ff89 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -15,13 +15,16 @@
 #[cfg(feature = "parsing")]
 use proc_macro2::TokenStream;
 #[cfg(feature = "parsing")]
-use {ParseError, Synom};
+use {Error, Synom};
 
 use proc_macro2::TokenTree;
 
 #[cfg(feature = "extra-traits")]
 use std::hash::{Hash, Hasher};
 
+#[cfg(feature = "parsing")]
+use lookahead;
+
 ast_enum_of_structs! {
     /// A Rust literal such as a string or integer or boolean.
     ///
@@ -122,12 +125,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()))
         }
@@ -411,96 +414,120 @@
 }
 
 #[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Lit(marker: lookahead::TokenMarker) -> Lit {
+    match marker {}
+}
+
+#[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use buffer::Cursor;
+    use parse::{Parse, ParseStream, Result};
     use parse_error;
-    use synom::PResult;
-    use synom::Synom;
 
-    impl Synom for Lit {
-        fn parse(input: Cursor) -> PResult<Self> {
-            match input.literal() {
-                Some((lit, rest)) => {
-                    if lit.to_string().starts_with('/') {
-                        // Doc comment literal which is not a Syn literal
-                        parse_error()
-                    } else {
-                        Ok((Lit::new(lit), rest))
+    impl Parse for Lit {
+        fn parse(input: ParseStream) -> Result<Self> {
+            input.step_cursor(|cursor| {
+                match cursor.literal() {
+                    Some((lit, rest)) => {
+                        if lit.to_string().starts_with('/') {
+                            // Doc comment literal which is not a Syn literal
+                            parse_error()
+                        } else {
+                            Ok((Lit::new(lit), rest))
+                        }
                     }
+                    _ => match cursor.ident() {
+                        Some((ident, rest)) => Ok((
+                            Lit::Bool(LitBool {
+                                value: if ident == "true" {
+                                    true
+                                } else if ident == "false" {
+                                    false
+                                } else {
+                                    return parse_error();
+                                },
+                                span: ident.span(),
+                            }),
+                            rest,
+                        )),
+                        _ => parse_error(),
+                    },
                 }
-                _ => match input.ident() {
-                    Some((ident, rest)) => Ok((
-                        Lit::Bool(LitBool {
-                            value: if ident == "true" {
-                                true
-                            } else if ident == "false" {
-                                false
-                            } else {
-                                return parse_error();
-                            },
-                            span: ident.span(),
-                        }),
-                        rest,
-                    )),
-                    _ => parse_error(),
-                },
-            }
-        }
-
-        fn description() -> Option<&'static str> {
-            Some("literal")
+            })
         }
     }
 
-    impl_synom!(LitStr "string literal" switch!(
-        syn!(Lit),
-        Lit::Str(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitStr {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::Str(lit) => Ok(lit),
+                _ => Err(head.error("expected string literal")),
+            }
+        }
+    }
 
-    impl_synom!(LitByteStr "byte string literal" switch!(
-        syn!(Lit),
-        Lit::ByteStr(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitByteStr {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::ByteStr(lit) => Ok(lit),
+                _ => Err(head.error("expected byte string literal")),
+            }
+        }
+    }
 
-    impl_synom!(LitByte "byte literal" switch!(
-        syn!(Lit),
-        Lit::Byte(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitByte {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::Byte(lit) => Ok(lit),
+                _ => Err(head.error("expected byte literal")),
+            }
+        }
+    }
 
-    impl_synom!(LitChar "character literal" switch!(
-        syn!(Lit),
-        Lit::Char(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitChar {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::Char(lit) => Ok(lit),
+                _ => Err(head.error("expected character literal")),
+            }
+        }
+    }
 
-    impl_synom!(LitInt "integer literal" switch!(
-        syn!(Lit),
-        Lit::Int(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitInt {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::Int(lit) => Ok(lit),
+                _ => Err(head.error("expected integer literal")),
+            }
+        }
+    }
 
-    impl_synom!(LitFloat "floating point literal" switch!(
-        syn!(Lit),
-        Lit::Float(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitFloat {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::Float(lit) => Ok(lit),
+                _ => Err(head.error("expected floating point literal")),
+            }
+        }
+    }
 
-    impl_synom!(LitBool "boolean literal" switch!(
-        syn!(Lit),
-        Lit::Bool(lit) => value!(lit)
-        |
-        _ => reject!()
-    ));
+    impl Parse for LitBool {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let head = input.fork();
+            match input.parse()? {
+                Lit::Bool(lit) => Ok(lit),
+                _ => Err(head.error("expected boolean literal")),
+            }
+        }
+    }
 }
 
 #[cfg(feature = "printing")]
diff --git a/src/lookahead.rs b/src/lookahead.rs
new file mode 100644
index 0000000..29cd2cc
--- /dev/null
+++ b/src/lookahead.rs
@@ -0,0 +1,99 @@
+use std::cell::RefCell;
+
+use proc_macro2::{Delimiter, Span};
+
+use buffer::Cursor;
+use error::{self, Error};
+use span::IntoSpans;
+use token::Token;
+
+/// Support for checking the next token in a stream to decide how to parse.
+///
+/// Use [`ParseStream::lookahead1`] to construct this object.
+///
+/// [`ParseStream::lookahead1`]: struct.ParseBuffer.html#method.lookahead1
+pub struct Lookahead1<'a> {
+    scope: Span,
+    cursor: Cursor<'a>,
+    comparisons: RefCell<Vec<String>>,
+}
+
+impl<'a> Lookahead1<'a> {
+    // Not public API.
+    #[doc(hidden)]
+    pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
+        Lookahead1 {
+            scope: scope,
+            cursor: cursor,
+            comparisons: RefCell::new(Vec::new()),
+        }
+    }
+
+    pub fn peek<T: Peek>(&self, token: T) -> bool {
+        let _ = token;
+        if T::Token::peek(self) {
+            return true;
+        }
+        self.comparisons.borrow_mut().push(T::Token::display());
+        false
+    }
+
+    pub fn error(self) -> Error {
+        let comparisons = self.comparisons.borrow();
+        match comparisons.len() {
+            0 => if self.cursor.eof() {
+                Error::new(self.scope, "unexpected end of input")
+            } else {
+                Error::new(self.cursor.span(), "unexpected token")
+            },
+            1 => {
+                let message = format!("expected {}", comparisons[0]);
+                error::new_at(self.scope, self.cursor, message)
+            }
+            _ => {
+                let join = comparisons.join(", ");
+                let message = format!("expected one of: {}", join);
+                error::new_at(self.scope, self.cursor, message)
+            }
+        }
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn cursor(&self) -> Cursor<'a> {
+        self.cursor
+    }
+}
+
+/// Types that can be parsed by looking at just one token.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+pub trait Peek: private::Sealed {
+    // Not public API.
+    #[doc(hidden)]
+    type Token: Token;
+}
+
+impl<F: FnOnce(TokenMarker) -> T, T: Token> Peek for F {
+    type Token = T;
+}
+
+pub enum TokenMarker {}
+
+impl<S> IntoSpans<S> for TokenMarker {
+    fn into_spans(self) -> S {
+        match self {}
+    }
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn is_delimiter(lookahead: &Lookahead1, delimiter: Delimiter) -> bool {
+    lookahead.cursor.group(delimiter).is_some()
+}
+
+mod private {
+    use super::{Token, TokenMarker};
+    pub trait Sealed {}
+    impl<F: FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
+}
diff --git a/src/mac.rs b/src/mac.rs
index a9219fe..b08c8a1 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -8,8 +8,12 @@
 
 use super::*;
 use proc_macro2::TokenStream;
+#[cfg(feature = "parsing")]
+use proc_macro2::{Delimiter, TokenTree};
 use token::{Brace, Bracket, Paren};
 
+#[cfg(feature = "parsing")]
+use parse::{ParseStream, Result};
 #[cfg(feature = "extra-traits")]
 use std::hash::{Hash, Hasher};
 #[cfg(feature = "extra-traits")]
@@ -67,26 +71,44 @@
 }
 
 #[cfg(feature = "parsing")]
+pub fn parse_delimiter(input: ParseStream) -> Result<(MacroDelimiter, TokenStream)> {
+    input.step_cursor(|cursor| {
+        if let Some((TokenTree::Group(g), rest)) = cursor.token_tree() {
+            let span = g.span();
+            let delimiter = match g.delimiter() {
+                Delimiter::Parenthesis => MacroDelimiter::Paren(Paren(span)),
+                Delimiter::Brace => MacroDelimiter::Brace(Brace(span)),
+                Delimiter::Bracket => MacroDelimiter::Bracket(Bracket(span)),
+                Delimiter::None => {
+                    return Err(cursor.error("expected delimiter"));
+                }
+            };
+            Ok(((delimiter, g.stream().clone()), rest))
+        } else {
+            Err(cursor.error("expected delimiter"))
+        }
+    })
+}
+
+#[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
 
-    use synom::Synom;
+    use parse::{Parse, ParseStream, Result};
 
-    impl Synom for Macro {
-        named!(parse -> Self, do_parse!(
-            what: call!(Path::parse_mod_style) >>
-            bang: punct!(!) >>
-            body: call!(tt::delimited) >>
-            (Macro {
-                path: what,
-                bang_token: bang,
-                delimiter: body.0,
-                tts: body.1,
+    impl Parse for Macro {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let tts;
+            Ok(Macro {
+                path: input.call(Path::parse_mod_style)?,
+                bang_token: input.parse()?,
+                delimiter: {
+                    let (delimiter, content) = parse_delimiter(input)?;
+                    tts = content;
+                    delimiter
+                },
+                tts: tts,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("macro invocation")
         }
     }
 }
diff --git a/src/macros.rs b/src/macros.rs
index f4e7d0a..5966e38 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -179,10 +179,7 @@
     ($($rest:tt)*) => (ast_struct! { $($rest)* });
 }
 
-#[cfg(all(
-    feature = "parsing",
-    any(feature = "full", feature = "derive")
-))]
+#[cfg(all(feature = "parsing", feature = "full"))]
 macro_rules! impl_synom {
     ($t:ident $description:tt $($parser:tt)+) => {
         impl Synom for $t {
diff --git a/src/next.rs b/src/next.rs
new file mode 100644
index 0000000..e5b902c
--- /dev/null
+++ b/src/next.rs
@@ -0,0 +1,82 @@
+use std::cell::Cell;
+use std::rc::Rc;
+use std::str::FromStr;
+
+use buffer::TokenBuffer;
+#[cfg(feature = "proc-macro")]
+use proc_macro;
+use proc_macro2::{self, Span};
+
+use error::Result;
+use parse::{Parse, ParseBuffer};
+
+/// Parse tokens of source code into the chosen syntax tree node.
+#[cfg(feature = "proc-macro")]
+pub fn parse<T: Parse>(input: proc_macro::TokenStream) -> Result<T> {
+    parse2(proc_macro2::TokenStream::from(input))
+}
+
+/// Parse a proc-macro2 token stream into the chosen syntax tree node.
+pub fn parse2<T: Parse>(input: proc_macro2::TokenStream) -> Result<T> {
+    let buf = TokenBuffer::new2(input);
+    let unexpected = Rc::new(Cell::new(None));
+    let state = ParseBuffer::new(Span::call_site(), buf.begin(), unexpected);
+    let node = T::parse(&state)?;
+    state.check_unexpected()?;
+    Ok(node)
+}
+
+/// Parse a string of Rust code into the chosen syntax tree node.
+pub fn parse_str<T: Parse>(input: &str) -> Result<T> {
+    let tokens = proc_macro2::TokenStream::from_str(input)?;
+    parse2(tokens)
+}
+
+/// Parse the input TokenStream of a macro, triggering a compile error if the
+/// tokens fail to parse.
+///
+/// # Intended usage
+///
+/// ```rust
+/// # extern crate proc_macro;
+/// # extern crate syn;
+/// #
+/// use proc_macro::TokenStream;
+/// use syn::parse_macro_input;
+/// use syn::parse::{Parse, ParseStream, Result};
+///
+/// struct MyMacroInput {
+///     /* ... */
+/// }
+///
+/// impl Parse for MyMacroInput {
+///     fn parse(input: ParseStream) -> Result<Self> {
+///         /* ... */
+/// #       Ok(MyMacroInput {})
+///     }
+/// }
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro]
+/// # };
+/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
+///     let input = parse_macro_input!(tokens as MyMacroInput);
+///
+///     /* ... */
+/// #   "".parse().unwrap()
+/// }
+/// #
+/// # fn main() {}
+/// ```
+#[cfg(feature = "proc-macro")]
+#[macro_export]
+macro_rules! parse_macro_input {
+    ($tokenstream:ident as $ty:ty) => {
+        match $crate::next::parse::<$ty>($tokenstream) {
+            $crate::export::Ok(data) => data,
+            $crate::export::Err(err) => {
+                return $crate::export::TokenStream::from(err.into_compile_error());
+            }
+        };
+    };
+}
diff --git a/src/op.rs b/src/op.rs
index a5188d0..c8f619d 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -91,82 +91,94 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use synom::Synom;
+
+    use parse::{Parse, ParseStream, Result};
 
     impl BinOp {
-        named!(pub parse_binop -> Self, alt!(
-            punct!(&&) => { BinOp::And }
-            |
-            punct!(||) => { BinOp::Or }
-            |
-            punct!(<<) => { BinOp::Shl }
-            |
-            punct!(>>) => { BinOp::Shr }
-            |
-            punct!(==) => { BinOp::Eq }
-            |
-            punct!(<=) => { BinOp::Le }
-            |
-            punct!(!=) => { BinOp::Ne }
-            |
-            punct!(>=) => { BinOp::Ge }
-            |
-            punct!(+) => { BinOp::Add }
-            |
-            punct!(-) => { BinOp::Sub }
-            |
-            punct!(*) => { BinOp::Mul }
-            |
-            punct!(/) => { BinOp::Div }
-            |
-            punct!(%) => { BinOp::Rem }
-            |
-            punct!(^) => { BinOp::BitXor }
-            |
-            punct!(&) => { BinOp::BitAnd }
-            |
-            punct!(|) => { BinOp::BitOr }
-            |
-            punct!(<) => { BinOp::Lt }
-            |
-            punct!(>) => { BinOp::Gt }
-        ));
+        pub fn parse_binop(input: ParseStream) -> Result<Self> {
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Token![&&]) {
+                input.parse().map(BinOp::And)
+            } else if lookahead.peek(Token![||]) {
+                input.parse().map(BinOp::Or)
+            } else if lookahead.peek(Token![<<]) {
+                input.parse().map(BinOp::Shl)
+            } else if lookahead.peek(Token![>>]) {
+                input.parse().map(BinOp::Shr)
+            } else if lookahead.peek(Token![==]) {
+                input.parse().map(BinOp::Eq)
+            } else if lookahead.peek(Token![<=]) {
+                input.parse().map(BinOp::Le)
+            } else if lookahead.peek(Token![!=]) {
+                input.parse().map(BinOp::Ne)
+            } else if lookahead.peek(Token![>=]) {
+                input.parse().map(BinOp::Ge)
+            } else if lookahead.peek(Token![+]) {
+                input.parse().map(BinOp::Add)
+            } else if lookahead.peek(Token![-]) {
+                input.parse().map(BinOp::Sub)
+            } else if lookahead.peek(Token![*]) {
+                input.parse().map(BinOp::Mul)
+            } else if lookahead.peek(Token![/]) {
+                input.parse().map(BinOp::Div)
+            } else if lookahead.peek(Token![%]) {
+                input.parse().map(BinOp::Rem)
+            } else if lookahead.peek(Token![^]) {
+                input.parse().map(BinOp::BitXor)
+            } else if lookahead.peek(Token![&]) {
+                input.parse().map(BinOp::BitAnd)
+            } else if lookahead.peek(Token![|]) {
+                input.parse().map(BinOp::BitOr)
+            } else if lookahead.peek(Token![<]) {
+                input.parse().map(BinOp::Lt)
+            } else if lookahead.peek(Token![>]) {
+                input.parse().map(BinOp::Gt)
+            } else {
+                Err(lookahead.error())
+            }
+        }
 
         #[cfg(feature = "full")]
-        named!(pub parse_assign_op -> Self, alt!(
-            punct!(+=) => { BinOp::AddEq }
-            |
-            punct!(-=) => { BinOp::SubEq }
-            |
-            punct!(*=) => { BinOp::MulEq }
-            |
-            punct!(/=) => { BinOp::DivEq }
-            |
-            punct!(%=) => { BinOp::RemEq }
-            |
-            punct!(^=) => { BinOp::BitXorEq }
-            |
-            punct!(&=) => { BinOp::BitAndEq }
-            |
-            punct!(|=) => { BinOp::BitOrEq }
-            |
-            punct!(<<=) => { BinOp::ShlEq }
-            |
-            punct!(>>=) => { BinOp::ShrEq }
-        ));
+        pub fn parse_assign_op(input: ParseStream) -> Result<Self> {
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Token![+=]) {
+                input.parse().map(BinOp::AddEq)
+            } else if lookahead.peek(Token![-=]) {
+                input.parse().map(BinOp::SubEq)
+            } else if lookahead.peek(Token![*=]) {
+                input.parse().map(BinOp::MulEq)
+            } else if lookahead.peek(Token![/=]) {
+                input.parse().map(BinOp::DivEq)
+            } else if lookahead.peek(Token![%=]) {
+                input.parse().map(BinOp::RemEq)
+            } else if lookahead.peek(Token![^=]) {
+                input.parse().map(BinOp::BitXorEq)
+            } else if lookahead.peek(Token![&=]) {
+                input.parse().map(BinOp::BitAndEq)
+            } else if lookahead.peek(Token![|=]) {
+                input.parse().map(BinOp::BitOrEq)
+            } else if lookahead.peek(Token![<<=]) {
+                input.parse().map(BinOp::ShlEq)
+            } else if lookahead.peek(Token![>>=]) {
+                input.parse().map(BinOp::ShrEq)
+            } else {
+                Err(lookahead.error())
+            }
+        }
     }
 
-    impl Synom for UnOp {
-        named!(parse -> Self, alt!(
-            punct!(*) => { UnOp::Deref }
-            |
-            punct!(!) => { UnOp::Not }
-            |
-            punct!(-) => { UnOp::Neg }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("unary operator: `*`, `!`, or `-`")
+    impl Parse for UnOp {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Token![*]) {
+                input.parse().map(UnOp::Deref)
+            } else if lookahead.peek(Token![!]) {
+                input.parse().map(UnOp::Not)
+            } else if lookahead.peek(Token![-]) {
+                input.parse().map(UnOp::Neg)
+            } else {
+                Err(lookahead.error())
+            }
         }
     }
 }
diff --git a/src/parse.rs b/src/parse.rs
new file mode 100644
index 0000000..64f972d
--- /dev/null
+++ b/src/parse.rs
@@ -0,0 +1,239 @@
+//! 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 std::rc::Rc;
+
+use proc_macro2::{Ident, Span};
+
+use buffer::Cursor;
+use error;
+use punctuated::Punctuated;
+use synom::PResult;
+use token::Token;
+
+pub use error::{Error, Result};
+pub use 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.
+pub struct ParseBuffer<'a> {
+    scope: Span,
+    cell: Cell<Cursor<'static>>,
+    marker: PhantomData<Cursor<'a>>,
+    unexpected: Rc<Cell<Option<Span>>>,
+}
+
+impl<'a> Drop for ParseBuffer<'a> {
+    fn drop(&mut self) {
+        if !self.is_empty() && self.unexpected.get().is_none() {
+            self.unexpected.set(Some(self.cursor().span()));
+        }
+    }
+}
+
+// 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) }
+    }
+
+    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>, unexpected: Rc<Cell<Option<Span>>>) -> Self {
+        let extend = unsafe { mem::transmute::<Cursor<'a>, Cursor<'static>>(cursor) };
+        ParseBuffer {
+            scope: scope,
+            cell: Cell::new(extend),
+            marker: PhantomData,
+            unexpected: unexpected,
+        }
+    }
+
+    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> {
+        self.check_unexpected()?;
+        T::parse(self)
+    }
+
+    pub fn call<T>(&self, function: fn(ParseStream) -> Result<T>) -> Result<T> {
+        function(self)
+    }
+
+    pub fn peek<T: Peek>(&self, token: T) -> bool {
+        self.lookahead1().peek(token)
+    }
+
+    pub fn peek2<T: Peek>(&self, token: T) -> bool {
+        if self.is_empty() {
+            return false;
+        }
+        let ahead = self.fork();
+        ahead
+            .step_cursor(|cursor| Ok(cursor.token_tree().unwrap()))
+            .unwrap();
+        ahead.peek(token)
+    }
+
+    pub fn peek3<T: Peek>(&self, token: T) -> bool {
+        if self.is_empty() {
+            return false;
+        }
+        let ahead = self.fork();
+        ahead
+            .step_cursor(|cursor| Ok(cursor.token_tree().unwrap()))
+            .unwrap();
+        ahead
+            .step_cursor(|cursor| Ok(cursor.token_tree().unwrap()))
+            .unwrap();
+        ahead.peek(token)
+    }
+
+    pub fn parse_terminated<T, P: Parse>(
+        &self,
+        parser: fn(ParseStream) -> Result<T>,
+    ) -> Result<Punctuated<T, P>> {
+        Punctuated::parse_terminated2(self, parser)
+    }
+
+    pub fn fork(&self) -> Self {
+        ParseBuffer {
+            scope: self.scope,
+            cell: self.cell.clone(),
+            marker: PhantomData,
+            // Not the parent's unexpected. Nothing cares whether the clone
+            // parses all the way.
+            unexpected: Rc::new(Cell::new(None)),
+        }
+    }
+
+    pub fn error<T: Display>(&self, message: T) -> Error {
+        error::new_at(self.scope, self.cursor(), message)
+    }
+
+    // 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>)>,
+    {
+        self.check_unexpected()?;
+        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),
+        }
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn parse_synom<T>(&self, parse: fn(Cursor) -> PResult<T>) -> Result<T> {
+        self.step_cursor(|step| parse(step.cursor))
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn get_unexpected(&self) -> Rc<Cell<Option<Span>>> {
+        self.unexpected.clone()
+    }
+
+    // Not public API.
+    #[doc(hidden)]
+    pub fn check_unexpected(&self) -> Result<()> {
+        match self.unexpected.get() {
+            Some(span) => Err(Error::new(span, "unexpected token")),
+            None => Ok(()),
+        }
+    }
+}
+
+impl Parse for Ident {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| {
+            if let Some((ident, rest)) = cursor.ident() {
+                match ident.to_string().as_str() {
+                    "_"
+                    // Based on https://doc.rust-lang.org/grammar.html#keywords
+                    // and https://github.com/rust-lang/rfcs/blob/master/text/2421-unreservations-2018.md
+                    | "abstract" | "as" | "become" | "box" | "break" | "const"
+                    | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
+                    | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
+                    | "mod" | "move" | "mut" | "override" | "priv" | "proc" | "pub"
+                    | "ref" | "return" | "Self" | "self" | "static" | "struct"
+                    | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
+                    | "virtual" | "where" | "while" | "yield" => {}
+                    _ => return Ok((ident, rest)),
+                }
+            }
+            Err(cursor.error("expected identifier"))
+        })
+    }
+}
+
+impl<T: Parse> Parse for Box<T> {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.parse().map(Box::new)
+    }
+}
+
+impl<T: Parse + Token> Parse for Option<T> {
+    fn parse(input: ParseStream) -> Result<Self> {
+        if T::peek(&input.lookahead1()) {
+            Ok(Some(input.parse()?))
+        } else {
+            Ok(None)
+        }
+    }
+}
diff --git a/src/parse_quote.rs b/src/parse_quote.rs
index ec8ef5a..08ba14b 100644
--- a/src/parse_quote.rs
+++ b/src/parse_quote.rs
@@ -152,9 +152,9 @@
 #[cfg(any(feature = "full", feature = "derive"))]
 impl ParseQuote for Attribute {
     named!(parse -> Self, alt!(
-        call!(Attribute::parse_outer)
+        call!(Attribute::old_parse_outer)
         |
-        call!(Attribute::parse_inner)
+        call!(Attribute::old_parse_inner)
     ));
 
     fn description() -> Option<&'static str> {
diff --git a/src/parsers.rs b/src/parsers.rs
index 400c0ca..c3c638b 100644
--- a/src/parsers.rs
+++ b/src/parsers.rs
@@ -1417,7 +1417,7 @@
 // Not public API.
 #[doc(hidden)]
 #[macro_export]
-macro_rules! grouped {
+macro_rules! old_grouped {
     ($i:expr, $submac:ident!( $($args:tt)* )) => {
         $crate::token::Group::parse($i, |i| $submac!(i, $($args)*))
     };
@@ -1426,3 +1426,19 @@
         grouped!($i, call!($f));
     };
 }
+
+macro_rules! shim {
+    ($i:expr, $parser:expr $(, $args:expr)*) => {{
+        let unexpected = ::std::rc::Rc::new(::std::cell::Cell::new(None));
+        let state = ::parse::ParseBuffer::new(::proc_macro2::Span::call_site(), $i, unexpected);
+        match $parser(&state $(, $args)*) {
+            Ok(node) => {
+                match state.check_unexpected() {
+                    Ok(()) => Ok((node, state.cursor())),
+                    Err(err) => Err(err),
+                }
+            }
+            Err(err) => Err(err),
+        }
+    }};
+}
diff --git a/src/path.rs b/src/path.rs
index a848944..c2ad34a 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -227,130 +227,160 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use synom::Synom;
+    use parse::{Parse, ParseStream, Result};
+    use synom::ext::IdentExt;
 
-    impl Synom for Path {
-        named!(parse -> Self, do_parse!(
-            colon: option!(punct!(::)) >>
-            segments: call!(Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty) >>
-            cond_reduce!(segments.first().map_or(true, |seg| seg.value().ident != "dyn")) >>
-            (Path {
-                leading_colon: colon,
-                segments: segments,
+    impl Parse for Path {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![dyn]) {
+                return Err(input.error("expected path"));
+            }
+
+            Ok(Path {
+                leading_colon: input.parse()?,
+                segments: input.parse_synom(Punctuated::parse_separated_nonempty)?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("path")
         }
     }
 
-    #[cfg(not(feature = "full"))]
-    impl Synom for GenericArgument {
-        named!(parse -> Self, alt!(
-            call!(ty_no_eq_after) => { GenericArgument::Type }
-            |
-            syn!(Lifetime) => { GenericArgument::Lifetime }
-            |
-            syn!(Binding) => { GenericArgument::Binding }
-        ));
-    }
+    impl Parse for GenericArgument {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Lifetime) && !input.peek3(Token![+]) {
+                return Ok(GenericArgument::Lifetime(input.parse()?));
+            }
 
-    #[cfg(feature = "full")]
-    impl Synom for GenericArgument {
-        named!(parse -> Self, alt!(
-            call!(ty_no_eq_after) => { GenericArgument::Type }
-            |
-            syn!(Lifetime) => { GenericArgument::Lifetime }
-            |
-            syn!(Binding) => { GenericArgument::Binding }
-            |
-            syn!(ExprLit) => { |l| GenericArgument::Const(Expr::Lit(l)) }
-            |
-            syn!(ExprBlock) => { |b| GenericArgument::Const(Expr::Block(b)) }
-        ));
+            if input.peek(Ident) && input.peek2(Token![=]) {
+                return Ok(GenericArgument::Binding(input.parse()?));
+            }
 
-        fn description() -> Option<&'static str> {
-            Some("generic argument")
+            #[cfg(feature = "full")]
+            {
+                if input.peek(Lit) {
+                    let lit = input.parse_synom(ExprLit::parse)?;
+                    return Ok(GenericArgument::Const(Expr::Lit(lit)));
+                }
+
+                if input.peek(token::Brace) {
+                    let block = input.parse_synom(ExprBlock::parse)?;
+                    return Ok(GenericArgument::Const(Expr::Block(block)));
+                }
+            }
+
+            Ok(GenericArgument::Type(input.parse_synom(ty_no_eq_after)?))
         }
     }
 
-    impl Synom for AngleBracketedGenericArguments {
-        named!(parse -> Self, do_parse!(
-            colon2: option!(punct!(::)) >>
-            lt: punct!(<) >>
-            args: call!(Punctuated::parse_terminated) >>
-            gt: punct!(>) >>
-            (AngleBracketedGenericArguments {
-                colon2_token: colon2,
-                lt_token: lt,
-                args: args,
-                gt_token: gt,
+    impl Parse for AngleBracketedGenericArguments {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(AngleBracketedGenericArguments {
+                colon2_token: input.parse()?,
+                lt_token: input.parse()?,
+                args: {
+                    let mut args = Punctuated::new();
+                    loop {
+                        if input.peek(Token![>]) {
+                            break;
+                        }
+                        let value = input.parse()?;
+                        args.push_value(value);
+                        if input.peek(Token![>]) {
+                            break;
+                        }
+                        let punct = input.parse()?;
+                        args.push_punct(punct);
+                    }
+                    args
+                },
+                gt_token: input.parse()?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("angle bracketed generic arguments")
         }
     }
 
-    impl Synom for ParenthesizedGenericArguments {
-        named!(parse -> Self, do_parse!(
-            data: parens!(Punctuated::parse_terminated) >>
-            output: call!(ReturnType::without_plus) >>
-            (ParenthesizedGenericArguments {
-                paren_token: data.0,
-                inputs: data.1,
-                output: output,
+    impl Parse for ParenthesizedGenericArguments {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(ParenthesizedGenericArguments {
+                paren_token: parenthesized!(content in input),
+                inputs: content.parse_synom(Punctuated::parse_terminated)?,
+                output: input.call(ReturnType::without_plus)?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("parenthesized generic arguments: `Foo(A, B, ..) -> T`")
         }
     }
 
-    impl Synom for PathSegment {
-        named!(parse -> Self, alt!(
-            do_parse!(
-                ident: syn!(Ident) >>
-                arguments: syn!(AngleBracketedGenericArguments) >>
-                (PathSegment {
+    impl Parse for PathSegment {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![super])
+                || input.peek(Token![self])
+                || input.peek(Token![Self])
+                || input.peek(Token![crate])
+                || input.peek(Token![extern])
+            {
+                let ident = input.parse_synom(Ident::parse_any)?;
+                return Ok(PathSegment::from(ident));
+            }
+
+            let ident = input.parse()?;
+            if input.peek(Token![<]) && !input.peek(Token![<=])
+                || input.peek(Token![::]) && input.peek3(Token![<])
+            {
+                Ok(PathSegment {
                     ident: ident,
-                    arguments: PathArguments::AngleBracketed(arguments),
+                    arguments: PathArguments::AngleBracketed(input.parse()?),
                 })
-            )
-            |
-            mod_style_path_segment
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("path segment")
+            } else {
+                Ok(PathSegment::from(ident))
+            }
         }
     }
 
-    impl Synom for Binding {
-        named!(parse -> Self, do_parse!(
-            id: syn!(Ident) >>
-            eq: punct!(=) >>
-            ty: syn!(Type) >>
-            (Binding {
-                ident: id,
-                eq_token: eq,
-                ty: ty,
+    impl Parse for Binding {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(Binding {
+                ident: input.parse()?,
+                eq_token: input.parse()?,
+                ty: input.parse()?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("associated type binding")
         }
     }
 
     impl Path {
-        named!(pub parse_mod_style -> Self, do_parse!(
+        pub fn parse_mod_style(input: ParseStream) -> Result<Self> {
+            Ok(Path {
+                leading_colon: input.parse()?,
+                segments: {
+                    let mut segments = Punctuated::new();
+                    loop {
+                        if !input.peek(Ident)
+                            && !input.peek(Token![super])
+                            && !input.peek(Token![self])
+                            && !input.peek(Token![Self])
+                            && !input.peek(Token![crate])
+                            && !input.peek(Token![extern])
+                        {
+                            break;
+                        }
+                        let ident = Ident::parse_any2(input)?;
+                        segments.push_value(PathSegment::from(ident));
+                        if !input.peek(Token![::]) {
+                            break;
+                        }
+                        let punct = input.parse()?;
+                        segments.push_punct(punct);
+                    }
+                    if segments.is_empty() {
+                        return Err(input.error("expected path"));
+                    } else if segments.trailing_punct() {
+                        return Err(input.error("expected path segment"));
+                    }
+                    segments
+                },
+            })
+        }
+
+        named!(pub old_parse_mod_style -> Self, do_parse!(
             colon: option!(punct!(::)) >>
             segments: call!(Punctuated::parse_separated_nonempty_with,
-                            mod_style_path_segment) >>
+                            old_mod_style_path_segment) >>
             (Path {
                 leading_colon: colon,
                 segments: segments,
@@ -358,7 +388,30 @@
         ));
     }
 
-    named!(pub mod_style_path_segment -> PathSegment, alt!(
+    // FIXME
+    /*
+    pub fn mod_style_path_segment(input: ParseStream) -> Result<PathSegment> {
+        let lookahead = input.lookahead1();
+        let ident = if lookahead.peek(Ident) {
+            input.parse()?
+        } else if lookahead.peek(Token![super]) {
+            Ident::from(input.parse::<Token![super]>()?)
+        } else if lookahead.peek(Token![self]) {
+            Ident::from(input.parse::<Token![self]>()?)
+        } else if lookahead.peek(Token![Self]) {
+            Ident::from(input.parse::<Token![Self]>()?)
+        } else if lookahead.peek(Token![crate]) {
+            Ident::from(input.parse::<Token![crate]>()?)
+        } else if lookahead.peek(Token![extern]) {
+            Ident::from(input.parse::<Token![extern]>()?)
+        } else {
+            return Err(lookahead.error());
+        };
+        Ok(PathSegment::from(ident))
+    }
+    */
+
+    named!(pub old_mod_style_path_segment -> PathSegment, alt!(
         syn!(Ident) => { Into::into }
         |
         keyword!(super) => { Into::into }
@@ -372,44 +425,6 @@
         keyword!(extern) => { Into::into }
     ));
 
-    named!(pub qpath -> (Option<QSelf>, Path), alt!(
-        map!(syn!(Path), |p| (None, p))
-        |
-        do_parse!(
-            lt: punct!(<) >>
-            this: syn!(Type) >>
-            path: option!(tuple!(keyword!(as), syn!(Path))) >>
-            gt: punct!(>) >>
-            colon2: punct!(::) >>
-            rest: call!(Punctuated::parse_separated_nonempty) >>
-            ({
-                let (pos, as_, path) = match path {
-                    Some((as_, mut path)) => {
-                        let pos = path.segments.len();
-                        path.segments.push_punct(colon2);
-                        path.segments.extend(rest.into_pairs());
-                        (pos, Some(as_), path)
-                    }
-                    None => {
-                        (0, None, Path {
-                            leading_colon: Some(colon2),
-                            segments: rest,
-                        })
-                    }
-                };
-                (Some(QSelf {
-                    lt_token: lt,
-                    ty: Box::new(this),
-                    position: pos,
-                    as_token: as_,
-                    gt_token: gt,
-                }), path)
-            })
-        )
-        |
-        map!(keyword!(self), |s| (None, s.into()))
-    ));
-
     named!(pub ty_no_eq_after -> Type, do_parse!(
         ty: syn!(Type) >>
         not!(punct!(=)) >>
diff --git a/src/punctuated.rs b/src/punctuated.rs
index b4a0b3f..171e549 100644
--- a/src/punctuated.rs
+++ b/src/punctuated.rs
@@ -40,6 +40,8 @@
 #[cfg(feature = "parsing")]
 use buffer::Cursor;
 #[cfg(feature = "parsing")]
+use parse::{Parse, ParseStream, Result};
+#[cfg(feature = "parsing")]
 use parse_error;
 #[cfg(feature = "parsing")]
 use synom::{PResult, Synom};
@@ -773,6 +775,34 @@
     }
 }
 
+#[cfg(feature = "parsing")]
+impl<T, P> Punctuated<T, P>
+where
+    P: Parse,
+{
+    pub fn parse_terminated2(
+        input: ParseStream,
+        parser: fn(ParseStream) -> Result<T>,
+    ) -> Result<Self> {
+        let mut res = Punctuated::new();
+
+        loop {
+            if input.is_empty() {
+                break;
+            }
+            let value = parser(input)?;
+            res.push_value(value);
+            if input.is_empty() {
+                break;
+            }
+            let punct = input.parse()?;
+            res.push_punct(punct);
+        }
+
+        Ok(res)
+    }
+}
+
 #[cfg(feature = "printing")]
 mod printing {
     use super::*;
diff --git a/src/span.rs b/src/span.rs
new file mode 100644
index 0000000..fb9e7ef
--- /dev/null
+++ b/src/span.rs
@@ -0,0 +1,69 @@
+use proc_macro2::Span;
+
+pub trait IntoSpans<S> {
+    // Not public API.
+    #[doc(hidden)]
+    fn into_spans(self) -> S;
+}
+
+impl IntoSpans<[Span; 1]> for Span {
+    fn into_spans(self) -> [Span; 1] {
+        [self]
+    }
+}
+
+impl IntoSpans<[Span; 2]> for Span {
+    fn into_spans(self) -> [Span; 2] {
+        [self, self]
+    }
+}
+
+impl IntoSpans<[Span; 3]> for Span {
+    fn into_spans(self) -> [Span; 3] {
+        [self, self, self]
+    }
+}
+
+impl IntoSpans<Self> for [Span; 1] {
+    fn into_spans(self) -> Self {
+        self
+    }
+}
+
+impl IntoSpans<Self> for [Span; 2] {
+    fn into_spans(self) -> Self {
+        self
+    }
+}
+
+impl IntoSpans<Self> for [Span; 3] {
+    fn into_spans(self) -> Self {
+        self
+    }
+}
+
+#[cfg(feature = "parsing")]
+pub trait FromSpans: Sized {
+    fn from_spans(spans: &[Span]) -> Self;
+}
+
+#[cfg(feature = "parsing")]
+impl FromSpans for [Span; 1] {
+    fn from_spans(spans: &[Span]) -> Self {
+        [spans[0]]
+    }
+}
+
+#[cfg(feature = "parsing")]
+impl FromSpans for [Span; 2] {
+    fn from_spans(spans: &[Span]) -> Self {
+        [spans[0], spans[1]]
+    }
+}
+
+#[cfg(feature = "parsing")]
+impl FromSpans for [Span; 3] {
+    fn from_spans(spans: &[Span]) -> Self {
+        [spans[0], spans[1], spans[2]]
+    }
+}
diff --git a/src/spanned.rs b/src/spanned.rs
index 9372dce..6e2215d 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -85,7 +85,8 @@
 /// tree node.
 ///
 /// This trait is automatically implemented for all types that implement
-/// [`ToTokens`] from the `quote` crate.
+/// [`ToTokens`] from the `quote` crate. It is sealed and cannot be implemented
+/// outside of the Syn crate other than by implementing `ToTokens`.
 ///
 /// [`ToTokens`]: https://docs.rs/quote/0.4/quote/trait.ToTokens.html
 ///
@@ -95,7 +96,7 @@
 ///
 /// *This trait is available if Syn is built with both the `"parsing"` and
 /// `"printing"` features.*
-pub trait Spanned {
+pub trait Spanned: private::Sealed {
     /// Returns a `Span` covering the complete contents of this syntax tree
     /// node, or [`Span::call_site()`] if this node is empty.
     ///
@@ -103,6 +104,12 @@
     fn span(&self) -> Span;
 }
 
+mod private {
+    use quote::ToTokens;
+    pub trait Sealed {}
+    impl<T: ToTokens> Sealed for T {}
+}
+
 impl<T> Spanned for T
 where
     T: ToTokens,
diff --git a/src/synom.rs b/src/synom.rs
index f3454eb..035b770 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.
@@ -105,7 +105,7 @@
 //!
 //! #     let tokens = TokenStream::new().into();
 //! // Parse zero or more outer attributes but not inner attributes.
-//! named!(outer_attrs -> Vec<Attribute>, many0!(Attribute::parse_outer));
+//! named!(outer_attrs -> Vec<Attribute>, many0!(Attribute::old_parse_outer));
 //! let attrs = outer_attrs.parse(tokens)?;
 //! #
 //! #     Ok(())
@@ -150,17 +150,21 @@
 //!
 //! *This module is available if Syn is built with the `"parsing"` feature.*
 
+use std::cell::Cell;
+use std::rc::Rc;
+
 #[cfg(all(
     not(all(target_arch = "wasm32", target_os = "unknown")),
     feature = "proc-macro"
 ))]
 use proc_macro;
-use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, TokenStream, TokenTree};
+use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
 
 use error::parse_error;
-pub use error::{PResult, ParseError};
+pub use error::{Error, PResult};
 
 use buffer::{Cursor, TokenBuffer};
+use parse::{Parse, ParseBuffer, ParseStream, Result};
 
 /// Parsing interface implemented by all types that can be parsed in a default
 /// way from a token stream.
@@ -207,97 +211,61 @@
     }
 }
 
-impl Synom for TokenStream {
+impl<T: Parse> Synom for T {
     fn parse(input: Cursor) -> PResult<Self> {
-        Ok((input.token_stream(), Cursor::empty()))
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("arbitrary token stream")
+        let unexpected = Rc::new(Cell::new(None));
+        let state = ParseBuffer::new(Span::call_site(), input, unexpected);
+        let node = <T as Parse>::parse(&state)?;
+        state.check_unexpected()?;
+        Ok((node, state.cursor()))
     }
 }
 
-impl Synom for TokenTree {
-    fn parse(input: Cursor) -> PResult<Self> {
-        match input.token_tree() {
+impl Parse for TokenStream {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
+    }
+}
+
+impl Parse for TokenTree {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| match cursor.token_tree() {
             Some((tt, rest)) => Ok((tt, rest)),
-            None => parse_error(),
-        }
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("token tree")
+            None => Err(cursor.error("expected token tree")),
+        })
     }
 }
 
-impl Synom for Group {
-    fn parse(input: Cursor) -> PResult<Self> {
-        for delim in &[Delimiter::Parenthesis, Delimiter::Brace, Delimiter::Bracket] {
-            if let Some((inside, span, rest)) = input.group(*delim) {
-                let mut group = Group::new(*delim, inside.token_stream());
-                group.set_span(span);
-                return Ok((group, rest));
+impl Parse for Group {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| {
+            for delim in &[Delimiter::Parenthesis, Delimiter::Brace, Delimiter::Bracket] {
+                if let Some((inside, span, rest)) = cursor.group(*delim) {
+                    let mut group = Group::new(*delim, inside.token_stream());
+                    group.set_span(span);
+                    return Ok((group, rest));
+                }
             }
-        }
-        parse_error()
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("group token")
+            Err(cursor.error("expected group token"))
+        })
     }
 }
 
-impl Synom for Ident {
-    fn parse(input: Cursor) -> PResult<Self> {
-        let (ident, rest) = match input.ident() {
-            Some(ident) => ident,
-            _ => return parse_error(),
-        };
-        match &ident.to_string()[..] {
-            "_"
-            // Based on https://doc.rust-lang.org/grammar.html#keywords
-            // and https://github.com/rust-lang/rfcs/blob/master/text/2421-unreservations-2018.md
-            | "abstract" | "as" | "become" | "box" | "break" | "const"
-            | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
-            | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
-            | "mod" | "move" | "mut" | "override" | "priv" | "proc" | "pub"
-            | "ref" | "return" | "Self" | "self" | "static" | "struct"
-            | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
-            | "virtual" | "where" | "while" | "yield" => return parse_error(),
-            _ => {}
-        }
-
-        Ok((ident, rest))
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("identifier")
-    }
-}
-
-impl Synom for Punct {
-    fn parse(input: Cursor) -> PResult<Self> {
-        match input.punct() {
+impl Parse for Punct {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| match cursor.punct() {
             Some((punct, rest)) => Ok((punct, rest)),
-            None => parse_error(),
-        }
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("punctuation token")
+            None => Err(cursor.error("expected punctuation token")),
+        })
     }
 }
 
-impl Synom for Literal {
-    fn parse(input: Cursor) -> PResult<Self> {
-        match input.literal() {
+impl Parse for Literal {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| match cursor.literal() {
             Some((literal, rest)) => Ok((literal, rest)),
-            None => parse_error(),
-        }
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("literal token")
+            None => Err(cursor.error("expected literal token")),
+        })
     }
 }
 
@@ -312,7 +280,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>;
 
     /// Parse tokens of source code into the chosen syntax tree node.
     ///
@@ -322,7 +290,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> {
         self.parse2(tokens.into())
     }
 
@@ -332,10 +300,13 @@
     ///
     /// 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> {
         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",
+            )),
         }
     }
 }
@@ -346,16 +317,16 @@
 {
     type Output = T;
 
-    fn parse2(self, tokens: TokenStream) -> Result<T, ParseError> {
+    fn parse2(self, tokens: TokenStream) -> Result<T> {
         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"))
         }
     }
 }
@@ -367,6 +338,8 @@
     use super::*;
     use proc_macro2::Ident;
 
+    use parse::{ParseStream, Result};
+
     /// Additional parsing methods for `Ident`.
     ///
     /// This trait is sealed and cannot be implemented for types outside of Syn.
@@ -401,12 +374,21 @@
         /// # fn main() {}
         /// ```
         fn parse_any(input: Cursor) -> PResult<Self>;
+
+        fn parse_any2(input: ParseStream) -> Result<Self>;
     }
 
     impl IdentExt for Ident {
         fn parse_any(input: Cursor) -> PResult<Self> {
             input.ident().map_or_else(parse_error, Ok)
         }
+
+        fn parse_any2(input: ParseStream) -> Result<Self> {
+            input.step_cursor(|cursor| match cursor.ident() {
+                Some((ident, rest)) => Ok((ident, rest)),
+                None => Err(cursor.error("expected ident")),
+            })
+        }
     }
 
     mod private {
diff --git a/src/token.rs b/src/token.rs
index 0fe8c4d..9f9b904 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -77,7 +77,7 @@
 //! #   use super::SynItemStatic as ItemStatic;
 //! #
 //! #   named!(parse -> ItemStatic, do_parse!(
-//!         attrs: many0!(Attribute::parse_outer) >>
+//!         attrs: many0!(Attribute::old_parse_outer) >>
 //!         vis: syn!(Visibility) >>
 //!         static_token: keyword!(static) >>
 //!         mutability: option!(keyword!(mut)) >>
@@ -97,418 +97,519 @@
 //! # fn main() {}
 //! ```
 
+use std;
+#[cfg(feature = "parsing")]
+use std::cell::Cell;
+#[cfg(feature = "extra-traits")]
+use std::cmp;
+#[cfg(feature = "extra-traits")]
+use std::fmt::{self, Debug};
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+#[cfg(feature = "parsing")]
+use std::rc::Rc;
+
+#[cfg(feature = "parsing")]
+use proc_macro2::Delimiter;
+#[cfg(any(feature = "printing", feature = "parsing"))]
+use proc_macro2::Spacing;
 use proc_macro2::{Ident, Span};
-
-macro_rules! tokens {
-    (
-        punct: {
-            $($punct:tt pub struct $punct_name:ident/$len:tt #[$punct_doc:meta])*
-        }
-        delimiter: {
-            $($delimiter:tt pub struct $delimiter_name:ident #[$delimiter_doc:meta])*
-        }
-        keyword: {
-            $($keyword:tt pub struct $keyword_name:ident #[$keyword_doc:meta])*
-        }
-    ) => (
-        $(token_punct_def! { #[$punct_doc] pub struct $punct_name/$len })*
-        $(token_punct_parser! { $punct pub struct $punct_name })*
-        $(token_delimiter! { #[$delimiter_doc] $delimiter pub struct $delimiter_name })*
-        $(token_keyword! { #[$keyword_doc] $keyword pub struct $keyword_name })*
-    )
-}
-
-macro_rules! token_punct_def {
-    (#[$doc:meta]pub struct $name:ident / $len:tt) => {
-        #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
-        #[$doc]
-        ///
-        /// Don't try to remember the name of this type -- use the [`Token!`]
-        /// macro instead.
-        ///
-        /// [`Token!`]: index.html
-        pub struct $name(pub [Span; $len]);
-
-        impl $name {
-            pub fn new(span: Span) -> Self {
-                $name([span; $len])
-            }
-        }
-
-        impl ::std::default::Default for $name {
-            fn default() -> Self {
-                $name([Span::call_site(); $len])
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::fmt::Debug for $name {
-            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
-                f.write_str(stringify!($name))
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::cmp::Eq for $name {}
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::cmp::PartialEq for $name {
-            fn eq(&self, _other: &$name) -> bool {
-                true
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::hash::Hash for $name {
-            fn hash<H>(&self, _state: &mut H)
-            where
-                H: ::std::hash::Hasher,
-            {
-            }
-        }
-
-        impl From<Span> for $name {
-            fn from(span: Span) -> Self {
-                $name([span; $len])
-            }
-        }
-    };
-}
-
-macro_rules! token_punct_parser {
-    ($s:tt pub struct $name:ident) => {
-        #[cfg(feature = "printing")]
-        impl ::quote::ToTokens for $name {
-            fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
-                printing::punct($s, &self.0, tokens);
-            }
-        }
-
-        #[cfg(feature = "parsing")]
-        impl ::Synom for $name {
-            fn parse(tokens: $crate::buffer::Cursor) -> $crate::synom::PResult<$name> {
-                parsing::punct($s, tokens, $name)
-            }
-
-            fn description() -> Option<&'static str> {
-                Some(concat!("`", $s, "`"))
-            }
-        }
-    };
-}
-
-macro_rules! token_keyword {
-    (#[$doc:meta] $s:tt pub struct $name:ident) => {
-        #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
-        #[$doc]
-        ///
-        /// Don't try to remember the name of this type -- use the [`Token!`]
-        /// macro instead.
-        ///
-        /// [`Token!`]: index.html
-        pub struct $name(pub Span);
-
-        impl ::std::default::Default for $name {
-            fn default() -> Self {
-                $name(Span::call_site())
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::fmt::Debug for $name {
-            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
-                f.write_str(stringify!($name))
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::cmp::Eq for $name {}
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::cmp::PartialEq for $name {
-            fn eq(&self, _other: &$name) -> bool {
-                true
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::hash::Hash for $name {
-            fn hash<H>(&self, _state: &mut H)
-            where
-                H: ::std::hash::Hasher,
-            {
-            }
-        }
-
-        #[cfg(feature = "printing")]
-        impl ::quote::ToTokens for $name {
-            fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
-                printing::keyword($s, &self.0, tokens);
-            }
-        }
-
-        #[cfg(feature = "parsing")]
-        impl ::Synom for $name {
-            fn parse(tokens: $crate::buffer::Cursor) -> $crate::synom::PResult<$name> {
-                parsing::keyword($s, tokens, $name)
-            }
-
-            fn description() -> Option<&'static str> {
-                Some(concat!("`", $s, "`"))
-            }
-        }
-
-        impl From<Span> for $name {
-            fn from(span: Span) -> Self {
-                $name(span)
-            }
-        }
-    };
-}
-
-macro_rules! token_delimiter {
-    (#[$doc:meta] $s:tt pub struct $name:ident) => {
-        #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
-        #[$doc]
-        pub struct $name(pub Span);
-
-        impl ::std::default::Default for $name {
-            fn default() -> Self {
-                $name(Span::call_site())
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::fmt::Debug for $name {
-            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
-                f.write_str(stringify!($name))
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::cmp::Eq for $name {}
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::cmp::PartialEq for $name {
-            fn eq(&self, _other: &$name) -> bool {
-                true
-            }
-        }
-
-        #[cfg(feature = "extra-traits")]
-        impl ::std::hash::Hash for $name {
-            fn hash<H>(&self, _state: &mut H)
-            where
-                H: ::std::hash::Hasher,
-            {
-            }
-        }
-
-        impl $name {
-            #[cfg(feature = "printing")]
-            pub fn surround<F>(&self, tokens: &mut ::proc_macro2::TokenStream, f: F)
-            where
-                F: FnOnce(&mut ::proc_macro2::TokenStream),
-            {
-                printing::delim($s, &self.0, tokens, f);
-            }
-
-            #[cfg(feature = "parsing")]
-            pub fn parse<F, R>(
-                tokens: $crate::buffer::Cursor,
-                f: F,
-            ) -> $crate::synom::PResult<($name, R)>
-            where
-                F: FnOnce($crate::buffer::Cursor) -> $crate::synom::PResult<R>,
-            {
-                parsing::delim($s, tokens, $name, f)
-            }
-        }
-
-        impl From<Span> for $name {
-            fn from(span: Span) -> Self {
-                $name(span)
-            }
-        }
-    };
-}
-
-token_punct_def! {
-    /// `_`
-    pub struct Underscore/1
-}
-
 #[cfg(feature = "printing")]
-impl ::quote::ToTokens for Underscore {
-    fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
-        use quote::TokenStreamExt;
-        tokens.append(::proc_macro2::Ident::new("_", self.0[0]));
-    }
+use proc_macro2::{Punct, TokenStream};
+#[cfg(feature = "printing")]
+use quote::{ToTokens, TokenStreamExt};
+
+#[cfg(feature = "parsing")]
+use error::Result;
+#[cfg(feature = "parsing")]
+use lifetime::Lifetime;
+#[cfg(feature = "parsing")]
+use lit::{Lit, LitBool, LitByte, LitByteStr, LitChar, LitFloat, LitInt, LitStr};
+#[cfg(feature = "parsing")]
+use lookahead;
+#[cfg(feature = "parsing")]
+use parse::{Lookahead1, Parse, ParseBuffer, ParseStream};
+use span::IntoSpans;
+
+/// Marker trait for types that represent single tokens.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+#[cfg(feature = "parsing")]
+pub trait Token: private::Sealed {
+    // Not public API.
+    #[doc(hidden)]
+    fn peek(lookahead: &Lookahead1) -> bool;
+
+    // Not public API.
+    #[doc(hidden)]
+    fn display() -> String;
 }
 
 #[cfg(feature = "parsing")]
-impl ::Synom for Underscore {
-    fn parse(input: ::buffer::Cursor) -> ::synom::PResult<Underscore> {
-        match input.ident() {
-            Some((ident, rest)) => {
-                if ident == "_" {
-                    Ok((Underscore([ident.span()]), rest))
-                } else {
-                    ::parse_error()
-                }
-            }
-            None => parsing::punct("_", input, Underscore),
-        }
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("`_`")
-    }
+mod private {
+    pub trait Sealed {}
 }
 
-token_punct_def! {
-    /// `'`
-    pub struct Apostrophe/1
+macro_rules! impl_token {
+    ($name:ident $display:expr) => {
+        #[cfg(feature = "parsing")]
+        impl Token for $name {
+            fn peek(lookahead: &Lookahead1) -> bool {
+                // TODO factor out in a way that can be compiled just once
+                let scope = Span::call_site();
+                let cursor = lookahead.cursor();
+                let unexpected = Rc::new(Cell::new(None));
+                ParseBuffer::new(scope, cursor, unexpected)
+                    .parse::<Self>()
+                    .is_ok()
+            }
+
+            fn display() -> String {
+                $display.to_owned()
+            }
+        }
+
+        #[cfg(feature = "parsing")]
+        impl private::Sealed for $name {}
+    };
+}
+
+impl_token!(Ident "identifier");
+impl_token!(Lifetime "lifetime");
+impl_token!(Lit "literal");
+impl_token!(LitStr "string literal");
+impl_token!(LitByteStr "byte string literal");
+impl_token!(LitByte "byte literal");
+impl_token!(LitChar "character literal");
+impl_token!(LitInt "integer literal");
+impl_token!(LitFloat "floating point literal");
+impl_token!(LitBool "boolean literal");
+
+macro_rules! define_keywords {
+    ($($token:tt pub struct $name:ident #[$doc:meta])*) => {
+        $(
+            #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
+            #[$doc]
+            ///
+            /// Don't try to remember the name of this type -- use the [`Token!`]
+            /// macro instead.
+            ///
+            /// [`Token!`]: index.html
+            pub struct $name {
+                pub span: Span,
+            }
+
+            #[doc(hidden)]
+            #[allow(non_snake_case)]
+            pub fn $name<S: IntoSpans<[Span; 1]>>(span: S) -> $name {
+                $name {
+                    span: span.into_spans()[0],
+                }
+            }
+
+            impl_token!($name concat!("`", $token, "`"));
+
+            impl std::default::Default for $name {
+                fn default() -> Self {
+                    $name(Span::call_site())
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl Debug for $name {
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    f.write_str(stringify!($name))
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl cmp::Eq for $name {}
+
+            #[cfg(feature = "extra-traits")]
+            impl PartialEq for $name {
+                fn eq(&self, _other: &$name) -> bool {
+                    true
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl Hash for $name {
+                fn hash<H: Hasher>(&self, _state: &mut H) {}
+            }
+
+            #[cfg(feature = "printing")]
+            impl ToTokens for $name {
+                fn to_tokens(&self, tokens: &mut TokenStream) {
+                    printing::keyword($token, &self.span, tokens);
+                }
+            }
+
+            #[cfg(feature = "parsing")]
+            impl Parse for $name {
+                fn parse(input: ParseStream) -> Result<Self> {
+                    parsing::keyword(input, $token).map($name)
+                }
+            }
+        )*
+    };
+}
+
+macro_rules! define_punctuation_structs {
+    ($($token:tt pub struct $name:ident/$len:tt #[$doc:meta])*) => {
+        $(
+            #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
+            #[$doc]
+            ///
+            /// Don't try to remember the name of this type -- use the [`Token!`]
+            /// macro instead.
+            ///
+            /// [`Token!`]: index.html
+            pub struct $name {
+                pub spans: [Span; $len],
+            }
+
+            #[doc(hidden)]
+            #[allow(non_snake_case)]
+            pub fn $name<S: IntoSpans<[Span; $len]>>(spans: S) -> $name {
+                $name {
+                    spans: spans.into_spans(),
+                }
+            }
+
+            impl_token!($name concat!("`", $token, "`"));
+
+            impl std::default::Default for $name {
+                fn default() -> Self {
+                    $name([Span::call_site(); $len])
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl Debug for $name {
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    f.write_str(stringify!($name))
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl cmp::Eq for $name {}
+
+            #[cfg(feature = "extra-traits")]
+            impl PartialEq for $name {
+                fn eq(&self, _other: &$name) -> bool {
+                    true
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl Hash for $name {
+                fn hash<H: Hasher>(&self, _state: &mut H) {}
+            }
+        )*
+    };
+}
+
+macro_rules! define_punctuation {
+    ($($token:tt pub struct $name:ident/$len:tt #[$doc:meta])*) => {
+        $(
+            define_punctuation_structs! {
+                $token pub struct $name/$len #[$doc]
+            }
+
+            #[cfg(feature = "printing")]
+            impl ToTokens for $name {
+                fn to_tokens(&self, tokens: &mut TokenStream) {
+                    printing::punct($token, &self.spans, tokens);
+                }
+            }
+
+            #[cfg(feature = "parsing")]
+            impl Parse for $name {
+                fn parse(input: ParseStream) -> Result<Self> {
+                    parsing::punct(input, $token).map($name::<[Span; $len]>)
+                }
+            }
+        )*
+    };
+}
+
+macro_rules! define_delimiters {
+    ($($token:tt pub struct $name:ident #[$doc:meta])*) => {
+        $(
+            #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
+            #[$doc]
+            pub struct $name {
+                pub span: Span,
+            }
+
+            #[doc(hidden)]
+            #[allow(non_snake_case)]
+            pub fn $name<S: IntoSpans<[Span; 1]>>(span: S) -> $name {
+                $name {
+                    span: span.into_spans()[0],
+                }
+            }
+
+            impl std::default::Default for $name {
+                fn default() -> Self {
+                    $name(Span::call_site())
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl Debug for $name {
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    f.write_str(stringify!($name))
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl cmp::Eq for $name {}
+
+            #[cfg(feature = "extra-traits")]
+            impl PartialEq for $name {
+                fn eq(&self, _other: &$name) -> bool {
+                    true
+                }
+            }
+
+            #[cfg(feature = "extra-traits")]
+            impl Hash for $name {
+                fn hash<H: Hasher>(&self, _state: &mut H) {}
+            }
+
+            impl $name {
+                #[cfg(feature = "printing")]
+                pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
+                where
+                    F: FnOnce(&mut TokenStream),
+                {
+                    printing::delim($token, &self.span, tokens, f);
+                }
+
+                #[cfg(feature = "parsing")]
+                pub fn parse<F, R>(
+                    tokens: $crate::buffer::Cursor,
+                    f: F,
+                ) -> $crate::synom::PResult<($name, R)>
+                where
+                    F: FnOnce($crate::buffer::Cursor) -> $crate::synom::PResult<R>,
+                {
+                    parsing::delim($token, tokens, $name, f)
+                }
+            }
+
+            #[cfg(feature = "parsing")]
+            impl private::Sealed for $name {}
+        )*
+    };
+}
+
+define_punctuation_structs! {
+    "'" pub struct Apostrophe/1 /// `'`
+    "_" pub struct Underscore/1 /// `_`
 }
 
 // Implement Clone anyway because it is required for cloning Lifetime.
 #[cfg(not(feature = "clone-impls"))]
 impl Clone for Apostrophe {
     fn clone(&self) -> Self {
-        Apostrophe(self.0)
+        Apostrophe(self.spans)
     }
 }
 
 #[cfg(feature = "printing")]
-impl ::quote::ToTokens for Apostrophe {
-    fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
-        use quote::TokenStreamExt;
-        let mut token = ::proc_macro2::Punct::new('\'', ::proc_macro2::Spacing::Joint);
-        token.set_span(self.0[0]);
+impl ToTokens for Apostrophe {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        let mut token = Punct::new('\'', Spacing::Joint);
+        token.set_span(self.spans[0]);
         tokens.append(token);
     }
 }
 
 #[cfg(feature = "parsing")]
-impl ::Synom for Apostrophe {
-    fn parse(input: ::buffer::Cursor) -> ::synom::PResult<Apostrophe> {
-        match input.punct() {
-            Some((op, rest)) => {
-                if op.as_char() == '\'' && op.spacing() == ::proc_macro2::Spacing::Joint {
-                    Ok((Apostrophe([op.span()]), rest))
-                } else {
-                    ::parse_error()
+impl Parse for Apostrophe {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| {
+            if let Some((punct, rest)) = cursor.punct() {
+                if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint {
+                    return Ok((Apostrophe(punct.span()), rest));
                 }
             }
-            None => ::parse_error(),
-        }
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("`'`")
+            Err(cursor.error("expected `'`"))
+        })
     }
 }
 
-tokens! {
-    punct: {
-        "+"        pub struct Add/1        /// `+`
-        "+="       pub struct AddEq/2      /// `+=`
-        "&"        pub struct And/1        /// `&`
-        "&&"       pub struct AndAnd/2     /// `&&`
-        "&="       pub struct AndEq/2      /// `&=`
-        "@"        pub struct At/1         /// `@`
-        "!"        pub struct Bang/1       /// `!`
-        "^"        pub struct Caret/1      /// `^`
-        "^="       pub struct CaretEq/2    /// `^=`
-        ":"        pub struct Colon/1      /// `:`
-        "::"       pub struct Colon2/2     /// `::`
-        ","        pub struct Comma/1      /// `,`
-        "/"        pub struct Div/1        /// `/`
-        "/="       pub struct DivEq/2      /// `/=`
-        "$"        pub struct Dollar/1     /// `$`
-        "."        pub struct Dot/1        /// `.`
-        ".."       pub struct Dot2/2       /// `..`
-        "..."      pub struct Dot3/3       /// `...`
-        "..="      pub struct DotDotEq/3   /// `..=`
-        "="        pub struct Eq/1         /// `=`
-        "=="       pub struct EqEq/2       /// `==`
-        ">="       pub struct Ge/2         /// `>=`
-        ">"        pub struct Gt/1         /// `>`
-        "<="       pub struct Le/2         /// `<=`
-        "<"        pub struct Lt/1         /// `<`
-        "*="       pub struct MulEq/2      /// `*=`
-        "!="       pub struct Ne/2         /// `!=`
-        "|"        pub struct Or/1         /// `|`
-        "|="       pub struct OrEq/2       /// `|=`
-        "||"       pub struct OrOr/2       /// `||`
-        "#"        pub struct Pound/1      /// `#`
-        "?"        pub struct Question/1   /// `?`
-        "->"       pub struct RArrow/2     /// `->`
-        "<-"       pub struct LArrow/2     /// `<-`
-        "%"        pub struct Rem/1        /// `%`
-        "%="       pub struct RemEq/2      /// `%=`
-        "=>"       pub struct FatArrow/2   /// `=>`
-        ";"        pub struct Semi/1       /// `;`
-        "<<"       pub struct Shl/2        /// `<<`
-        "<<="      pub struct ShlEq/3      /// `<<=`
-        ">>"       pub struct Shr/2        /// `>>`
-        ">>="      pub struct ShrEq/3      /// `>>=`
-        "*"        pub struct Star/1       /// `*`
-        "-"        pub struct Sub/1        /// `-`
-        "-="       pub struct SubEq/2      /// `-=`
+#[cfg(feature = "printing")]
+impl ToTokens for Underscore {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        tokens.append(Ident::new("_", self.spans[0]));
     }
-    delimiter: {
-        "{"        pub struct Brace        /// `{...}`
-        "["        pub struct Bracket      /// `[...]`
-        "("        pub struct Paren        /// `(...)`
-        " "        pub struct Group        /// None-delimited group
+}
+
+#[cfg(feature = "parsing")]
+impl Parse for Underscore {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.step_cursor(|cursor| {
+            if let Some((ident, rest)) = cursor.ident() {
+                if ident == "_" {
+                    return Ok((Underscore(ident.span()), rest));
+                }
+            }
+            if let Some((punct, rest)) = cursor.punct() {
+                if punct.as_char() == '_' {
+                    return Ok((Underscore(punct.span()), rest));
+                }
+            }
+            Err(cursor.error("expected `_`"))
+        })
     }
-    keyword: {
-        "as"       pub struct As           /// `as`
-        "async"    pub struct Async        /// `async`
-        "auto"     pub struct Auto         /// `auto`
-        "box"      pub struct Box          /// `box`
-        "break"    pub struct Break        /// `break`
-        "Self"     pub struct CapSelf      /// `Self`
-        "catch"    pub struct Catch        /// `catch`
-        "const"    pub struct Const        /// `const`
-        "continue" pub struct Continue     /// `continue`
-        "crate"    pub struct Crate        /// `crate`
-        "default"  pub struct Default      /// `default`
-        "do"       pub struct Do           /// `do`
-        "dyn"      pub struct Dyn          /// `dyn`
-        "else"     pub struct Else         /// `else`
-        "enum"     pub struct Enum         /// `enum`
-        "extern"   pub struct Extern       /// `extern`
-        "fn"       pub struct Fn           /// `fn`
-        "for"      pub struct For          /// `for`
-        "if"       pub struct If           /// `if`
-        "impl"     pub struct Impl         /// `impl`
-        "in"       pub struct In           /// `in`
-        "let"      pub struct Let          /// `let`
-        "loop"     pub struct Loop         /// `loop`
-        "macro"    pub struct Macro        /// `macro`
-        "match"    pub struct Match        /// `match`
-        "mod"      pub struct Mod          /// `mod`
-        "move"     pub struct Move         /// `move`
-        "mut"      pub struct Mut          /// `mut`
-        "pub"      pub struct Pub          /// `pub`
-        "ref"      pub struct Ref          /// `ref`
-        "return"   pub struct Return       /// `return`
-        "self"     pub struct Self_        /// `self`
-        "static"   pub struct Static       /// `static`
-        "struct"   pub struct Struct       /// `struct`
-        "super"    pub struct Super        /// `super`
-        "trait"    pub struct Trait        /// `trait`
-        "try"      pub struct Try          /// `try`
-        "type"     pub struct Type         /// `type`
-        "union"    pub struct Union        /// `union`
-        "unsafe"   pub struct Unsafe       /// `unsafe`
-        "use"      pub struct Use          /// `use`
-        "where"    pub struct Where        /// `where`
-        "while"    pub struct While        /// `while`
-        "yield"    pub struct Yield        /// `yield`
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Paren {
+    fn peek(lookahead: &Lookahead1) -> bool {
+        lookahead::is_delimiter(lookahead, Delimiter::Parenthesis)
     }
+
+    fn display() -> String {
+        "parentheses".to_owned()
+    }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Brace {
+    fn peek(lookahead: &Lookahead1) -> bool {
+        lookahead::is_delimiter(lookahead, Delimiter::Brace)
+    }
+
+    fn display() -> String {
+        "curly braces".to_owned()
+    }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Bracket {
+    fn peek(lookahead: &Lookahead1) -> bool {
+        lookahead::is_delimiter(lookahead, Delimiter::Bracket)
+    }
+
+    fn display() -> String {
+        "square brackets".to_owned()
+    }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Group {
+    fn peek(lookahead: &Lookahead1) -> bool {
+        lookahead::is_delimiter(lookahead, Delimiter::None)
+    }
+
+    fn display() -> String {
+        "invisible group".to_owned()
+    }
+}
+
+define_keywords! {
+    "as"          pub struct As           /// `as`
+    "async"       pub struct Async        /// `async`
+    "auto"        pub struct Auto         /// `auto`
+    "box"         pub struct Box          /// `box`
+    "break"       pub struct Break        /// `break`
+    "Self"        pub struct CapSelf      /// `Self`
+    "const"       pub struct Const        /// `const`
+    "continue"    pub struct Continue     /// `continue`
+    "crate"       pub struct Crate        /// `crate`
+    "default"     pub struct Default      /// `default`
+    "dyn"         pub struct Dyn          /// `dyn`
+    "else"        pub struct Else         /// `else`
+    "enum"        pub struct Enum         /// `enum`
+    "existential" pub struct Existential  /// `existential`
+    "extern"      pub struct Extern       /// `extern`
+    "fn"          pub struct Fn           /// `fn`
+    "for"         pub struct For          /// `for`
+    "if"          pub struct If           /// `if`
+    "impl"        pub struct Impl         /// `impl`
+    "in"          pub struct In           /// `in`
+    "let"         pub struct Let          /// `let`
+    "loop"        pub struct Loop         /// `loop`
+    "macro"       pub struct Macro        /// `macro`
+    "match"       pub struct Match        /// `match`
+    "mod"         pub struct Mod          /// `mod`
+    "move"        pub struct Move         /// `move`
+    "mut"         pub struct Mut          /// `mut`
+    "pub"         pub struct Pub          /// `pub`
+    "ref"         pub struct Ref          /// `ref`
+    "return"      pub struct Return       /// `return`
+    "self"        pub struct Self_        /// `self`
+    "static"      pub struct Static       /// `static`
+    "struct"      pub struct Struct       /// `struct`
+    "super"       pub struct Super        /// `super`
+    "trait"       pub struct Trait        /// `trait`
+    "try"         pub struct Try          /// `try`
+    "type"        pub struct Type         /// `type`
+    "union"       pub struct Union        /// `union`
+    "unsafe"      pub struct Unsafe       /// `unsafe`
+    "use"         pub struct Use          /// `use`
+    "where"       pub struct Where        /// `where`
+    "while"       pub struct While        /// `while`
+    "yield"       pub struct Yield        /// `yield`
+}
+
+define_punctuation! {
+    "+"           pub struct Add/1        /// `+`
+    "+="          pub struct AddEq/2      /// `+=`
+    "&"           pub struct And/1        /// `&`
+    "&&"          pub struct AndAnd/2     /// `&&`
+    "&="          pub struct AndEq/2      /// `&=`
+    "@"           pub struct At/1         /// `@`
+    "!"           pub struct Bang/1       /// `!`
+    "^"           pub struct Caret/1      /// `^`
+    "^="          pub struct CaretEq/2    /// `^=`
+    ":"           pub struct Colon/1      /// `:`
+    "::"          pub struct Colon2/2     /// `::`
+    ","           pub struct Comma/1      /// `,`
+    "/"           pub struct Div/1        /// `/`
+    "/="          pub struct DivEq/2      /// `/=`
+    "$"           pub struct Dollar/1     /// `$`
+    "."           pub struct Dot/1        /// `.`
+    ".."          pub struct Dot2/2       /// `..`
+    "..."         pub struct Dot3/3       /// `...`
+    "..="         pub struct DotDotEq/3   /// `..=`
+    "="           pub struct Eq/1         /// `=`
+    "=="          pub struct EqEq/2       /// `==`
+    ">="          pub struct Ge/2         /// `>=`
+    ">"           pub struct Gt/1         /// `>`
+    "<="          pub struct Le/2         /// `<=`
+    "<"           pub struct Lt/1         /// `<`
+    "*="          pub struct MulEq/2      /// `*=`
+    "!="          pub struct Ne/2         /// `!=`
+    "|"           pub struct Or/1         /// `|`
+    "|="          pub struct OrEq/2       /// `|=`
+    "||"          pub struct OrOr/2       /// `||`
+    "#"           pub struct Pound/1      /// `#`
+    "?"           pub struct Question/1   /// `?`
+    "->"          pub struct RArrow/2     /// `->`
+    "<-"          pub struct LArrow/2     /// `<-`
+    "%"           pub struct Rem/1        /// `%`
+    "%="          pub struct RemEq/2      /// `%=`
+    "=>"          pub struct FatArrow/2   /// `=>`
+    ";"           pub struct Semi/1       /// `;`
+    "<<"          pub struct Shl/2        /// `<<`
+    "<<="         pub struct ShlEq/3      /// `<<=`
+    ">>"          pub struct Shr/2        /// `>>`
+    ">>="         pub struct ShrEq/3      /// `>>=`
+    "*"           pub struct Star/1       /// `*`
+    "-"           pub struct Sub/1        /// `-`
+    "-="          pub struct SubEq/2      /// `-=`
+}
+
+define_delimiters! {
+    "{"           pub struct Brace        /// `{...}`
+    "["           pub struct Bracket      /// `[...]`
+    "("           pub struct Paren        /// `(...)`
+    " "           pub struct Group        /// None-delimited group
 }
 
 /// A type-macro that expands to the name of the Rust type representation of a
@@ -522,95 +623,94 @@
 #[macro_export]
 #[cfg_attr(rustfmt, rustfmt_skip)]
 macro_rules! Token {
-    (+)        => { $crate::token::Add };
-    (+=)       => { $crate::token::AddEq };
-    (&)        => { $crate::token::And };
-    (&&)       => { $crate::token::AndAnd };
-    (&=)       => { $crate::token::AndEq };
-    (@)        => { $crate::token::At };
-    (!)        => { $crate::token::Bang };
-    (^)        => { $crate::token::Caret };
-    (^=)       => { $crate::token::CaretEq };
-    (:)        => { $crate::token::Colon };
-    (::)       => { $crate::token::Colon2 };
-    (,)        => { $crate::token::Comma };
-    (/)        => { $crate::token::Div };
-    (/=)       => { $crate::token::DivEq };
-    (.)        => { $crate::token::Dot };
-    (..)       => { $crate::token::Dot2 };
-    (...)      => { $crate::token::Dot3 };
-    (..=)      => { $crate::token::DotDotEq };
-    (=)        => { $crate::token::Eq };
-    (==)       => { $crate::token::EqEq };
-    (>=)       => { $crate::token::Ge };
-    (>)        => { $crate::token::Gt };
-    (<=)       => { $crate::token::Le };
-    (<)        => { $crate::token::Lt };
-    (*=)       => { $crate::token::MulEq };
-    (!=)       => { $crate::token::Ne };
-    (|)        => { $crate::token::Or };
-    (|=)       => { $crate::token::OrEq };
-    (||)       => { $crate::token::OrOr };
-    (#)        => { $crate::token::Pound };
-    (?)        => { $crate::token::Question };
-    (->)       => { $crate::token::RArrow };
-    (<-)       => { $crate::token::LArrow };
-    (%)        => { $crate::token::Rem };
-    (%=)       => { $crate::token::RemEq };
-    (=>)       => { $crate::token::FatArrow };
-    (;)        => { $crate::token::Semi };
-    (<<)       => { $crate::token::Shl };
-    (<<=)      => { $crate::token::ShlEq };
-    (>>)       => { $crate::token::Shr };
-    (>>=)      => { $crate::token::ShrEq };
-    (*)        => { $crate::token::Star };
-    (-)        => { $crate::token::Sub };
-    (-=)       => { $crate::token::SubEq };
-    (_)        => { $crate::token::Underscore };
-    (as)       => { $crate::token::As };
-    (async)    => { $crate::token::Async };
-    (auto)     => { $crate::token::Auto };
-    (box)      => { $crate::token::Box };
-    (break)    => { $crate::token::Break };
-    (Self)     => { $crate::token::CapSelf };
-    (catch)    => { $crate::token::Catch };
-    (const)    => { $crate::token::Const };
-    (continue) => { $crate::token::Continue };
-    (crate)    => { $crate::token::Crate };
-    (default)  => { $crate::token::Default };
-    (do)       => { $crate::token::Do };
-    (dyn)      => { $crate::token::Dyn };
-    (else)     => { $crate::token::Else };
-    (enum)     => { $crate::token::Enum };
-    (extern)   => { $crate::token::Extern };
-    (fn)       => { $crate::token::Fn };
-    (for)      => { $crate::token::For };
-    (if)       => { $crate::token::If };
-    (impl)     => { $crate::token::Impl };
-    (in)       => { $crate::token::In };
-    (let)      => { $crate::token::Let };
-    (loop)     => { $crate::token::Loop };
-    (macro)    => { $crate::token::Macro };
-    (match)    => { $crate::token::Match };
-    (mod)      => { $crate::token::Mod };
-    (move)     => { $crate::token::Move };
-    (mut)      => { $crate::token::Mut };
-    (pub)      => { $crate::token::Pub };
-    (ref)      => { $crate::token::Ref };
-    (return)   => { $crate::token::Return };
-    (self)     => { $crate::token::Self_ };
-    (static)   => { $crate::token::Static };
-    (struct)   => { $crate::token::Struct };
-    (super)    => { $crate::token::Super };
-    (trait)    => { $crate::token::Trait };
-    (try)      => { $crate::token::Try };
-    (type)     => { $crate::token::Type };
-    (union)    => { $crate::token::Union };
-    (unsafe)   => { $crate::token::Unsafe };
-    (use)      => { $crate::token::Use };
-    (where)    => { $crate::token::Where };
-    (while)    => { $crate::token::While };
-    (yield)    => { $crate::token::Yield };
+    (as)          => { $crate::token::As };
+    (async)       => { $crate::token::Async };
+    (auto)        => { $crate::token::Auto };
+    (box)         => { $crate::token::Box };
+    (break)       => { $crate::token::Break };
+    (Self)        => { $crate::token::CapSelf };
+    (const)       => { $crate::token::Const };
+    (continue)    => { $crate::token::Continue };
+    (crate)       => { $crate::token::Crate };
+    (default)     => { $crate::token::Default };
+    (dyn)         => { $crate::token::Dyn };
+    (else)        => { $crate::token::Else };
+    (enum)        => { $crate::token::Enum };
+    (existential) => { $crate::token::Existential };
+    (extern)      => { $crate::token::Extern };
+    (fn)          => { $crate::token::Fn };
+    (for)         => { $crate::token::For };
+    (if)          => { $crate::token::If };
+    (impl)        => { $crate::token::Impl };
+    (in)          => { $crate::token::In };
+    (let)         => { $crate::token::Let };
+    (loop)        => { $crate::token::Loop };
+    (macro)       => { $crate::token::Macro };
+    (match)       => { $crate::token::Match };
+    (mod)         => { $crate::token::Mod };
+    (move)        => { $crate::token::Move };
+    (mut)         => { $crate::token::Mut };
+    (pub)         => { $crate::token::Pub };
+    (ref)         => { $crate::token::Ref };
+    (return)      => { $crate::token::Return };
+    (self)        => { $crate::token::Self_ };
+    (static)      => { $crate::token::Static };
+    (struct)      => { $crate::token::Struct };
+    (super)       => { $crate::token::Super };
+    (trait)       => { $crate::token::Trait };
+    (try)         => { $crate::token::Try };
+    (type)        => { $crate::token::Type };
+    (union)       => { $crate::token::Union };
+    (unsafe)      => { $crate::token::Unsafe };
+    (use)         => { $crate::token::Use };
+    (where)       => { $crate::token::Where };
+    (while)       => { $crate::token::While };
+    (yield)       => { $crate::token::Yield };
+    (+)           => { $crate::token::Add };
+    (+=)          => { $crate::token::AddEq };
+    (&)           => { $crate::token::And };
+    (&&)          => { $crate::token::AndAnd };
+    (&=)          => { $crate::token::AndEq };
+    (@)           => { $crate::token::At };
+    (!)           => { $crate::token::Bang };
+    (^)           => { $crate::token::Caret };
+    (^=)          => { $crate::token::CaretEq };
+    (:)           => { $crate::token::Colon };
+    (::)          => { $crate::token::Colon2 };
+    (,)           => { $crate::token::Comma };
+    (/)           => { $crate::token::Div };
+    (/=)          => { $crate::token::DivEq };
+    (.)           => { $crate::token::Dot };
+    (..)          => { $crate::token::Dot2 };
+    (...)         => { $crate::token::Dot3 };
+    (..=)         => { $crate::token::DotDotEq };
+    (=)           => { $crate::token::Eq };
+    (==)          => { $crate::token::EqEq };
+    (>=)          => { $crate::token::Ge };
+    (>)           => { $crate::token::Gt };
+    (<=)          => { $crate::token::Le };
+    (<)           => { $crate::token::Lt };
+    (*=)          => { $crate::token::MulEq };
+    (!=)          => { $crate::token::Ne };
+    (|)           => { $crate::token::Or };
+    (|=)          => { $crate::token::OrEq };
+    (||)          => { $crate::token::OrOr };
+    (#)           => { $crate::token::Pound };
+    (?)           => { $crate::token::Question };
+    (->)          => { $crate::token::RArrow };
+    (<-)          => { $crate::token::LArrow };
+    (%)           => { $crate::token::Rem };
+    (%=)          => { $crate::token::RemEq };
+    (=>)          => { $crate::token::FatArrow };
+    (;)           => { $crate::token::Semi };
+    (<<)          => { $crate::token::Shl };
+    (<<=)         => { $crate::token::ShlEq };
+    (>>)          => { $crate::token::Shr };
+    (>>=)         => { $crate::token::ShrEq };
+    (*)           => { $crate::token::Star };
+    (-)           => { $crate::token::Sub };
+    (-=)          => { $crate::token::SubEq };
+    (_)           => { $crate::token::Underscore };
 }
 
 /// Parse a single Rust punctuation token.
@@ -682,57 +782,56 @@
 #[macro_export]
 #[cfg_attr(rustfmt, rustfmt_skip)]
 macro_rules! keyword {
-    ($i:expr, as)       => { call!($i, <$crate::token::As as $crate::synom::Synom>::parse) };
-    ($i:expr, async)    => { call!($i, <$crate::token::Async as $crate::synom::Synom>::parse) };
-    ($i:expr, auto)     => { call!($i, <$crate::token::Auto as $crate::synom::Synom>::parse) };
-    ($i:expr, box)      => { call!($i, <$crate::token::Box as $crate::synom::Synom>::parse) };
-    ($i:expr, break)    => { call!($i, <$crate::token::Break as $crate::synom::Synom>::parse) };
-    ($i:expr, Self)     => { call!($i, <$crate::token::CapSelf as $crate::synom::Synom>::parse) };
-    ($i:expr, catch)    => { call!($i, <$crate::token::Catch as $crate::synom::Synom>::parse) };
-    ($i:expr, const)    => { call!($i, <$crate::token::Const as $crate::synom::Synom>::parse) };
-    ($i:expr, continue) => { call!($i, <$crate::token::Continue as $crate::synom::Synom>::parse) };
-    ($i:expr, crate)    => { call!($i, <$crate::token::Crate as $crate::synom::Synom>::parse) };
-    ($i:expr, default)  => { call!($i, <$crate::token::Default as $crate::synom::Synom>::parse) };
-    ($i:expr, do)       => { call!($i, <$crate::token::Do as $crate::synom::Synom>::parse) };
-    ($i:expr, dyn)      => { call!($i, <$crate::token::Dyn as $crate::synom::Synom>::parse) };
-    ($i:expr, else)     => { call!($i, <$crate::token::Else as $crate::synom::Synom>::parse) };
-    ($i:expr, enum)     => { call!($i, <$crate::token::Enum as $crate::synom::Synom>::parse) };
-    ($i:expr, extern)   => { call!($i, <$crate::token::Extern as $crate::synom::Synom>::parse) };
-    ($i:expr, fn)       => { call!($i, <$crate::token::Fn as $crate::synom::Synom>::parse) };
-    ($i:expr, for)      => { call!($i, <$crate::token::For as $crate::synom::Synom>::parse) };
-    ($i:expr, if)       => { call!($i, <$crate::token::If as $crate::synom::Synom>::parse) };
-    ($i:expr, impl)     => { call!($i, <$crate::token::Impl as $crate::synom::Synom>::parse) };
-    ($i:expr, in)       => { call!($i, <$crate::token::In as $crate::synom::Synom>::parse) };
-    ($i:expr, let)      => { call!($i, <$crate::token::Let as $crate::synom::Synom>::parse) };
-    ($i:expr, loop)     => { call!($i, <$crate::token::Loop as $crate::synom::Synom>::parse) };
-    ($i:expr, macro)    => { call!($i, <$crate::token::Macro as $crate::synom::Synom>::parse) };
-    ($i:expr, match)    => { call!($i, <$crate::token::Match as $crate::synom::Synom>::parse) };
-    ($i:expr, mod)      => { call!($i, <$crate::token::Mod as $crate::synom::Synom>::parse) };
-    ($i:expr, move)     => { call!($i, <$crate::token::Move as $crate::synom::Synom>::parse) };
-    ($i:expr, mut)      => { call!($i, <$crate::token::Mut as $crate::synom::Synom>::parse) };
-    ($i:expr, pub)      => { call!($i, <$crate::token::Pub as $crate::synom::Synom>::parse) };
-    ($i:expr, ref)      => { call!($i, <$crate::token::Ref as $crate::synom::Synom>::parse) };
-    ($i:expr, return)   => { call!($i, <$crate::token::Return as $crate::synom::Synom>::parse) };
-    ($i:expr, self)     => { call!($i, <$crate::token::Self_ as $crate::synom::Synom>::parse) };
-    ($i:expr, static)   => { call!($i, <$crate::token::Static as $crate::synom::Synom>::parse) };
-    ($i:expr, struct)   => { call!($i, <$crate::token::Struct as $crate::synom::Synom>::parse) };
-    ($i:expr, super)    => { call!($i, <$crate::token::Super as $crate::synom::Synom>::parse) };
-    ($i:expr, trait)    => { call!($i, <$crate::token::Trait as $crate::synom::Synom>::parse) };
-    ($i:expr, try)      => { call!($i, <$crate::token::Try as $crate::synom::Synom>::parse) };
-    ($i:expr, type)     => { call!($i, <$crate::token::Type as $crate::synom::Synom>::parse) };
-    ($i:expr, union)    => { call!($i, <$crate::token::Union as $crate::synom::Synom>::parse) };
-    ($i:expr, unsafe)   => { call!($i, <$crate::token::Unsafe as $crate::synom::Synom>::parse) };
-    ($i:expr, use)      => { call!($i, <$crate::token::Use as $crate::synom::Synom>::parse) };
-    ($i:expr, where)    => { call!($i, <$crate::token::Where as $crate::synom::Synom>::parse) };
-    ($i:expr, while)    => { call!($i, <$crate::token::While as $crate::synom::Synom>::parse) };
-    ($i:expr, yield)    => { call!($i, <$crate::token::Yield as $crate::synom::Synom>::parse) };
+    ($i:expr, as)          => { call!($i, <$crate::token::As as $crate::synom::Synom>::parse) };
+    ($i:expr, async)       => { call!($i, <$crate::token::Async as $crate::synom::Synom>::parse) };
+    ($i:expr, auto)        => { call!($i, <$crate::token::Auto as $crate::synom::Synom>::parse) };
+    ($i:expr, box)         => { call!($i, <$crate::token::Box as $crate::synom::Synom>::parse) };
+    ($i:expr, break)       => { call!($i, <$crate::token::Break as $crate::synom::Synom>::parse) };
+    ($i:expr, Self)        => { call!($i, <$crate::token::CapSelf as $crate::synom::Synom>::parse) };
+    ($i:expr, const)       => { call!($i, <$crate::token::Const as $crate::synom::Synom>::parse) };
+    ($i:expr, continue)    => { call!($i, <$crate::token::Continue as $crate::synom::Synom>::parse) };
+    ($i:expr, crate)       => { call!($i, <$crate::token::Crate as $crate::synom::Synom>::parse) };
+    ($i:expr, default)     => { call!($i, <$crate::token::Default as $crate::synom::Synom>::parse) };
+    ($i:expr, dyn)         => { call!($i, <$crate::token::Dyn as $crate::synom::Synom>::parse) };
+    ($i:expr, else)        => { call!($i, <$crate::token::Else as $crate::synom::Synom>::parse) };
+    ($i:expr, enum)        => { call!($i, <$crate::token::Enum as $crate::synom::Synom>::parse) };
+    ($i:expr, extern)      => { call!($i, <$crate::token::Extern as $crate::synom::Synom>::parse) };
+    ($i:expr, existential) => { call!($i, <$crate::token::Existential as $crate::synom::Synom>::parse) };
+    ($i:expr, fn)          => { call!($i, <$crate::token::Fn as $crate::synom::Synom>::parse) };
+    ($i:expr, for)         => { call!($i, <$crate::token::For as $crate::synom::Synom>::parse) };
+    ($i:expr, if)          => { call!($i, <$crate::token::If as $crate::synom::Synom>::parse) };
+    ($i:expr, impl)        => { call!($i, <$crate::token::Impl as $crate::synom::Synom>::parse) };
+    ($i:expr, in)          => { call!($i, <$crate::token::In as $crate::synom::Synom>::parse) };
+    ($i:expr, let)         => { call!($i, <$crate::token::Let as $crate::synom::Synom>::parse) };
+    ($i:expr, loop)        => { call!($i, <$crate::token::Loop as $crate::synom::Synom>::parse) };
+    ($i:expr, macro)       => { call!($i, <$crate::token::Macro as $crate::synom::Synom>::parse) };
+    ($i:expr, match)       => { call!($i, <$crate::token::Match as $crate::synom::Synom>::parse) };
+    ($i:expr, mod)         => { call!($i, <$crate::token::Mod as $crate::synom::Synom>::parse) };
+    ($i:expr, move)        => { call!($i, <$crate::token::Move as $crate::synom::Synom>::parse) };
+    ($i:expr, mut)         => { call!($i, <$crate::token::Mut as $crate::synom::Synom>::parse) };
+    ($i:expr, pub)         => { call!($i, <$crate::token::Pub as $crate::synom::Synom>::parse) };
+    ($i:expr, ref)         => { call!($i, <$crate::token::Ref as $crate::synom::Synom>::parse) };
+    ($i:expr, return)      => { call!($i, <$crate::token::Return as $crate::synom::Synom>::parse) };
+    ($i:expr, self)        => { call!($i, <$crate::token::Self_ as $crate::synom::Synom>::parse) };
+    ($i:expr, static)      => { call!($i, <$crate::token::Static as $crate::synom::Synom>::parse) };
+    ($i:expr, struct)      => { call!($i, <$crate::token::Struct as $crate::synom::Synom>::parse) };
+    ($i:expr, super)       => { call!($i, <$crate::token::Super as $crate::synom::Synom>::parse) };
+    ($i:expr, trait)       => { call!($i, <$crate::token::Trait as $crate::synom::Synom>::parse) };
+    ($i:expr, try)         => { call!($i, <$crate::token::Try as $crate::synom::Synom>::parse) };
+    ($i:expr, type)        => { call!($i, <$crate::token::Type as $crate::synom::Synom>::parse) };
+    ($i:expr, union)       => { call!($i, <$crate::token::Union as $crate::synom::Synom>::parse) };
+    ($i:expr, unsafe)      => { call!($i, <$crate::token::Unsafe as $crate::synom::Synom>::parse) };
+    ($i:expr, use)         => { call!($i, <$crate::token::Use as $crate::synom::Synom>::parse) };
+    ($i:expr, where)       => { call!($i, <$crate::token::Where as $crate::synom::Synom>::parse) };
+    ($i:expr, while)       => { call!($i, <$crate::token::While as $crate::synom::Synom>::parse) };
+    ($i:expr, yield)       => { call!($i, <$crate::token::Yield as $crate::synom::Synom>::parse) };
 }
 
 macro_rules! ident_from_token {
     ($token:ident) => {
         impl From<Token![$token]> for Ident {
             fn from(token: Token![$token]) -> Ident {
-                Ident::new(stringify!($token), token.0)
+                Ident::new(stringify!($token), token.span)
             }
         }
     };
@@ -749,68 +848,48 @@
     use proc_macro2::{Delimiter, Spacing, Span};
 
     use buffer::Cursor;
+    use error::{Error, Result};
+    use parse::ParseStream;
     use parse_error;
+    use span::FromSpans;
     use synom::PResult;
 
-    pub trait FromSpans: Sized {
-        fn from_spans(spans: &[Span]) -> Self;
-    }
-
-    impl FromSpans for [Span; 1] {
-        fn from_spans(spans: &[Span]) -> Self {
-            [spans[0]]
-        }
-    }
-
-    impl FromSpans for [Span; 2] {
-        fn from_spans(spans: &[Span]) -> Self {
-            [spans[0], spans[1]]
-        }
-    }
-
-    impl FromSpans for [Span; 3] {
-        fn from_spans(spans: &[Span]) -> Self {
-            [spans[0], spans[1], spans[2]]
-        }
-    }
-
-    pub fn punct<'a, T, R>(s: &str, mut tokens: Cursor<'a>, new: fn(T) -> R) -> PResult<'a, R>
-    where
-        T: FromSpans,
-    {
-        let mut spans = [Span::call_site(); 3];
-        assert!(s.len() <= spans.len());
-        let chars = s.chars();
-
-        for (i, (ch, slot)) in chars.zip(&mut spans).enumerate() {
-            match tokens.punct() {
-                Some((op, rest)) => {
-                    if op.as_char() == ch {
-                        if i != s.len() - 1 {
-                            match op.spacing() {
-                                Spacing::Joint => {}
-                                _ => return parse_error(),
-                            }
-                        }
-                        *slot = op.span();
-                        tokens = rest;
-                    } else {
-                        return parse_error();
-                    }
+    pub fn keyword(input: ParseStream, token: &str) -> Result<Span> {
+        input.step_cursor(|cursor| {
+            if let Some((ident, rest)) = cursor.ident() {
+                if ident == token {
+                    return Ok((ident.span(), rest));
                 }
-                _ => return parse_error(),
             }
-        }
-        Ok((new(T::from_spans(&spans)), tokens))
+            Err(cursor.error(format!("expected `{}`", token)))
+        })
     }
 
-    pub fn keyword<'a, T>(keyword: &str, tokens: Cursor<'a>, new: fn(Span) -> T) -> PResult<'a, T> {
-        if let Some((ident, rest)) = tokens.ident() {
-            if ident == keyword {
-                return Ok((new(ident.span()), rest));
+    pub fn punct<S: FromSpans>(input: ParseStream, token: &str) -> Result<S> {
+        input.step_cursor(|cursor| {
+            let mut cursor = *cursor;
+            let mut spans = [cursor.span(); 3];
+            assert!(token.len() <= spans.len());
+
+            for (i, ch) in token.chars().enumerate() {
+                match cursor.punct() {
+                    Some((punct, rest)) => {
+                        spans[i] = punct.span();
+                        if punct.as_char() != ch {
+                            break;
+                        } else if i == token.len() - 1 {
+                            return Ok((S::from_spans(&spans), rest));
+                        } else if punct.spacing() != Spacing::Joint {
+                            break;
+                        }
+                        cursor = rest;
+                    }
+                    None => break,
+                }
             }
-        }
-        parse_error()
+
+            Err(Error::new(spans[0], format!("expected `{}`", token)))
+        })
     }
 
     pub fn delim<'a, F, R, T>(
diff --git a/src/tt.rs b/src/tt.rs
index bde82dc..e4f703e 100644
--- a/src/tt.rs
+++ b/src/tt.rs
@@ -6,61 +6,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[cfg(feature = "parsing")]
-use buffer::Cursor;
-#[cfg(feature = "parsing")]
-use synom::PResult;
-#[cfg(feature = "parsing")]
-use token::{Brace, Bracket, Paren};
-#[cfg(feature = "parsing")]
-use {parse_error, MacroDelimiter};
-
-#[cfg(feature = "extra-traits")]
 use std::hash::{Hash, Hasher};
 
-#[cfg(any(feature = "parsing", feature = "extra-traits"))]
 use proc_macro2::{Delimiter, TokenStream, TokenTree};
 
-#[cfg(feature = "parsing")]
-pub fn delimited(input: Cursor) -> PResult<(MacroDelimiter, TokenStream)> {
-    if let Some((TokenTree::Group(g), rest)) = input.token_tree() {
-        let span = g.span();
-        let delimiter = match g.delimiter() {
-            Delimiter::Parenthesis => MacroDelimiter::Paren(Paren(span)),
-            Delimiter::Brace => MacroDelimiter::Brace(Brace(span)),
-            Delimiter::Bracket => MacroDelimiter::Bracket(Bracket(span)),
-            Delimiter::None => return parse_error(),
-        };
-
-        return Ok(((delimiter, g.stream().clone()), rest));
-    }
-    parse_error()
-}
-
-#[cfg(all(feature = "full", feature = "parsing"))]
-pub fn braced(input: Cursor) -> PResult<(Brace, TokenStream)> {
-    if let Some((TokenTree::Group(g), rest)) = input.token_tree() {
-        if g.delimiter() == Delimiter::Brace {
-            return Ok(((Brace(g.span()), g.stream().clone()), rest));
-        }
-    }
-    parse_error()
-}
-
-#[cfg(all(feature = "full", feature = "parsing"))]
-pub fn parenthesized(input: Cursor) -> PResult<(Paren, TokenStream)> {
-    if let Some((TokenTree::Group(g), rest)) = input.token_tree() {
-        if g.delimiter() == Delimiter::Parenthesis {
-            return Ok(((Paren(g.span()), g.stream().clone()), rest));
-        }
-    }
-    parse_error()
-}
-
-#[cfg(feature = "extra-traits")]
 pub struct TokenTreeHelper<'a>(pub &'a TokenTree);
 
-#[cfg(feature = "extra-traits")]
 impl<'a> PartialEq for TokenTreeHelper<'a> {
     fn eq(&self, other: &Self) -> bool {
         use proc_macro2::Spacing;
@@ -104,7 +55,6 @@
     }
 }
 
-#[cfg(feature = "extra-traits")]
 impl<'a> Hash for TokenTreeHelper<'a> {
     fn hash<H: Hasher>(&self, h: &mut H) {
         use proc_macro2::Spacing;
@@ -138,10 +88,8 @@
     }
 }
 
-#[cfg(feature = "extra-traits")]
 pub struct TokenStreamHelper<'a>(pub &'a TokenStream);
 
-#[cfg(feature = "extra-traits")]
 impl<'a> PartialEq for TokenStreamHelper<'a> {
     fn eq(&self, other: &Self) -> bool {
         let left = self.0.clone().into_iter().collect::<Vec<_>>();
@@ -158,7 +106,6 @@
     }
 }
 
-#[cfg(feature = "extra-traits")]
 impl<'a> Hash for TokenStreamHelper<'a> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         let tts = self.0.clone().into_iter().collect::<Vec<_>>();
diff --git a/src/ty.rs b/src/ty.rs
index 1ee46d0..fa1083f 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -73,10 +73,10 @@
         /// *This type is available if Syn is built with the `"derive"` or
         /// `"full"` feature.*
         pub BareFn(TypeBareFn {
+            pub lifetimes: Option<BoundLifetimes>,
             pub unsafety: Option<Token![unsafe]>,
             pub abi: Option<Abi>,
             pub fn_token: Token![fn],
-            pub lifetimes: Option<BoundLifetimes>,
             pub paren_token: token::Paren,
             pub inputs: Punctuated<BareFnArg, Token![,]>,
             pub variadic: Option<Token![...]>,
@@ -249,14 +249,12 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use path::parsing::qpath;
+    use parse::{Parse, ParseStream, Result};
     use synom::Synom;
 
-    impl Synom for Type {
-        named!(parse -> Self, call!(ambig_ty, true));
-
-        fn description() -> Option<&'static str> {
-            Some("type")
+    impl Parse for Type {
+        fn parse(input: ParseStream) -> Result<Self> {
+            ambig_ty(input, true)
         }
     }
 
@@ -266,250 +264,389 @@
         /// contain a `+` character.
         ///
         /// This parser does not allow a `+`, while the default parser does.
-        named!(pub without_plus -> Self, call!(ambig_ty, false));
-    }
-
-    named!(ambig_ty(allow_plus: bool) -> Type, alt!(
-        syn!(TypeGroup) => { Type::Group }
-        |
-        // must be before TypeTuple
-        call!(TypeParen::parse, allow_plus) => { Type::Paren }
-        |
-        // must be before TypePath
-        syn!(TypeMacro) => { Type::Macro }
-        |
-        // must be before TypePath
-        syn!(TypeBareFn) => { Type::BareFn }
-        |
-        // must be before TypeTraitObject
-        call!(TypePath::parse, allow_plus) => { Type::Path }
-        |
-        // Don't try parsing more than one trait bound if we aren't allowing it.
-        // must be before TypeTuple
-        call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
-        |
-        syn!(TypeSlice) => { Type::Slice }
-        |
-        syn!(TypeArray) => { Type::Array }
-        |
-        syn!(TypePtr) => { Type::Ptr }
-        |
-        syn!(TypeReference) => { Type::Reference }
-        |
-        syn!(TypeNever) => { Type::Never }
-        |
-        syn!(TypeTuple) => { Type::Tuple }
-        |
-        syn!(TypeImplTrait) => { Type::ImplTrait }
-        |
-        syn!(TypeInfer) => { Type::Infer }
-    ));
-
-    impl Synom for TypeSlice {
-        named!(parse -> Self, map!(
-            brackets!(syn!(Type)),
-            |(b, ty)| TypeSlice {
-                elem: Box::new(ty),
-                bracket_token: b,
-            }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("slice type")
+        pub fn without_plus(input: ParseStream) -> Result<Self> {
+            ambig_ty(input, false)
         }
     }
 
-    impl Synom for TypeArray {
-        named!(parse -> Self, map!(
-            brackets!(do_parse!(
-                elem: syn!(Type) >>
-                    semi: punct!(;) >>
-                    len: syn!(Expr) >>
-                    (elem, semi, len)
-            )),
-            |(brackets, (elem, semi, len))| {
-                TypeArray {
+    fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
+        if input.peek(token::Group) {
+            return input.parse().map(Type::Group);
+        }
+
+        let mut lifetimes = None::<BoundLifetimes>;
+        let mut lookahead = input.lookahead1();
+        if lookahead.peek(Token![for]) {
+            lifetimes = input.parse()?;
+            lookahead = input.lookahead1();
+            if !lookahead.peek(Ident)
+                && !lookahead.peek(Token![fn])
+                && !lookahead.peek(Token![unsafe])
+                && !lookahead.peek(Token![extern])
+                && !lookahead.peek(Token![super])
+                && !lookahead.peek(Token![self])
+                && !lookahead.peek(Token![Self])
+                && !lookahead.peek(Token![crate])
+            {
+                return Err(lookahead.error());
+            }
+        }
+
+        if lookahead.peek(token::Paren) {
+            let content;
+            let paren_token = parenthesized!(content in input);
+            if content.is_empty() {
+                return Ok(Type::Tuple(TypeTuple {
+                    paren_token: paren_token,
+                    elems: Punctuated::new(),
+                }));
+            }
+            if content.peek(Lifetime) {
+                return Ok(Type::Paren(TypeParen {
+                    paren_token: paren_token,
+                    elem: Box::new(Type::TraitObject(content.parse()?)),
+                }));
+            }
+            let first: Type = content.parse()?;
+            if content.peek(Token![,]) {
+                Ok(Type::Tuple(TypeTuple {
+                    paren_token: paren_token,
+                    elems: {
+                        let mut elems = Punctuated::new();
+                        elems.push_value(first);
+                        elems.push_punct(content.parse()?);
+                        let rest: Punctuated<Type, Token![,]> =
+                            content.parse_terminated(Parse::parse)?;
+                        elems.extend(rest);
+                        elems
+                    },
+                }))
+            } else {
+                Ok(Type::Paren(TypeParen {
+                    paren_token: paren_token,
+                    elem: Box::new(first),
+                }))
+            }
+        } else if lookahead.peek(Token![fn])
+            || lookahead.peek(Token![unsafe])
+            || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
+        {
+            let mut bare_fn: TypeBareFn = input.parse()?;
+            bare_fn.lifetimes = lifetimes;
+            Ok(Type::BareFn(bare_fn))
+        } else if lookahead.peek(Ident)
+            || input.peek(Token![super])
+            || input.peek(Token![self])
+            || input.peek(Token![Self])
+            || input.peek(Token![crate])
+            || input.peek(Token![extern])
+            || lookahead.peek(Token![::])
+            || lookahead.peek(Token![<])
+        {
+            if input.peek(Token![dyn]) {
+                let mut trait_object: TypeTraitObject = input.parse()?;
+                if lifetimes.is_some() {
+                    match *trait_object.bounds.iter_mut().next().unwrap() {
+                        TypeParamBound::Trait(ref mut trait_bound) => {
+                            trait_bound.lifetimes = lifetimes;
+                        }
+                        TypeParamBound::Lifetime(_) => unreachable!(),
+                    }
+                }
+                return Ok(Type::TraitObject(trait_object));
+            }
+
+            let ty: TypePath = input.parse()?;
+            if ty.qself.is_some() {
+                return Ok(Type::Path(ty));
+            }
+
+            if input.peek(Token![!]) && !input.peek(Token![!=]) {
+                let mut contains_arguments = false;
+                for segment in &ty.path.segments {
+                    match segment.arguments {
+                        PathArguments::None => {}
+                        PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
+                            contains_arguments = true;
+                        }
+                    }
+                }
+
+                if !contains_arguments {
+                    let bang_token: Token![!] = input.parse()?;
+                    let (delimiter, tts) = mac::parse_delimiter(input)?;
+                    return Ok(Type::Macro(TypeMacro {
+                        mac: Macro {
+                            path: ty.path,
+                            bang_token: bang_token,
+                            delimiter: delimiter,
+                            tts: tts,
+                        },
+                    }));
+                }
+            }
+
+            if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
+                let mut bounds = Punctuated::new();
+                bounds.push_value(TypeParamBound::Trait(TraitBound {
+                    paren_token: None,
+                    modifier: TraitBoundModifier::None,
+                    lifetimes: lifetimes,
+                    path: ty.path,
+                }));
+                if allow_plus && input.peek(Token![+]) {
+                    bounds.push_punct(input.parse()?);
+                    let rest: Punctuated<TypeParamBound, Token![+]> =
+                        input.parse_synom(Punctuated::parse_terminated_nonempty)?;
+                    bounds.extend(rest);
+                }
+                return Ok(Type::TraitObject(TypeTraitObject {
+                    dyn_token: None,
+                    bounds: bounds,
+                }));
+            }
+
+            Ok(Type::Path(ty))
+        } else if lookahead.peek(token::Bracket) {
+            let content;
+            let bracket_token = bracketed!(content in input);
+            let elem: Type = content.parse()?;
+            if content.peek(Token![;]) {
+                Ok(Type::Array(TypeArray {
+                    bracket_token: bracket_token,
                     elem: Box::new(elem),
-                    len: len,
-                    bracket_token: brackets,
-                    semi_token: semi,
-                }
+                    semi_token: content.parse()?,
+                    len: content.parse_synom(Expr::parse)?,
+                }))
+            } else {
+                Ok(Type::Slice(TypeSlice {
+                    bracket_token: bracket_token,
+                    elem: Box::new(elem),
+                }))
             }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("array type")
+        } else if lookahead.peek(Token![*]) {
+            input.parse().map(Type::Ptr)
+        } else if lookahead.peek(Token![&]) {
+            input.parse().map(Type::Reference)
+        } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
+            input.parse().map(Type::Never)
+        } else if lookahead.peek(Token![impl ]) {
+            input.parse().map(Type::ImplTrait)
+        } else if lookahead.peek(Token![_]) {
+            input.parse().map(Type::Infer)
+        } else if lookahead.peek(Lifetime) {
+            input.parse().map(Type::TraitObject)
+        } else {
+            Err(lookahead.error())
         }
     }
 
-    impl Synom for TypePtr {
-        named!(parse -> Self, do_parse!(
-            star: punct!(*) >>
-            mutability: alt!(
-                keyword!(const) => { |c| (None, Some(c)) }
-                |
-                keyword!(mut) => { |m| (Some(m), None) }
-            ) >>
-            target: call!(Type::without_plus) >>
-            (TypePtr {
-                const_token: mutability.1,
-                star_token: star,
-                mutability: mutability.0,
-                elem: Box::new(target),
+    impl Parse for TypeSlice {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(TypeSlice {
+                bracket_token: bracketed!(content in input),
+                elem: content.parse()?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("raw pointer type")
         }
     }
 
-    impl Synom for TypeReference {
-        named!(parse -> Self, do_parse!(
-            amp: punct!(&) >>
-            life: option!(syn!(Lifetime)) >>
-            mutability: option!(keyword!(mut)) >>
-            // & binds tighter than +, so we don't allow + here.
-            target: call!(Type::without_plus) >>
-            (TypeReference {
-                lifetime: life,
+    impl Parse for TypeArray {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(TypeArray {
+                bracket_token: bracketed!(content in input),
+                elem: content.parse()?,
+                semi_token: content.parse()?,
+                len: content.parse_synom(Expr::parse)?,
+            })
+        }
+    }
+
+    impl Parse for TypePtr {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let star_token: Token![*] = input.parse()?;
+
+            let lookahead = input.lookahead1();
+            let (const_token, mutability) = if lookahead.peek(Token![const]) {
+                (Some(input.parse()?), None)
+            } else if lookahead.peek(Token![mut]) {
+                (None, Some(input.parse()?))
+            } else {
+                return Err(lookahead.error());
+            };
+
+            Ok(TypePtr {
+                star_token: star_token,
+                const_token: const_token,
                 mutability: mutability,
-                elem: Box::new(target),
-                and_token: amp,
+                elem: Box::new(input.call(Type::without_plus)?),
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("reference type")
         }
     }
 
-    impl Synom for TypeBareFn {
-        named!(parse -> Self, do_parse!(
-            lifetimes: option!(syn!(BoundLifetimes)) >>
-            unsafety: option!(keyword!(unsafe)) >>
-            abi: option!(syn!(Abi)) >>
-            fn_: keyword!(fn) >>
-            parens: parens!(do_parse!(
-                inputs: call!(Punctuated::parse_terminated) >>
-                variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >>
-                (inputs, variadic)
-            )) >>
-            output: call!(ReturnType::without_plus) >>
-            (TypeBareFn {
-                unsafety: unsafety,
-                abi: abi,
-                lifetimes: lifetimes,
-                output: output,
-                variadic: (parens.1).1,
-                fn_token: fn_,
-                paren_token: parens.0,
-                inputs: (parens.1).0,
+    impl Parse for TypeReference {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(TypeReference {
+                and_token: input.parse()?,
+                lifetime: input.parse()?,
+                mutability: input.parse()?,
+                // & binds tighter than +, so we don't allow + here.
+                elem: Box::new(input.call(Type::without_plus)?),
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("`fn` type")
         }
     }
 
-    impl Synom for TypeNever {
-        named!(parse -> Self, map!(
-            punct!(!),
-            |b| TypeNever { bang_token: b }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("never type: `!`")
-        }
-    }
-
-    impl Synom for TypeInfer {
-        named!(parse -> Self, map!(
-            punct!(_),
-            |u| TypeInfer { underscore_token: u }
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("inferred type: `_`")
-        }
-    }
-
-    impl Synom for TypeTuple {
-        named!(parse -> Self, do_parse!(
-            data: parens!(Punctuated::parse_terminated) >>
-            (TypeTuple {
-                paren_token: data.0,
-                elems: data.1,
+    impl Parse for TypeBareFn {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let args;
+            let allow_variadic;
+            Ok(TypeBareFn {
+                lifetimes: input.parse()?,
+                unsafety: input.parse()?,
+                abi: input.parse()?,
+                fn_token: input.parse()?,
+                paren_token: parenthesized!(args in input),
+                inputs: {
+                    let inputs = args.parse_synom(Punctuated::parse_terminated)?;
+                    allow_variadic = inputs.empty_or_trailing();
+                    inputs
+                },
+                variadic: {
+                    if allow_variadic && args.peek(Token![...]) {
+                        Some(args.parse()?)
+                    } else {
+                        None
+                    }
+                },
+                output: input.call(ReturnType::without_plus)?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("tuple type")
         }
     }
 
-    impl Synom for TypeMacro {
-        named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac }));
-
-        fn description() -> Option<&'static str> {
-            Some("macro invocation")
-        }
-    }
-
-    impl Synom for TypePath {
-        named!(parse -> Self, call!(Self::parse, false));
-
-        fn description() -> Option<&'static str> {
-            Some("type path")
-        }
-    }
-
-    impl TypePath {
-        named!(parse(allow_plus: bool) -> Self, do_parse!(
-            qpath: qpath >>
-            parenthesized: option!(cond_reduce!(
-                qpath.1.segments.last().unwrap().value().arguments.is_empty(),
-                syn!(ParenthesizedGenericArguments)
-            )) >>
-            cond!(allow_plus, not!(punct!(+))) >>
-            ({
-                let (qself, mut path) = qpath;
-                if let Some(parenthesized) = parenthesized {
-                    let parenthesized = PathArguments::Parenthesized(parenthesized);
-                    path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
-                }
-                TypePath { qself: qself, path: path }
+    impl Parse for TypeNever {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(TypeNever {
+                bang_token: input.parse()?,
             })
-        ));
+        }
+    }
+
+    impl Parse for TypeInfer {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(TypeInfer {
+                underscore_token: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for TypeTuple {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(TypeTuple {
+                paren_token: parenthesized!(content in input),
+                elems: content.parse_terminated(<Type as Parse>::parse)?,
+            })
+        }
+    }
+
+    impl Parse for TypeMacro {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(TypeMacro {
+                mac: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for TypePath {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let (qself, mut path) = if input.peek(Token![<]) {
+                let lt_token: Token![<] = input.parse()?;
+                let this: Type = input.parse()?;
+                let path = if input.peek(Token![as]) {
+                    let as_token: Token![as] = input.parse()?;
+                    let path: Path = input.parse()?;
+                    Some((as_token, path))
+                } else {
+                    None
+                };
+                let gt_token: Token![>] = input.parse()?;
+                let colon2_token: Token![::] = input.parse()?;
+                let rest = input.parse_synom(Punctuated::parse_separated_nonempty)?;
+                let (position, as_token, path) = match path {
+                    Some((as_token, mut path)) => {
+                        let pos = path.segments.len();
+                        path.segments.push_punct(colon2_token);
+                        path.segments.extend(rest.into_pairs());
+                        (pos, Some(as_token), path)
+                    }
+                    None => {
+                        let path = Path {
+                            leading_colon: Some(colon2_token),
+                            segments: rest,
+                        };
+                        (0, None, path)
+                    }
+                };
+                let qself = QSelf {
+                    lt_token: lt_token,
+                    ty: Box::new(this),
+                    position: position,
+                    as_token: as_token,
+                    gt_token: gt_token,
+                };
+                (Some(qself), path)
+            } else {
+                let path: Path = input.parse()?;
+                (None, path)
+            };
+
+            let parenthesized = if path.segments.last().unwrap().value().arguments.is_empty()
+                && input.peek(token::Paren)
+            {
+                let args: ParenthesizedGenericArguments = input.parse()?;
+                Some(args)
+            } else {
+                None
+            };
+
+            if let Some(parenthesized) = parenthesized {
+                let parenthesized = PathArguments::Parenthesized(parenthesized);
+                path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
+            }
+
+            Ok(TypePath {
+                qself: qself,
+                path: path,
+            })
+        }
     }
 
     impl ReturnType {
-        named!(pub without_plus -> Self, call!(Self::parse, false));
-        named!(parse(allow_plus: bool) -> Self, alt!(
-            do_parse!(
-                arrow: punct!(->) >>
-                ty: call!(ambig_ty, allow_plus) >>
-                (ReturnType::Type(arrow, Box::new(ty)))
-            )
-            |
-            epsilon!() => { |_| ReturnType::Default }
-        ));
-    }
+        pub fn without_plus(input: ParseStream) -> Result<Self> {
+            Self::parse(input, false)
+        }
 
-    impl Synom for ReturnType {
-        named!(parse -> Self, call!(Self::parse, true));
-
-        fn description() -> Option<&'static str> {
-            Some("return type")
+        pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+            if input.peek(Token![->]) {
+                let arrow = input.parse()?;
+                let ty = ambig_ty(input, allow_plus)?;
+                Ok(ReturnType::Type(arrow, Box::new(ty)))
+            } else {
+                Ok(ReturnType::Default)
+            }
         }
     }
 
-    impl Synom for TypeTraitObject {
-        named!(parse -> Self, call!(Self::parse, true));
+    impl Parse for ReturnType {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Self::parse(input, true)
+        }
+    }
 
-        fn description() -> Option<&'static str> {
-            Some("trait object type")
+    impl Parse for TypeTraitObject {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Self::parse(input, true)
         }
     }
 
@@ -523,123 +660,118 @@
     }
 
     impl TypeTraitObject {
-        named!(pub without_plus -> Self, call!(Self::parse, false));
+        pub fn without_plus(input: ParseStream) -> Result<Self> {
+            Self::parse(input, false)
+        }
 
         // Only allow multiple trait references if allow_plus is true.
-        named!(parse(allow_plus: bool) -> Self, do_parse!(
-            dyn_token: option!(keyword!(dyn)) >>
-            bounds: alt!(
-                cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty)
-                |
-                syn!(TypeParamBound) => {|x| {
-                    let mut bounds = Punctuated::new();
-                    bounds.push_value(x);
+        pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+            Ok(TypeTraitObject {
+                dyn_token: input.parse()?,
+                bounds: {
+                    let bounds = if allow_plus {
+                        input.parse_synom(Punctuated::parse_terminated_nonempty)?
+                    } else {
+                        let mut bounds = Punctuated::new();
+                        bounds.push_value(input.parse()?);
+                        bounds
+                    };
+                    // Just lifetimes like `'a + 'b` is not a TraitObject.
+                    if !at_least_one_type(&bounds) {
+                        return Err(input.error("expected at least one type"));
+                    }
                     bounds
-                }}
-            ) >>
-            // Just lifetimes like `'a + 'b` is not a TraitObject.
-            cond_reduce!(at_least_one_type(&bounds)) >>
-            (TypeTraitObject {
-                dyn_token: dyn_token,
-                bounds: bounds,
+                },
             })
-        ));
-    }
-
-    impl Synom for TypeImplTrait {
-        named!(parse -> Self, do_parse!(
-            impl_: keyword!(impl) >>
-            // NOTE: rust-lang/rust#34511 includes discussion about whether or
-            // not + should be allowed in ImplTrait directly without ().
-            elem: call!(Punctuated::parse_terminated_nonempty) >>
-            (TypeImplTrait {
-                impl_token: impl_,
-                bounds: elem,
-            })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("`impl Trait` type")
         }
     }
 
-    impl Synom for TypeGroup {
-        named!(parse -> Self, do_parse!(
-            data: grouped!(syn!(Type)) >>
-            (TypeGroup {
-                group_token: data.0,
-                elem: Box::new(data.1),
+    impl Parse for TypeImplTrait {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(TypeImplTrait {
+                impl_token: input.parse()?,
+                // NOTE: rust-lang/rust#34511 includes discussion about whether
+                // or not + should be allowed in ImplTrait directly without ().
+                bounds: input.parse_synom(Punctuated::parse_terminated_nonempty)?,
             })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("type surrounded by invisible delimiters")
         }
     }
 
-    impl Synom for TypeParen {
-        named!(parse -> Self, call!(Self::parse, false));
+    impl Parse for TypeGroup {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let content;
+            Ok(TypeGroup {
+                group_token: grouped!(content in input),
+                elem: content.parse()?,
+            })
+        }
+    }
 
-        fn description() -> Option<&'static str> {
-            Some("parenthesized type")
+    impl Parse for TypeParen {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Self::parse(input, false)
         }
     }
 
     impl TypeParen {
-        named!(parse(allow_plus: bool) -> Self, do_parse!(
-            data: parens!(syn!(Type)) >>
-            cond!(allow_plus, not!(punct!(+))) >>
-            (TypeParen {
-                paren_token: data.0,
-                elem: Box::new(data.1),
+        fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+            let content;
+            Ok(TypeParen {
+                paren_token: parenthesized!(content in input),
+                elem: Box::new(ambig_ty(&content, allow_plus)?),
             })
-        ));
-    }
-
-    impl Synom for BareFnArg {
-        named!(parse -> Self, do_parse!(
-            name: option!(do_parse!(
-                name: syn!(BareFnArgName) >>
-                not!(punct!(::)) >>
-                colon: punct!(:) >>
-                (name, colon)
-            )) >>
-            ty: syn!(Type) >>
-            (BareFnArg {
-                name: name,
-                ty: ty,
-            })
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("function type argument")
         }
     }
 
-    impl Synom for BareFnArgName {
-        named!(parse -> Self, alt!(
-            map!(syn!(Ident), BareFnArgName::Named)
-            |
-            map!(punct!(_), BareFnArgName::Wild)
-        ));
-
-        fn description() -> Option<&'static str> {
-            Some("function argument name")
+    impl Parse for BareFnArg {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(BareFnArg {
+                name: {
+                    if (input.peek(Ident) || input.peek(Token![_]))
+                        && !input.peek2(Token![::])
+                        && input.peek2(Token![:])
+                    {
+                        let name: BareFnArgName = input.parse()?;
+                        let colon: Token![:] = input.parse()?;
+                        Some((name, colon))
+                    } else {
+                        None
+                    }
+                },
+                ty: input.parse()?,
+            })
         }
     }
 
-    impl Synom for Abi {
-        named!(parse -> Self, do_parse!(
-            extern_: keyword!(extern) >>
-            name: option!(syn!(LitStr)) >>
-            (Abi {
-                extern_token: extern_,
-                name: name,
-            })
-        ));
+    impl Parse for BareFnArgName {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let lookahead = input.lookahead1();
+            if lookahead.peek(Ident) {
+                input.parse().map(BareFnArgName::Named)
+            } else if lookahead.peek(Token![_]) {
+                input.parse().map(BareFnArgName::Wild)
+            } else {
+                Err(lookahead.error())
+            }
+        }
+    }
 
-        fn description() -> Option<&'static str> {
-            Some("`extern` ABI qualifier")
+    impl Parse for Abi {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(Abi {
+                extern_token: input.parse()?,
+                name: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for Option<Abi> {
+        fn parse(input: ParseStream) -> Result<Self> {
+            if input.peek(Token![extern]) {
+                input.parse().map(Some)
+            } else {
+                Ok(None)
+            }
         }
     }
 }
@@ -700,8 +832,8 @@
                 self.inputs.to_tokens(tokens);
                 if let Some(ref variadic) = self.variadic {
                     if !self.inputs.empty_or_trailing() {
-                        let span = variadic.0[0];
-                        <Token![,]>::new(span).to_tokens(tokens);
+                        let span = variadic.spans[0];
+                        Token![,](span).to_tokens(tokens);
                     }
                     variadic.to_tokens(tokens);
                 }
diff --git a/src/verbatim.rs b/src/verbatim.rs
index 8ab0603..35145d5 100644
--- a/src/verbatim.rs
+++ b/src/verbatim.rs
@@ -4,10 +4,12 @@
 use proc_macro2::TokenStream;
 use synom::PResult;
 
+#[allow(dead_code)]
 pub fn grab_cursor(cursor: Cursor) -> PResult<Cursor> {
     Ok((cursor, cursor))
 }
 
+#[allow(dead_code)]
 pub fn token_range(range: Range<Cursor>) -> TokenStream {
     let mut tts = Vec::new();
     let mut cursor = range.start;
diff --git a/tests/test_asyncness.rs b/tests/test_asyncness.rs
new file mode 100644
index 0000000..b73537b
--- /dev/null
+++ b/tests/test_asyncness.rs
@@ -0,0 +1,71 @@
+// Copyright 2018 Syn Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg(all(feature = "extra-traits", feature = "full"))]
+
+extern crate proc_macro2;
+extern crate syn;
+
+use proc_macro2::Span;
+use syn::punctuated::Punctuated;
+use syn::{Block, Expr, ExprBlock, ExprClosure, FnDecl, Ident, ItemFn, ReturnType, Visibility};
+
+#[test]
+fn test_async_fn() {
+    let raw = "async fn process() {}";
+
+    let expected = ItemFn {
+        attrs: vec![],
+        vis: Visibility::Inherited,
+        constness: None,
+        unsafety: None,
+        asyncness: Some(Default::default()),
+        abi: None,
+        ident: Ident::new("process", Span::call_site()),
+        decl: Box::new(FnDecl {
+            fn_token: Default::default(),
+            generics: Default::default(),
+            paren_token: Default::default(),
+            inputs: Punctuated::new(),
+            variadic: None,
+            output: ReturnType::Default,
+        }),
+        block: Box::new(Block {
+            brace_token: Default::default(),
+            stmts: vec![],
+        }),
+    };
+
+    assert_eq!(expected, syn::parse_str(raw).unwrap());
+}
+
+#[test]
+fn test_async_closure() {
+    let raw = "async || {}";
+
+    let expected = Expr::Closure(ExprClosure {
+        attrs: vec![],
+        movability: None,
+        asyncness: Some(Default::default()),
+        capture: None,
+        or1_token: Default::default(),
+        inputs: Punctuated::new(),
+        or2_token: Default::default(),
+        output: ReturnType::Default,
+        body: Box::new(Expr::Block(ExprBlock {
+            attrs: vec![],
+            label: None,
+            block: Block {
+                brace_token: Default::default(),
+                stmts: vec![],
+            },
+        })),
+    });
+
+    assert_eq!(expected, syn::parse_str(raw).unwrap());
+}
diff --git a/tests/test_derive_input.rs b/tests/test_derive_input.rs
index 5ca2c72..045e506 100644
--- a/tests/test_derive_input.rs
+++ b/tests/test_derive_input.rs
@@ -84,7 +84,6 @@
                 Parenthesis,
                 vec![word("Debug"), op(','), word("Clone")],
             )]),
-            is_sugared_doc: false,
         }],
         generics: Generics::default(),
         data: Data::Struct(DataStruct {
@@ -254,7 +253,6 @@
                         " See the std::result module documentation for details.",
                     )),
                 ]),
-                is_sugared_doc: false,
             },
             Attribute {
                 bracket_token: Default::default(),
@@ -262,7 +260,6 @@
                 style: AttrStyle::Outer,
                 path: ident("must_use").into(),
                 tts: TokenStream::new(),
-                is_sugared_doc: false,
             },
         ],
         generics: Generics {
@@ -447,7 +444,6 @@
                     ],
                 ),
             ]),
-            is_sugared_doc: false,
         }],
         generics: Generics::default(),
         data: Data::Struct(DataStruct {
@@ -483,7 +479,6 @@
                 segments: punctuated![PathSegment::from(ident("inert"))],
             },
             tts: TokenStream::from_iter(vec![op('<'), word("T"), op('>')]),
-            is_sugared_doc: false,
         }],
         generics: Generics::default(),
         data: Data::Struct(DataStruct {
@@ -522,7 +517,6 @@
                 ],
             },
             tts: TokenStream::new(),
-            is_sugared_doc: false,
         }],
         generics: Generics::default(),
         data: Data::Struct(DataStruct {
diff --git a/tests/test_expr.rs b/tests/test_expr.rs
deleted file mode 100644
index 4b5bf8c..0000000
--- a/tests/test_expr.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2018 Syn Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(feature = "extra-traits")]
-
-extern crate proc_macro2;
-extern crate syn;
-use proc_macro2::*;
-use syn::*;
-
-macro_rules! assert_let {
-    ($p:pat = $e:expr) => {
-        assert_let!($p = $e; {})
-    };
-
-    ($p:pat = $e:expr; $body:block) => {
-        if let $p = $e
-            $body
-        else {
-            panic!("Expected to match {} but got {:?}", stringify!($p), $e)
-        }
-    };
-}
-
-#[test]
-#[cfg(feature = "full")]
-fn test_catch_expr() {
-    // Taken from tests/rust/src/test/run-pass/catch-expr.rs
-    let raw = r#"
-        struct catch {}
-
-        pub fn main() {
-            let catch_result = do catch {
-                let x = 5;
-                x
-            };
-            assert_eq!(catch_result, 5);
-
-            let mut catch = true;
-            while catch { catch = false; }
-            assert_eq!(catch, false);
-
-            catch = if catch { false } else { true };
-            assert_eq!(catch, true);
-
-            match catch {
-                _ => {}
-            };
-
-            let catch_err = do catch {
-                Err(22)?;
-                Ok(1)
-            };
-            assert_eq!(catch_err, Err(22));
-
-            let catch_okay: Result<i32, i32> = do catch {
-                if false { Err(25)?; }
-                Ok::<(), i32>(())?;
-                Ok(28)
-            };
-            assert_eq!(catch_okay, Ok(28));
-
-            let catch_from_loop: Result<i32, i32> = do catch {
-                for i in 0..10 {
-                    if i < 5 { Ok::<i32, i32>(i)?; } else { Err(i)?; }
-                }
-                Ok(22)
-            };
-            assert_eq!(catch_from_loop, Err(5));
-
-            let cfg_init;
-            let _res: Result<(), ()> = do catch {
-                cfg_init = 5;
-                Ok(())
-            };
-            assert_eq!(cfg_init, 5);
-
-            let cfg_init_2;
-            let _res: Result<(), ()> = do catch {
-                cfg_init_2 = 6;
-                Err(())?;
-                Ok(())
-            };
-            assert_eq!(cfg_init_2, 6);
-
-            let my_string = "test".to_string();
-            let res: Result<&str, ()> = do catch {
-                Ok(&my_string)
-            };
-            assert_eq!(res, Ok("test"));
-        }
-    "#;
-
-    let actual: File = syn::parse_str(raw).unwrap();
-
-    assert_let!(Item::Struct(ItemStruct { ref ident, .. }) = actual.items[0]; {
-        assert_eq!(ident, "catch");
-    });
-
-    assert_let!(Item::Fn(ItemFn { ref block, .. }) = actual.items[1]; {
-        assert_let!(Stmt::Local(ref local) = block.stmts[0]; {
-            assert_let!(Local { init: Some((_, ref init_expr)), .. } = *local; {
-                assert_let!(Expr::Catch(..) = **init_expr);
-            });
-        });
-
-        assert_let!(Stmt::Local(ref local) = block.stmts[2]; {
-            assert_let!(Pat::Ident(PatIdent { by_ref: None, mutability: Some(_), ref ident, .. }) = local.pats.iter().next().unwrap(); {
-                assert_eq!(ident, "catch");
-            });
-        });
-
-        assert_let!(Stmt::Expr(ref expr) = block.stmts[3]; {
-            assert_let!(Expr::While(ExprWhile { ref cond, .. }) = *expr; {
-                assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
-                    let name = Ident::new("catch", Span::call_site());
-                    assert_eq!(*path, name.into());
-                });
-            });
-        });
-
-        assert_let!(Stmt::Semi(ref expr, _) = block.stmts[5]; {
-            assert_let!(Expr::Assign(ExprAssign { ref left, ref right, .. }) = *expr; {
-                assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **left; {
-                    let name = Ident::new("catch", Span::call_site());
-                    assert_eq!(*path, name.into());
-                });
-
-                assert_let!(Expr::If(ExprIf { ref cond, .. }) = **right; {
-                    assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
-                        let name = Ident::new("catch", Span::call_site());
-                        assert_eq!(*path, name.into());
-                    });
-                });
-            });
-        });
-
-        assert_let!(Stmt::Semi(ref expr, _) = block.stmts[7]; {
-            assert_let!(Expr::Match(ExprMatch { ref expr, .. }) = *expr; {
-                assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **expr; {
-                    let name = Ident::new("catch", Span::call_site());
-                    assert_eq!(*path, name.into());
-                });
-            });
-        });
-    });
-}
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index fe33fbd..33e7768 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -54,7 +54,6 @@
                     style: AttrStyle::Outer,
                     path: ident("may_dangle").into(),
                     tts: TokenStream::new(),
-                    is_sugared_doc: false,
                 }],
                 ident: ident("T"),
                 bounds: punctuated![TypeParamBound::Lifetime(Lifetime::new(
diff --git a/tests/test_ident.rs b/tests/test_ident.rs
index 73187d3..498e8be 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::parse::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..92109ce 100644
--- a/tests/test_meta_item.rs
+++ b/tests/test_meta_item.rs
@@ -170,12 +170,12 @@
 fn run_test<T: Into<Meta>>(input: &str, expected: T) {
     let tokens = input.parse::<TokenStream>().unwrap();
     let buf = TokenBuffer::new2(tokens);
-    let attr = match Attribute::parse_outer(buf.begin()) {
+    let attr = match Attribute::old_parse_outer(buf.begin()) {
         Ok((e, rest)) => {
             assert!(rest.eof());
             e
         }
-        Err(err) => panic!(err),
+        Err(err) => panic!(err.to_string()),
     };
     assert_eq!(expected.into(), attr.interpret_meta().unwrap());
 }
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
index b272d49..a85bf27 100644
--- a/tests/test_precedence.rs
+++ b/tests/test_precedence.rs
@@ -228,18 +228,6 @@
     impl Folder for BracketsFolder {
         fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
             e.map(|e| match e.node {
-                ExprKind::Block(_, label) if label.is_some() => Expr {
-                    id: ast::DUMMY_NODE_ID,
-                    node: ExprKind::Paren(P(e)),
-                    span: DUMMY_SP,
-                    attrs: ThinVec::new(),
-                },
-                ExprKind::TryBlock(_) => Expr {
-                    id: ast::DUMMY_NODE_ID,
-                    node: ExprKind::Paren(P(e)),
-                    span: DUMMY_SP,
-                    attrs: ThinVec::new(),
-                },
                 ExprKind::If(..) | ExprKind::Block(..) | ExprKind::IfLet(..) => {
                     fold::noop_fold_expr(e, self)
                 }
diff --git a/tests/test_token_trees.rs b/tests/test_token_trees.rs
index c385727..02d8f48 100644
--- a/tests/test_token_trees.rs
+++ b/tests/test_token_trees.rs
@@ -82,7 +82,6 @@
             bracket_token: Default::default(),
             path: Ident::new("test", Span::call_site()).into(),
             tts,
-            is_sugared_doc: false,
         }
     }