Parse more items
diff --git a/src/derive.rs b/src/derive.rs
index e956277..5ca033a 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -149,7 +149,9 @@
         }
     }
 
-    fn data_struct(input: ParseStream) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)> {
+    pub 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]) {
@@ -183,7 +185,7 @@
         }
     }
 
-    fn data_enum(
+    pub fn data_enum(
         input: ParseStream,
     ) -> Result<(
         Option<WhereClause>,
@@ -199,7 +201,7 @@
         Ok((where_clause, brace, variants))
     }
 
-    fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
+    pub fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
         let where_clause = input.parse()?;
         let fields = input.parse()?;
         Ok((where_clause, fields))
diff --git a/src/file.rs b/src/file.rs
index d692f11..7cb9f95 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -98,7 +98,7 @@
                 items: {
                     let mut items = Vec::new();
                     while !input.is_empty() {
-                        items.push(input.parse_synom(Item::parse)?);
+                        items.push(input.parse()?);
                     }
                     items
                 },
diff --git a/src/item.rs b/src/item.rs
index 2e14a49..6776fa6 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -758,39 +758,108 @@
     use synom::ext::IdentExt;
     use synom::Synom;
 
-    impl_synom!(Item "item" alt!(
-        syn!(ItemExternCrate) => { Item::ExternCrate }
-        |
-        syn!(ItemUse) => { Item::Use }
-        |
-        syn!(ItemStatic) => { Item::Static }
-        |
-        syn!(ItemConst) => { Item::Const }
-        |
-        syn!(ItemFn) => { Item::Fn }
-        |
-        syn!(ItemMod) => { Item::Mod }
-        |
-        syn!(ItemForeignMod) => { Item::ForeignMod }
-        |
-        syn!(ItemType) => { Item::Type }
-        |
-        syn!(ItemExistential) => { Item::Existential }
-        |
-        syn!(ItemStruct) => { Item::Struct }
-        |
-        syn!(ItemEnum) => { Item::Enum }
-        |
-        syn!(ItemUnion) => { Item::Union }
-        |
-        syn!(ItemTrait) => { Item::Trait }
-        |
-        syn!(ItemImpl) => { Item::Impl }
-        |
-        syn!(ItemMacro) => { Item::Macro }
-        |
-        syn!(ItemMacro2) => { Item::Macro2 }
-    ));
+    impl Parse for Item {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let ahead = input.fork();
+            ahead.call(Attribute::parse_outer)?;
+            let vis: Visibility = ahead.parse()?;
+
+            let lookahead = ahead.lookahead1();
+            if lookahead.peek(Token![extern]) {
+                ahead.parse::<Token![extern]>()?;
+                let lookahead = ahead.lookahead1();
+                if lookahead.peek(Token![crate]) {
+                    input.parse().map(Item::ExternCrate)
+                } else if lookahead.peek(Token![fn]) {
+                    input.parse().map(Item::Fn)
+                } else if lookahead.peek(token::Brace) {
+                    input.parse().map(Item::ForeignMod)
+                } else if lookahead.peek(LitStr) {
+                    ahead.parse::<LitStr>()?;
+                    let lookahead = ahead.lookahead1();
+                    if lookahead.peek(token::Brace) {
+                        input.parse().map(Item::ForeignMod)
+                    } else if lookahead.peek(Token![fn]) {
+                        input.parse().map(Item::Fn)
+                    } else {
+                        Err(lookahead.error())
+                    }
+                } else {
+                    Err(lookahead.error())
+                }
+            } else if lookahead.peek(Token![use]) {
+                input.parse().map(Item::Use)
+            } else if lookahead.peek(Token![static]) {
+                input.parse().map(Item::Static)
+            } else if lookahead.peek(Token![const]) {
+                ahead.parse::<Token![const]>()?;
+                let lookahead = ahead.lookahead1();
+                if lookahead.peek(Ident) {
+                    input.parse().map(Item::Const)
+                } else if lookahead.peek(Token![unsafe])
+                    || lookahead.peek(Token![async])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![fn])
+                {
+                    input.parse().map(Item::Fn)
+                } else {
+                    Err(lookahead.error())
+                }
+            } else if lookahead.peek(Token![unsafe]) {
+                ahead.parse::<Token![unsafe]>()?;
+                let lookahead = ahead.lookahead1();
+                if lookahead.peek(Token![trait])
+                    || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
+                {
+                    input.parse().map(Item::Trait)
+                } else if lookahead.peek(Token![impl ]) {
+                    input.parse().map(Item::Impl)
+                } else if lookahead.peek(Token![async])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![fn])
+                {
+                    input.parse().map(Item::Fn)
+                } else {
+                    Err(lookahead.error())
+                }
+            } else if lookahead.peek(Token![async]) || lookahead.peek(Token![fn]) {
+                input.parse().map(Item::Fn)
+            } else if lookahead.peek(Token![mod]) {
+                input.parse().map(Item::Mod)
+            } else if lookahead.peek(Token![type]) {
+                input.parse().map(Item::Type)
+            } else if lookahead.peek(Token![existential]) {
+                input.parse().map(Item::Existential)
+            } else if lookahead.peek(Token![struct]) {
+                input.parse().map(Item::Struct)
+            } else if lookahead.peek(Token![enum]) {
+                input.parse().map(Item::Enum)
+            } else if lookahead.peek(Token![union]) && ahead.peek2(Ident) {
+                input.parse().map(Item::Union)
+            } else if lookahead.peek(Token![trait])
+                || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
+            {
+                input.parse().map(Item::Trait)
+            } else if lookahead.peek(Token![impl ])
+                || lookahead.peek(Token![default]) && !ahead.peek2(Token![!])
+            {
+                input.parse().map(Item::Impl)
+            } else if lookahead.peek(Token![macro]) {
+                input.parse().map(Item::Macro2)
+            } else if vis.is_inherited()
+                && (lookahead.peek(Ident)
+                    || lookahead.peek(Token![self])
+                    || lookahead.peek(Token![super])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![crate])
+                    || lookahead.peek(Token![::]))
+            {
+                input.parse().map(Item::Macro)
+            } else {
+                Err(lookahead.error())
+            }
+        }
+    }
 
     impl Parse for ItemMacro {
         fn parse(input: ParseStream) -> Result<Self> {
@@ -799,7 +868,7 @@
             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) {
+            let semi_token: Option<Token![;]> = if !delimiter.is_brace() {
                 Some(input.parse()?)
             } else {
                 None
@@ -1077,7 +1146,7 @@
 
                 let mut items = Vec::new();
                 while !content.is_empty() {
-                    items.push(content.parse_synom(Item::parse)?);
+                    items.push(content.parse()?);
                 }
 
                 Ok(ItemMod {
@@ -1108,7 +1177,7 @@
             let inner_attrs = content.call(Attribute::parse_inner)?;
             let mut items = Vec::new();
             while !content.is_empty() {
-                items.push(content.parse_synom(ForeignItem::parse)?);
+                items.push(content.parse()?);
             }
 
             Ok(ItemForeignMod {
@@ -1124,15 +1193,33 @@
         }
     }
 
-    impl_synom!(ForeignItem "foreign item" alt!(
-        syn!(ForeignItemFn) => { ForeignItem::Fn }
-        |
-        syn!(ForeignItemStatic) => { ForeignItem::Static }
-        |
-        syn!(ForeignItemType) => { ForeignItem::Type }
-        |
-        syn!(ForeignItemMacro) => { ForeignItem::Macro }
-    ));
+    impl Parse for ForeignItem {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let ahead = input.fork();
+            ahead.call(Attribute::parse_outer)?;
+            let vis: Visibility = ahead.parse()?;
+
+            let lookahead = ahead.lookahead1();
+            if lookahead.peek(Token![fn]) {
+                input.parse().map(ForeignItem::Fn)
+            } else if lookahead.peek(Token![static]) {
+                input.parse().map(ForeignItem::Static)
+            } else if lookahead.peek(Token![type]) {
+                input.parse().map(ForeignItem::Type)
+            } else if vis.is_inherited()
+                && (lookahead.peek(Ident)
+                    || lookahead.peek(Token![self])
+                    || lookahead.peek(Token![super])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![crate])
+                    || lookahead.peek(Token![::]))
+            {
+                input.parse().map(ForeignItem::Macro)
+            } else {
+                Err(lookahead.error())
+            }
+        }
+    }
 
     impl Parse for ForeignItemFn {
         fn parse(input: ParseStream) -> Result<Self> {
@@ -1206,7 +1293,7 @@
         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) {
+            let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
                 None
             } else {
                 Some(input.parse()?)
@@ -1258,122 +1345,208 @@
         }
     }
 
-    impl_synom!(ItemStruct "struct item" switch!(
-        map!(syn!(DeriveInput), Into::into),
-        Item::Struct(item) => value!(item)
-        |
-        _ => reject!()
-    ));
+    impl Parse for ItemStruct {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let vis = input.parse::<Visibility>()?;
+            let struct_token = input.parse::<Token![struct]>()?;
+            let ident = input.parse::<Ident>()?;
+            let generics = input.parse::<Generics>()?;
+            let (where_clause, fields, semi_token) = derive::parsing::data_struct(input)?;
+            Ok(ItemStruct {
+                attrs: attrs,
+                vis: vis,
+                struct_token: struct_token,
+                ident: ident,
+                generics: Generics {
+                    where_clause: where_clause,
+                    ..generics
+                },
+                fields: fields,
+                semi_token: semi_token,
+            })
+        }
+    }
 
-    impl_synom!(ItemEnum "enum item" switch!(
-        map!(syn!(DeriveInput), Into::into),
-        Item::Enum(item) => value!(item)
-        |
-        _ => reject!()
-    ));
+    impl Parse for ItemEnum {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let vis = input.parse::<Visibility>()?;
+            let enum_token = input.parse::<Token![enum]>()?;
+            let ident = input.parse::<Ident>()?;
+            let generics = input.parse::<Generics>()?;
+            let (where_clause, brace_token, variants) = derive::parsing::data_enum(input)?;
+            Ok(ItemEnum {
+                attrs: attrs,
+                vis: vis,
+                enum_token: enum_token,
+                ident: ident,
+                generics: Generics {
+                    where_clause: where_clause,
+                    ..generics
+                },
+                brace_token: brace_token,
+                variants: variants,
+            })
+        }
+    }
 
-    impl_synom!(ItemUnion "union item" do_parse!(
-        attrs: many0!(Attribute::old_parse_outer) >>
-        vis: syn!(Visibility) >>
-        union_: keyword!(union) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        fields: syn!(FieldsNamed) >>
-        (ItemUnion {
-            attrs: attrs,
-            vis: vis,
-            union_token: union_,
-            ident: ident,
-            generics: Generics {
-                where_clause: where_clause,
-                ..generics
-            },
-            fields: fields,
-        })
-    ));
+    impl Parse for ItemUnion {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let vis = input.parse::<Visibility>()?;
+            let union_token = input.parse::<Token![union]>()?;
+            let ident = input.parse::<Ident>()?;
+            let generics = input.parse::<Generics>()?;
+            let (where_clause, fields) = derive::parsing::data_union(input)?;
+            Ok(ItemUnion {
+                attrs: attrs,
+                vis: vis,
+                union_token: union_token,
+                ident: ident,
+                generics: Generics {
+                    where_clause: where_clause,
+                    ..generics
+                },
+                fields: fields,
+            })
+        }
+    }
 
-    impl_synom!(ItemTrait "trait item" do_parse!(
-        attrs: many0!(Attribute::old_parse_outer) >>
-        vis: syn!(Visibility) >>
-        unsafety: option!(keyword!(unsafe)) >>
-        auto_: option!(keyword!(auto)) >>
-        trait_: keyword!(trait) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        colon: option!(punct!(:)) >>
-        bounds: cond!(colon.is_some(), Punctuated::parse_separated_nonempty) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        body: braces!(many0!(TraitItem::parse)) >>
-        (ItemTrait {
-            attrs: attrs,
-            vis: vis,
-            unsafety: unsafety,
-            auto_token: auto_,
-            trait_token: trait_,
-            ident: ident,
-            generics: Generics {
-                where_clause: where_clause,
-                ..generics
-            },
-            colon_token: colon,
-            supertraits: bounds.unwrap_or_default(),
-            brace_token: body.0,
-            items: body.1,
-        })
-    ));
-
-    impl_synom!(TraitItem "trait item" alt!(
-        syn!(TraitItemConst) => { TraitItem::Const }
-        |
-        syn!(TraitItemMethod) => { TraitItem::Method }
-        |
-        syn!(TraitItemType) => { TraitItem::Type }
-        |
-        syn!(TraitItemMacro) => { TraitItem::Macro }
-    ));
-
-    impl_synom!(TraitItemConst "const trait item" do_parse!(
-        attrs: many0!(Attribute::old_parse_outer) >>
-        const_: keyword!(const) >>
-        ident: syn!(Ident) >>
-        colon: punct!(:) >>
-        ty: syn!(Type) >>
-        default: option!(tuple!(punct!(=), syn!(Expr))) >>
-        semi: punct!(;) >>
-        (TraitItemConst {
-            attrs: attrs,
-            const_token: const_,
-            ident: ident,
-            colon_token: colon,
-            ty: ty,
-            default: default,
-            semi_token: semi,
-        })
-    ));
-
-    impl_synom!(TraitItemMethod "method trait item" do_parse!(
-        outer_attrs: many0!(Attribute::old_parse_outer) >>
-        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)) >>
-        body: option!(braces!(tuple!(
-            many0!(Attribute::old_parse_inner),
-            call!(Block::parse_within),
-        ))) >>
-        semi: cond!(body.is_none(), punct!(;)) >>
-        ({
-            let (inner_attrs, stmts) = match body {
-                Some((b, (inner_attrs, stmts))) => (inner_attrs, Some((stmts, b))),
-                None => (Vec::new(), None),
+    impl Parse for ItemTrait {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let vis: Visibility = input.parse()?;
+            let unsafety: Option<Token![unsafe]> = input.parse()?;
+            let auto_token: Option<Token![auto]> = input.parse()?;
+            let trait_token: Token![trait] = input.parse()?;
+            let ident: Ident = input.parse()?;
+            let mut generics: Generics = input.parse()?;
+            let colon_token: Option<Token![:]> = input.parse()?;
+            let supertraits = if colon_token.is_some() {
+                input.parse_synom(Punctuated::parse_separated_nonempty)?
+            } else {
+                Punctuated::new()
             };
-            TraitItemMethod {
+            generics.where_clause = input.parse()?;
+
+            let content;
+            let brace_token = braced!(content in input);
+            let mut items = Vec::new();
+            while !content.is_empty() {
+                items.push(content.parse()?);
+            }
+
+            Ok(ItemTrait {
+                attrs: attrs,
+                vis: vis,
+                unsafety: unsafety,
+                auto_token: auto_token,
+                trait_token: trait_token,
+                ident: ident,
+                generics: generics,
+                colon_token: colon_token,
+                supertraits: supertraits,
+                brace_token: brace_token,
+                items: items,
+            })
+        }
+    }
+
+    impl Parse for TraitItem {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let ahead = input.fork();
+            ahead.call(Attribute::parse_outer)?;
+
+            let lookahead = ahead.lookahead1();
+            if lookahead.peek(Token![const]) {
+                ahead.parse::<Token![const]>()?;
+                let lookahead = ahead.lookahead1();
+                if lookahead.peek(Ident) {
+                    input.parse().map(TraitItem::Const)
+                } else if lookahead.peek(Token![unsafe])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![fn])
+                {
+                    input.parse().map(TraitItem::Method)
+                } else {
+                    Err(lookahead.error())
+                }
+            } else if lookahead.peek(Token![unsafe])
+                || lookahead.peek(Token![extern])
+                || lookahead.peek(Token![fn])
+            {
+                input.parse().map(TraitItem::Method)
+            } else if lookahead.peek(Token![type]) {
+                input.parse().map(TraitItem::Type)
+            } else if lookahead.peek(Ident)
+                || lookahead.peek(Token![self])
+                || lookahead.peek(Token![super])
+                || lookahead.peek(Token![extern])
+                || lookahead.peek(Token![crate])
+                || lookahead.peek(Token![::])
+            {
+                input.parse().map(TraitItem::Macro)
+            } else {
+                Err(lookahead.error())
+            }
+        }
+    }
+
+    impl Parse for TraitItemConst {
+        fn parse(input: ParseStream) -> Result<Self> {
+            Ok(TraitItemConst {
+                attrs: input.call(Attribute::parse_outer)?,
+                const_token: input.parse()?,
+                ident: input.parse()?,
+                colon_token: input.parse()?,
+                ty: input.parse()?,
+                default: {
+                    if input.peek(Token![=]) {
+                        let eq_token: Token![=] = input.parse()?;
+                        let default = input.parse_synom(Expr::parse)?;
+                        Some((eq_token, default))
+                    } else {
+                        None
+                    }
+                },
+                semi_token: input.parse()?,
+            })
+        }
+    }
+
+    impl Parse for TraitItemMethod {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let outer_attrs = input.call(Attribute::parse_outer)?;
+            let constness: Option<Token![const]> = input.parse()?;
+            let unsafety: Option<Token![unsafe]> = 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 lookahead = input.lookahead1();
+            let (brace_token, inner_attrs, stmts, semi_token) = if lookahead.peek(token::Brace) {
+                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)?;
+                (Some(brace_token), inner_attrs, stmts, None)
+            } else if lookahead.peek(Token![;]) {
+                let semi_token: Token![;] = input.parse()?;
+                (None, Vec::new(), Vec::new(), Some(semi_token))
+            } else {
+                return Err(lookahead.error());
+            };
+
+            Ok(TraitItemMethod {
                 attrs: {
                     let mut attrs = outer_attrs;
                     attrs.extend(inner_attrs);
@@ -1386,10 +1559,10 @@
                     abi: abi,
                     ident: ident,
                     decl: FnDecl {
-                        inputs: inputs.1,
-                        output: ret,
-                        fn_token: fn_,
-                        paren_token: inputs.0,
+                        fn_token: fn_token,
+                        paren_token: paren_token,
+                        inputs: inputs,
+                        output: output,
                         variadic: None,
                         generics: Generics {
                             where_clause: where_clause,
@@ -1397,106 +1570,178 @@
                         },
                     },
                 },
-                default: stmts.map(|stmts| {
-                    Block {
-                        stmts: stmts.0,
-                        brace_token: stmts.1,
-                    }
+                default: brace_token.map(|brace_token| Block {
+                    brace_token: brace_token,
+                    stmts: stmts,
                 }),
-                semi_token: semi,
+                semi_token: semi_token,
+            })
+        }
+    }
+
+    impl Parse for TraitItemType {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let type_token: Token![type] = input.parse()?;
+            let ident: Ident = input.parse()?;
+            let mut generics: Generics = input.parse()?;
+            let colon_token: Option<Token![:]> = input.parse()?;
+            let bounds = if colon_token.is_some() {
+                input.parse_synom(Punctuated::parse_separated_nonempty)?
+            } else {
+                Punctuated::new()
+            };
+            generics.where_clause = input.parse()?;
+            let default = if input.peek(Token![=]) {
+                let eq_token: Token![=] = input.parse()?;
+                let default: Type = input.parse()?;
+                Some((eq_token, default))
+            } else {
+                None
+            };
+            let semi_token: Token![;] = input.parse()?;
+
+            Ok(TraitItemType {
+                attrs: attrs,
+                type_token: type_token,
+                ident: ident,
+                generics: generics,
+                colon_token: colon_token,
+                bounds: bounds,
+                default: default,
+                semi_token: semi_token,
+            })
+        }
+    }
+
+    impl Parse for TraitItemMacro {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let attrs = input.call(Attribute::parse_outer)?;
+            let mac: Macro = input.parse()?;
+            let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+                None
+            } else {
+                Some(input.parse()?)
+            };
+            Ok(TraitItemMacro {
+                attrs: attrs,
+                mac: mac,
+                semi_token: semi_token,
+            })
+        }
+    }
+
+    impl Parse for ItemImpl {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let outer_attrs = input.call(Attribute::parse_outer)?;
+            let defaultness: Option<Token![default]> = input.parse()?;
+            let unsafety: Option<Token![unsafe]> = input.parse()?;
+            let impl_token: Token![impl ] = input.parse()?;
+            let generics: Generics = input.parse()?;
+            let trait_ = {
+                let ahead = input.fork();
+                if ahead.parse::<Option<Token![!]>>().is_ok()
+                    && ahead.parse::<Path>().is_ok()
+                    && ahead.parse::<Token![for]>().is_ok()
+                {
+                    let polarity: Option<Token![!]> = input.parse()?;
+                    let path: Path = input.parse()?;
+                    let for_token: Token![for] = input.parse()?;
+                    Some((polarity, path, for_token))
+                } else {
+                    None
+                }
+            };
+            let self_ty: Type = 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 mut items = Vec::new();
+            while !content.is_empty() {
+                items.push(content.parse()?);
             }
-        })
-    ));
 
-    impl_synom!(TraitItemType "trait item type" do_parse!(
-        attrs: many0!(Attribute::old_parse_outer) >>
-        type_: keyword!(type) >>
-        ident: syn!(Ident) >>
-        generics: syn!(Generics) >>
-        colon: option!(punct!(:)) >>
-        bounds: cond!(colon.is_some(), Punctuated::parse_separated_nonempty) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        default: option!(tuple!(punct!(=), syn!(Type))) >>
-        semi: punct!(;) >>
-        (TraitItemType {
-            attrs: attrs,
-            type_token: type_,
-            ident: ident,
-            generics: Generics {
-                where_clause: where_clause,
-                ..generics
-            },
-            colon_token: colon,
-            bounds: bounds.unwrap_or_default(),
-            default: default,
-            semi_token: semi,
-        })
-    ));
+            Ok(ItemImpl {
+                attrs: {
+                    let mut attrs = outer_attrs;
+                    attrs.extend(inner_attrs);
+                    attrs
+                },
+                defaultness: defaultness,
+                unsafety: unsafety,
+                impl_token: impl_token,
+                generics: Generics {
+                    where_clause: where_clause,
+                    ..generics
+                },
+                trait_: trait_,
+                self_ty: Box::new(self_ty),
+                brace_token: brace_token,
+                items: items,
+            })
+        }
+    }
 
-    impl_synom!(TraitItemMacro "trait item macro" do_parse!(
-        attrs: many0!(Attribute::old_parse_outer) >>
-        mac: syn!(Macro) >>
-        semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
-        (TraitItemMacro {
-            attrs: attrs,
-            mac: mac,
-            semi_token: semi,
-        })
-    ));
+    impl Parse for ImplItem {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let ahead = input.fork();
+            ahead.call(Attribute::parse_outer)?;
+            let vis: Visibility = ahead.parse()?;
 
-    impl_synom!(ItemImpl "impl item" do_parse!(
-        outer_attrs: many0!(Attribute::old_parse_outer) >>
-        defaultness: option!(keyword!(default)) >>
-        unsafety: option!(keyword!(unsafe)) >>
-        impl_: keyword!(impl) >>
-        generics: syn!(Generics) >>
-        polarity_path: alt!(
-            do_parse!(
-                polarity: option!(punct!(!)) >>
-                path: syn!(Path) >>
-                for_: keyword!(for) >>
-                (Some((polarity, path, for_)))
-            )
-            |
-            epsilon!() => { |_| None }
-        ) >>
-        self_ty: syn!(Type) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        inner: braces!(tuple!(
-            many0!(Attribute::old_parse_inner),
-            many0!(ImplItem::parse),
-        )) >>
-        (ItemImpl {
-            attrs: {
-                let mut attrs = outer_attrs;
-                attrs.extend((inner.1).0);
-                attrs
-            },
-            defaultness: defaultness,
-            unsafety: unsafety,
-            impl_token: impl_,
-            generics: Generics {
-                where_clause: where_clause,
-                ..generics
-            },
-            trait_: polarity_path,
-            self_ty: Box::new(self_ty),
-            brace_token: inner.0,
-            items: (inner.1).1,
-        })
-    ));
+            let mut lookahead = ahead.lookahead1();
+            let defaultness = if lookahead.peek(Token![default]) && !ahead.peek2(Token![!]) {
+                let defaultness: Token![default] = ahead.parse()?;
+                lookahead = ahead.lookahead1();
+                Some(defaultness)
+            } else {
+                None
+            };
 
-    impl_synom!(ImplItem "item in impl block" alt!(
-        syn!(ImplItemConst) => { ImplItem::Const }
-        |
-        syn!(ImplItemMethod) => { ImplItem::Method }
-        |
-        syn!(ImplItemType) => { ImplItem::Type }
-        |
-        syn!(ImplItemExistential) => { ImplItem::Existential }
-        |
-        syn!(ImplItemMacro) => { ImplItem::Macro }
-    ));
+            if lookahead.peek(Token![const]) {
+                ahead.parse::<Token![const]>()?;
+                let lookahead = ahead.lookahead1();
+                if lookahead.peek(Ident) {
+                    input.parse().map(ImplItem::Const)
+                } else if lookahead.peek(Token![unsafe])
+                    || lookahead.peek(Token![async])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![fn])
+                {
+                    input.parse().map(ImplItem::Method)
+                } else {
+                    Err(lookahead.error())
+                }
+            } else if lookahead.peek(Token![unsafe])
+                || lookahead.peek(Token![async])
+                || lookahead.peek(Token![extern])
+                || lookahead.peek(Token![fn])
+            {
+                input.parse().map(ImplItem::Method)
+            } else if lookahead.peek(Token![type]) {
+                input.parse().map(ImplItem::Type)
+            } else if vis.is_inherited()
+                && defaultness.is_none()
+                && lookahead.peek(Token![existential])
+            {
+                input.parse().map(ImplItem::Existential)
+            } else if vis.is_inherited()
+                && defaultness.is_none()
+                && (lookahead.peek(Ident)
+                    || lookahead.peek(Token![self])
+                    || lookahead.peek(Token![super])
+                    || lookahead.peek(Token![extern])
+                    || lookahead.peek(Token![crate])
+                    || lookahead.peek(Token![::]))
+            {
+                input.parse().map(ImplItem::Macro)
+            } else {
+                Err(lookahead.error())
+            }
+        }
+    }
 
     impl Parse for ImplItemConst {
         fn parse(input: ParseStream) -> Result<Self> {
@@ -1515,56 +1760,64 @@
         }
     }
 
-    impl_synom!(ImplItemMethod "method in impl block" do_parse!(
-        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) >>
-        generics: syn!(Generics) >>
-        inputs: parens!(Punctuated::parse_terminated) >>
-        ret: syn!(ReturnType) >>
-        where_clause: option!(syn!(WhereClause)) >>
-        inner_attrs_stmts: braces!(tuple!(
-            many0!(Attribute::old_parse_inner),
-            call!(Block::parse_within),
-        )) >>
-        (ImplItemMethod {
-            attrs: {
-                let mut attrs = outer_attrs;
-                attrs.extend((inner_attrs_stmts.1).0);
-                attrs
-            },
-            vis: vis,
-            defaultness: defaultness,
-            sig: MethodSig {
-                constness: constness,
-                unsafety: unsafety,
-                asyncness: asyncness,
-                abi: abi,
-                ident: ident,
-                decl: FnDecl {
-                    fn_token: fn_,
-                    paren_token: inputs.0,
-                    inputs: inputs.1,
-                    output: ret,
-                    generics: Generics {
-                        where_clause: where_clause,
-                        ..generics
-                    },
-                    variadic: None,
+    impl Parse for ImplItemMethod {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let outer_attrs = input.call(Attribute::parse_outer)?;
+            let vis: Visibility = input.parse()?;
+            let defaultness: Option<Token![default]> = 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(ImplItemMethod {
+                attrs: {
+                    let mut attrs = outer_attrs;
+                    attrs.extend(inner_attrs);
+                    attrs
                 },
-            },
-            block: Block {
-                brace_token: inner_attrs_stmts.0,
-                stmts: (inner_attrs_stmts.1).1,
-            },
-        })
-    ));
+                vis: vis,
+                defaultness: defaultness,
+                sig: MethodSig {
+                    constness: constness,
+                    unsafety: unsafety,
+                    asyncness: asyncness,
+                    abi: abi,
+                    ident: ident,
+                    decl: FnDecl {
+                        fn_token: fn_token,
+                        paren_token: paren_token,
+                        inputs: inputs,
+                        output: output,
+                        variadic: None,
+                        generics: Generics {
+                            where_clause: where_clause,
+                            ..generics
+                        },
+                    },
+                },
+                block: Block {
+                    brace_token: brace_token,
+                    stmts: stmts,
+                },
+            })
+        }
+    }
 
     impl Parse for ImplItemType {
         fn parse(input: ParseStream) -> Result<Self> {
@@ -1606,7 +1859,7 @@
         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) {
+            let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
                 None
             } else {
                 Some(input.parse()?)
@@ -1619,10 +1872,21 @@
         }
     }
 
-    fn is_brace(delimiter: &MacroDelimiter) -> bool {
-        match *delimiter {
-            MacroDelimiter::Brace(_) => true,
-            MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
+    impl Visibility {
+        fn is_inherited(&self) -> bool {
+            match *self {
+                Visibility::Inherited => true,
+                _ => false,
+            }
+        }
+    }
+
+    impl MacroDelimiter {
+        fn is_brace(&self) -> bool {
+            match *self {
+                MacroDelimiter::Brace(_) => true,
+                MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
+            }
         }
     }
 }
diff --git a/src/lit.rs b/src/lit.rs
index 908ff89..5b2bf86 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -340,6 +340,13 @@
                 self.$field.to_string().hash(state);
             }
         }
+
+        #[cfg(feature = "parsing")]
+        #[doc(hidden)]
+        #[allow(non_snake_case)]
+        pub fn $ty(marker: lookahead::TokenMarker) -> $ty {
+            match marker {}
+        }
     };
 }
 
diff --git a/src/macros.rs b/src/macros.rs
index 5966e38..519c73c 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -178,16 +178,3 @@
 
     ($($rest:tt)*) => (ast_struct! { $($rest)* });
 }
-
-#[cfg(all(feature = "parsing", feature = "full"))]
-macro_rules! impl_synom {
-    ($t:ident $description:tt $($parser:tt)+) => {
-        impl Synom for $t {
-            named!(parse -> Self, $($parser)+);
-
-            fn description() -> Option<&'static str> {
-                Some($description)
-            }
-        }
-    }
-}