Switch from IResult to PResult in syn
diff --git a/src/attr.rs b/src/attr.rs
index 76b1503..5bff9be 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -292,7 +292,7 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use synom::IResult;
+    use synom::{PResult, Cursor, parse_error};
     use synom::tokens::*;
     use proc_macro2::{TokenKind, OpKind, TokenTree};
 
@@ -305,102 +305,96 @@
 
     impl Attribute {
         #[cfg(feature = "full")]
-        pub fn parse_inner(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    pound: syn!(Pound) >>
-                    bang: syn!(Bang) >>
-                    path_and_tts: brackets!(tuple!(
-                        call!(::Path::parse_mod_style),
-                        call!(::TokenTree::parse_list)
-                    )) >>
-                    ({
-                        let ((path, tts), bracket) = path_and_tts;
+        named!(pub parse_inner -> Self, alt!(
+            do_parse!(
+                pound: syn!(Pound) >>
+                bang: syn!(Bang) >>
+                path_and_tts: brackets!(tuple!(
+                    call!(::Path::parse_mod_style),
+                    call!(::TokenTree::parse_list)
+                )) >>
+                ({
+                    let ((path, tts), bracket) = path_and_tts;
 
-                        Attribute {
-                            style: AttrStyle::Inner(bang),
-                            path: path,
-                            tts: tts,
-                            is_sugared_doc: false,
-                            pound_token: pound,
-                            bracket_token: bracket,
-                        }
-                    })
-                )
-                |
-                map!(
-                    lit_doc_comment,
-                    |lit| Attribute {
-                        style: AttrStyle::Inner(tokens::Bang::default()),
-                        path: "doc".into(),
-                        tts: vec![
-                            ::TokenTree(eq()),
-                            ::TokenTree(lit),
-                        ],
-                        is_sugared_doc: true,
-                        pound_token: tokens::Pound::default(),
-                        bracket_token: tokens::Bracket::default(),
+                    Attribute {
+                        style: AttrStyle::Inner(bang),
+                        path: path,
+                        tts: tts,
+                        is_sugared_doc: false,
+                        pound_token: pound,
+                        bracket_token: bracket,
                     }
-                )
-            }
-        }
+                })
+            )
+            |
+            map!(
+                lit_doc_comment,
+                |lit| Attribute {
+                    style: AttrStyle::Inner(tokens::Bang::default()),
+                    path: "doc".into(),
+                    tts: vec![
+                        ::TokenTree(eq()),
+                        ::TokenTree(lit),
+                    ],
+                    is_sugared_doc: true,
+                    pound_token: tokens::Pound::default(),
+                    bracket_token: tokens::Bracket::default(),
+                }
+            )
+        ));
 
-        pub fn parse_outer(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    pound: syn!(Pound) >>
-                    path_and_tts: brackets!(tuple!(
-                        call!(::Path::parse_mod_style),
-                        call!(::TokenTree::parse_list)
-                    )) >>
-                    ({
-                        let ((path, tts), bracket) = path_and_tts;
+        named!(pub parse_outer -> Self, alt!(
+            do_parse!(
+                pound: syn!(Pound) >>
+                path_and_tts: brackets!(tuple!(
+                    call!(::Path::parse_mod_style),
+                    call!(::TokenTree::parse_list)
+                )) >>
+                ({
+                    let ((path, tts), bracket) = path_and_tts;
 
-                        Attribute {
-                            style: AttrStyle::Outer,
-                            path: path,
-                            tts: tts,
-                            is_sugared_doc: false,
-                            pound_token: pound,
-                            bracket_token: bracket,
-                        }
-                    })
-                )
-                |
-                map!(
-                    lit_doc_comment,
-                    |lit| Attribute {
+                    Attribute {
                         style: AttrStyle::Outer,
-                        path: "doc".into(),
-                        tts: vec![
-                            ::TokenTree(eq()),
-                            ::TokenTree(lit),
-                        ],
-                        is_sugared_doc: true,
-                        pound_token: tokens::Pound::default(),
-                        bracket_token: tokens::Bracket::default(),
+                        path: path,
+                        tts: tts,
+                        is_sugared_doc: false,
+                        pound_token: pound,
+                        bracket_token: bracket,
                     }
-                )
-            }
-        }
+                })
+            )
+            |
+            map!(
+                lit_doc_comment,
+                |lit| Attribute {
+                    style: AttrStyle::Outer,
+                    path: "doc".into(),
+                    tts: vec![
+                        ::TokenTree(eq()),
+                        ::TokenTree(lit),
+                    ],
+                    is_sugared_doc: true,
+                    pound_token: tokens::Pound::default(),
+                    bracket_token: tokens::Bracket::default(),
+                }
+            )
+        ));
     }
 
-    fn lit_doc_comment(input: &[TokenTree]) -> IResult<&[TokenTree], TokenTree> {
+    fn lit_doc_comment(input: Cursor) -> PResult<TokenTree> {
         let mut tokens = input.iter();
         let tok = match tokens.next() {
             Some(tok) => tok,
-            None => return IResult::Error,
+            None => return parse_error(),
         };
         let literal = match tok.kind {
             TokenKind::Literal(ref l) => l.to_string(),
-            _ => return IResult::Error,
+            _ => return parse_error(),
         };
         if literal.starts_with("//") || literal.starts_with("/*") {
-            IResult::Done(tokens.as_slice(), tok.clone())
+            Ok((tokens.as_slice(), tok.clone()))
         } else {
-            IResult::Error
+            parse_error()
         }
     }
 }
diff --git a/src/constant.rs b/src/constant.rs
index d76a827..d3991b7 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -89,64 +89,60 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use proc_macro2::TokenTree;
-    use synom::{IResult, Synom};
+    use synom::Synom;
     use synom::tokens::*;
 
     impl Synom for ConstExpr {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                mut e: alt!(
-                    map!(syn!(ConstUnary), |e: ConstUnary| e.into())
-                    |
-                    map!(syn!(Lit), |e: Lit| e.into())
-                    |
-                    map!(syn!(Path), |e: Path| e.into())
-                    |
-                    map!(syn!(ConstParen), |e: ConstParen| e.into())
-                    // Cannot handle ConstExpr::Other here because for example
-                    // `[u32; n!()]` would end up successfully parsing `n` as
-                    // ConstExpr::Path and then fail to parse `!()`. Instead, callers
-                    // are required to handle Other. See ty::parsing::array_len and
-                    // data::parsing::discriminant.
-                ) >>
-                many0!(alt!(
-                    tap!(args: and_call => {
-                        let (args, paren) = args;
-                        e = ConstCall {
-                            func: Box::new(e),
-                            args: args,
-                            paren_token: paren,
-                        }.into();
-                    })
-                    |
-                    tap!(more: and_binary => {
-                        let (op, other) = more;
-                        e = ConstBinary { op: op, left: Box::new(e), right: Box::new(other) }.into();
-                    })
-                    |
-                    tap!(ty: and_cast => {
-                        let (ty, token) = ty;
-                        e = ConstCast {
-                            expr: Box::new(e),
-                            ty: Box::new(ty),
-                            as_token: token,
-                        }.into();
-                    })
-                    |
-                    tap!(i: and_index => {
-                        let (i, bracket) = i;
-                        e = ConstIndex {
-                            expr: Box::new(e),
-                            index: Box::new(i),
-                            bracket_token: bracket,
-                        }.into();
-                    })
-                )) >>
-                (e)
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            mut e: alt!(
+                map!(syn!(ConstUnary), |e: ConstUnary| e.into())
+                |
+                map!(syn!(Lit), |e: Lit| e.into())
+                |
+                map!(syn!(Path), |e: Path| e.into())
+                |
+                map!(syn!(ConstParen), |e: ConstParen| e.into())
+                // Cannot handle ConstExpr::Other here because for example
+                // `[u32; n!()]` would end up successfully parsing `n` as
+                // ConstExpr::Path and then fail to parse `!()`. Instead, callers
+                // are required to handle Other. See ty::parsing::array_len and
+                // data::parsing::discriminant.
+            ) >>
+            many0!(alt!(
+                tap!(args: and_call => {
+                    let (args, paren) = args;
+                    e = ConstCall {
+                        func: Box::new(e),
+                        args: args,
+                        paren_token: paren,
+                    }.into();
+                })
+                |
+                tap!(more: and_binary => {
+                    let (op, other) = more;
+                    e = ConstBinary { op: op, left: Box::new(e), right: Box::new(other) }.into();
+                })
+                |
+                tap!(ty: and_cast => {
+                    let (ty, token) = ty;
+                    e = ConstCast {
+                        expr: Box::new(e),
+                        ty: Box::new(ty),
+                        as_token: token,
+                    }.into();
+                })
+                |
+                tap!(i: and_index => {
+                    let (i, bracket) = i;
+                    e = ConstIndex {
+                        expr: Box::new(e),
+                        index: Box::new(i),
+                        bracket_token: bracket,
+                    }.into();
+                })
+            )) >>
+            (e)
+        ));
     }
 
     named!(and_call -> (Delimited<ConstExpr, tokens::Comma>, tokens::Paren),
@@ -156,30 +152,24 @@
            tuple!(call!(BinOp::parse_binop), syn!(ConstExpr)));
 
     impl Synom for ConstUnary {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                operator: syn!(UnOp) >>
-                operand: syn!(ConstExpr) >>
-                (ConstUnary { op: operator, expr: Box::new(operand) })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            operator: syn!(UnOp) >>
+            operand: syn!(ConstExpr) >>
+            (ConstUnary { op: operator, expr: Box::new(operand) })
+        ));
     }
 
     named!(and_index -> (ConstExpr, tokens::Bracket),
            brackets!(syn!(ConstExpr)));
 
     impl Synom for ConstParen {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                parens: parens!(syn!(ConstExpr)) >>
-                (ConstParen {
-                    expr: Box::new(parens.0),
-                    paren_token: parens.1,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            parens: parens!(syn!(ConstExpr)) >>
+            (ConstParen {
+                expr: Box::new(parens.0),
+                paren_token: parens.1,
+            })
+        ));
     }
 
     named!(and_cast -> (Ty, tokens::As), do_parse!(
diff --git a/src/data.rs b/src/data.rs
index 290c8ff..ef6490e 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -108,107 +108,97 @@
 pub mod parsing {
     use super::*;
 
-    use synom::{IResult, Synom};
+    use synom::Synom;
     use synom::tokens;
     use synom::tokens::*;
-    use proc_macro2::TokenTree;
 
     impl Field {
-        pub fn parse_struct(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                vis: syn!(Visibility) >>
-                id: syn!(Ident) >>
-                colon: syn!(Colon) >>
-                ty: syn!(Ty) >>
-                (Field {
-                    ident: Some(id),
-                    vis: vis,
-                    attrs: attrs,
-                    ty: ty,
-                    colon_token: Some(colon),
-                })
-            }
-        }
+        named!(pub parse_struct -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            vis: syn!(Visibility) >>
+            id: syn!(Ident) >>
+            colon: syn!(Colon) >>
+            ty: syn!(Ty) >>
+            (Field {
+                ident: Some(id),
+                vis: vis,
+                attrs: attrs,
+                ty: ty,
+                colon_token: Some(colon),
+            })
+        ));
 
-        pub fn parse_tuple(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                vis: syn!(Visibility) >>
-                ty: syn!(Ty) >>
-                (Field {
-                    ident: None,
-                    colon_token: None,
-                    vis: vis,
-                    attrs: attrs,
-                    ty: ty,
-                })
-            }
-        }
+        named!(pub parse_tuple -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            vis: syn!(Visibility) >>
+            ty: syn!(Ty) >>
+            (Field {
+                ident: None,
+                colon_token: None,
+                vis: vis,
+                attrs: attrs,
+                ty: ty,
+            })
+        ));
     }
 
     impl Synom for Visibility {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    pub_token: syn!(Pub) >>
-                    other: parens!(syn!(tokens::Crate)) >>
-                    (Visibility::Crate(VisCrate {
-                        crate_token: other.0,
-                        paren_token: other.1,
-                        pub_token: pub_token,
-                    }))
-                )
-                |
-                do_parse!(
-                    pub_token: syn!(Pub) >>
-                    other: parens!(syn!(Self_)) >>
-                    (Visibility::Restricted(VisRestricted {
-                        path: Box::new(other.0.into()),
-                        in_token: None,
-                        paren_token: other.1,
-                        pub_token: pub_token,
-                    }))
-                )
-                |
-                do_parse!(
-                    pub_token: syn!(Pub) >>
-                    other: parens!(syn!(Super)) >>
-                    (Visibility::Restricted(VisRestricted {
-                        path: Box::new(other.0.into()),
-                        in_token: None,
-                        paren_token: other.1,
-                        pub_token: pub_token,
-                    }))
-                )
-                |
-                do_parse!(
-                    pub_token: syn!(Pub) >>
-                    other: parens!(do_parse!(
-                        in_tok: syn!(In) >>
-                        restricted: call!(Path::parse_mod_style) >>
-                        (in_tok, restricted)
-                    )) >>
-                    (Visibility::Restricted(VisRestricted {
-                        path: Box::new((other.0).1),
-                        in_token: Some((other.0).0),
-                        paren_token: other.1,
-                        pub_token: pub_token,
-                    }))
-                )
-                |
-                syn!(Pub) => { |tok| {
-                    Visibility::Public(VisPublic {
-                        pub_token: tok,
-                    })
-                } }
-                |
-                epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                pub_token: syn!(Pub) >>
+                other: parens!(syn!(tokens::Crate)) >>
+                (Visibility::Crate(VisCrate {
+                    crate_token: other.0,
+                    paren_token: other.1,
+                    pub_token: pub_token,
+                }))
+            )
+            |
+            do_parse!(
+                pub_token: syn!(Pub) >>
+                other: parens!(syn!(Self_)) >>
+                (Visibility::Restricted(VisRestricted {
+                    path: Box::new(other.0.into()),
+                    in_token: None,
+                    paren_token: other.1,
+                    pub_token: pub_token,
+                }))
+            )
+            |
+            do_parse!(
+                pub_token: syn!(Pub) >>
+                other: parens!(syn!(Super)) >>
+                (Visibility::Restricted(VisRestricted {
+                    path: Box::new(other.0.into()),
+                    in_token: None,
+                    paren_token: other.1,
+                    pub_token: pub_token,
+                }))
+            )
+            |
+            do_parse!(
+                pub_token: syn!(Pub) >>
+                other: parens!(do_parse!(
+                    in_tok: syn!(In) >>
+                    restricted: call!(Path::parse_mod_style) >>
+                    (in_tok, restricted)
+                )) >>
+                (Visibility::Restricted(VisRestricted {
+                    path: Box::new((other.0).1),
+                    in_token: Some((other.0).0),
+                    paren_token: other.1,
+                    pub_token: pub_token,
+                }))
+            )
+            |
+            syn!(Pub) => { |tok| {
+                Visibility::Public(VisPublic {
+                    pub_token: tok,
+                })
+            } }
+            |
+            epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
+        ));
     }
 }
 
diff --git a/src/derive.rs b/src/derive.rs
index 7d6aabd..a5f7d8c 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -47,58 +47,54 @@
 pub mod parsing {
     use super::*;
 
-    use proc_macro2::TokenTree;
-    use synom::{IResult, Synom};
+    use synom::Synom;
     use synom::tokens::*;
 
     impl Synom for DeriveInput {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                vis: syn!(Visibility) >>
-                which: alt!(
-                    syn!(Struct) => { Ok }
-                    |
-                    // weird hack to get around exhaustiveness check below
-                    syn!(Enum) => { |e| Err((e, 1)) }
-                ) >>
-                id: syn!(Ident) >>
-                generics: syn!(Generics) >>
-                item: switch!(value!(which),
-                    Ok(s) => map!(struct_body, move |(wh, body, semi)| DeriveInput {
-                        ident: id,
-                        vis: vis,
-                        attrs: attrs,
-                        generics: Generics {
-                            where_clause: wh,
-                            .. generics
-                        },
-                        body: Body::Struct(BodyStruct {
-                            struct_token: s,
-                            data: body,
-                            semi_token: semi,
-                        }),
-                    })
-                    |
-                    Err((e, 1)) => map!(enum_body, move |(wh, body, brace)| DeriveInput {
-                        ident: id,
-                        vis: vis,
-                        attrs: attrs,
-                        generics: Generics {
-                            where_clause: wh,
-                            .. generics
-                        },
-                        body: Body::Enum(BodyEnum {
-                            variants: body,
-                            brace_token: brace,
-                            enum_token: e,
-                        }),
-                    })
-                ) >>
-                (item)
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            vis: syn!(Visibility) >>
+            which: alt!(
+                syn!(Struct) => { Ok }
+                |
+                // weird hack to get around exhaustiveness check below
+                syn!(Enum) => { |e| Err((e, 1)) }
+            ) >>
+            id: syn!(Ident) >>
+            generics: syn!(Generics) >>
+            item: switch!(value!(which),
+                Ok(s) => map!(struct_body, move |(wh, body, semi)| DeriveInput {
+                    ident: id,
+                    vis: vis,
+                    attrs: attrs,
+                    generics: Generics {
+                        where_clause: wh,
+                        .. generics
+                    },
+                    body: Body::Struct(BodyStruct {
+                        struct_token: s,
+                        data: body,
+                        semi_token: semi,
+                    }),
+                })
+                |
+                Err((e, 1)) => map!(enum_body, move |(wh, body, brace)| DeriveInput {
+                    ident: id,
+                    vis: vis,
+                    attrs: attrs,
+                    generics: Generics {
+                        where_clause: wh,
+                        .. generics
+                    },
+                    body: Body::Enum(BodyEnum {
+                        variants: body,
+                        brace_token: brace,
+                        enum_token: e,
+                    }),
+                })
+            ) >>
+            (item)
+        ));
 
         fn description() -> Option<&'static str> {
             Some("derive input")
@@ -134,32 +130,29 @@
     ));
 
     impl Synom for Variant {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                id: syn!(Ident) >>
-                data: alt!(
-                    struct_like_body => { |(d, b)| VariantData::Struct(d, b) }
-                    |
-                    tuple_like_body => { |(d, b)| VariantData::Tuple(d, b) }
-                    |
-                    epsilon!() => { |_| VariantData::Unit }
-                ) >>
-                disr: option!(do_parse!(
-                    eq: syn!(Eq) >>
-                    disr: discriminant >>
-                    (eq, disr)
-                )) >>
-                (Variant {
-                    ident: id,
-                    attrs: attrs,
-                    data: data,
-                    eq_token: disr.as_ref().map(|p| tokens::Eq((p.0).0)),
-                    discriminant: disr.map(|p| p.1),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            id: syn!(Ident) >>
+            data: alt!(
+                struct_like_body => { |(d, b)| VariantData::Struct(d, b) }
+                |
+                tuple_like_body => { |(d, b)| VariantData::Tuple(d, b) }
+                |
+                epsilon!() => { |_| VariantData::Unit }
+            ) >>
+            disr: option!(do_parse!(
+                eq: syn!(Eq) >>
+                disr: discriminant >>
+                (eq, disr)
+            )) >>
+            (Variant {
+                ident: id,
+                attrs: attrs,
+                data: data,
+                eq_token: disr.as_ref().map(|p| tokens::Eq((p.0).0)),
+                discriminant: disr.map(|p| p.1),
+            })
+        ));
     }
 
     #[cfg(not(feature = "full"))]
diff --git a/src/expr.rs b/src/expr.rs
index 23f2faa..fff9c52 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -589,16 +589,16 @@
     use super::*;
     use ty::parsing::qpath;
 
-    use proc_macro2::{TokenTree, TokenStream, TokenKind, Delimiter};
-    use synom::{IResult, Synom};
+    use proc_macro2::{TokenStream, TokenKind, Delimiter};
+    use synom::{PResult, Cursor, Synom, parse_error};
     use synom::tokens::*;
 
     // Struct literals are ambiguous in certain positions
     // https://github.com/rust-lang/rfcs/pull/92
     macro_rules! named_ambiguous_expr {
         ($name:ident -> $o:ty, $allow_struct:ident, $submac:ident!( $($args:tt)* )) => {
-            fn $name(i: &[$crate::synom::TokenTree], $allow_struct: bool)
-                     -> $crate::synom::IResult<&[$crate::synom::TokenTree], $o> {
+            fn $name(i: $crate::synom::Cursor, $allow_struct: bool)
+                     -> $crate::synom::PResult<$o> {
                 $submac!(i, $($args)*)
             }
         };
@@ -611,9 +611,7 @@
     }
 
     impl Synom for Expr {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            ambiguous_expr!(input, true)
-        }
+        named!(parse -> Self, ambiguous_expr!(true));
 
         fn description() -> Option<&'static str> {
             Some("expression")
@@ -624,10 +622,10 @@
     named!(expr_no_struct -> Expr, ambiguous_expr!(false));
 
     #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
-    fn ambiguous_expr(i: &[synom::TokenTree],
+    fn ambiguous_expr(i: Cursor,
                       allow_struct: bool,
                       allow_block: bool)
-                      -> IResult<&[synom::TokenTree], Expr> {
+                      -> PResult<Expr> {
         do_parse! {
             i,
             mut e: alt!(
@@ -793,16 +791,13 @@
     }
 
     impl Synom for ExprParen {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                e: parens!(syn!(Expr)) >>
-                (ExprParen {
-                    expr: Box::new(e.0),
-                    paren_token: e.1,
-                }.into())
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            e: parens!(syn!(Expr)) >>
+            (ExprParen {
+                expr: Box::new(e.0),
+                paren_token: e.1,
+            }.into())
+        ));
     }
 
     named_ambiguous_expr!(expr_box -> ExprKind, allow_struct, do_parse!(
@@ -815,41 +810,35 @@
     ));
 
     impl Synom for ExprInPlace {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                in_: syn!(In) >>
-                place: expr_no_struct >>
-                value: braces!(call!(Block::parse_within)) >>
-                (ExprInPlace {
-                    in_token: in_,
-                    place: Box::new(place),
-                    value: Box::new(Expr {
-                        node: ExprBlock {
-                            unsafety: Unsafety::Normal,
-                            block: Block {
-                                stmts: value.0,
-                                brace_token: value.1,
-                            },
-                        }.into(),
-                        attrs: Vec::new(),
-                    }),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            in_: syn!(In) >>
+            place: expr_no_struct >>
+            value: braces!(call!(Block::parse_within)) >>
+            (ExprInPlace {
+                in_token: in_,
+                place: Box::new(place),
+                value: Box::new(Expr {
+                    node: ExprBlock {
+                        unsafety: Unsafety::Normal,
+                        block: Block {
+                            stmts: value.0,
+                            brace_token: value.1,
+                        },
+                    }.into(),
+                    attrs: Vec::new(),
+                }),
+            })
+        ));
     }
 
     impl Synom for ExprArray {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                elems: brackets!(call!(Delimited::parse_terminated)) >>
-                (ExprArray {
-                    exprs: elems.0,
-                    bracket_token: elems.1,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            elems: brackets!(call!(Delimited::parse_terminated)) >>
+            (ExprArray {
+                exprs: elems.0,
+                bracket_token: elems.1,
+            })
+        ));
     }
 
     named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
@@ -891,17 +880,14 @@
     ));
 
     impl Synom for ExprTup {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                elems: parens!(call!(Delimited::parse_terminated)) >>
-                (ExprTup {
-                    args: elems.0,
-                    paren_token: elems.1,
-                    lone_comma: None, // TODO: parse this
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            elems: parens!(call!(Delimited::parse_terminated)) >>
+            (ExprTup {
+                args: elems.0,
+                paren_token: elems.1,
+                lone_comma: None, // TODO: parse this
+            })
+        ));
     }
 
     named_ambiguous_expr!(and_binary -> (BinOp, Expr), allow_struct, tuple!(
@@ -925,53 +911,47 @@
            map!(tuple!(syn!(Colon), syn!(Ty)), |(a, b)| (b, a)));
 
     impl Synom for ExprIfLet {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                if_: syn!(If) >>
-                let_: syn!(Let) >>
-                pat: syn!(Pat) >>
-                eq: syn!(Eq) >>
-                cond: expr_no_struct >>
-                then_block: braces!(call!(Block::parse_within)) >>
-                else_block: option!(else_block) >>
-                (ExprIfLet {
-                    pat: Box::new(pat),
-                    let_token: let_,
-                    eq_token: eq,
-                    expr: Box::new(cond),
-                    if_true: Block {
-                        stmts: then_block.0,
-                        brace_token: then_block.1,
-                    },
-                    if_token: if_,
-                    else_token: else_block.as_ref().map(|p| Else((p.0).0)),
-                    if_false: else_block.map(|p| Box::new(p.1.into())),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            if_: syn!(If) >>
+            let_: syn!(Let) >>
+            pat: syn!(Pat) >>
+            eq: syn!(Eq) >>
+            cond: expr_no_struct >>
+            then_block: braces!(call!(Block::parse_within)) >>
+            else_block: option!(else_block) >>
+            (ExprIfLet {
+                pat: Box::new(pat),
+                let_token: let_,
+                eq_token: eq,
+                expr: Box::new(cond),
+                if_true: Block {
+                    stmts: then_block.0,
+                    brace_token: then_block.1,
+                },
+                if_token: if_,
+                else_token: else_block.as_ref().map(|p| Else((p.0).0)),
+                if_false: else_block.map(|p| Box::new(p.1.into())),
+            })
+        ));
     }
 
     impl Synom for ExprIf {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                if_: syn!(If) >>
-                cond: expr_no_struct >>
-                then_block: braces!(call!(Block::parse_within)) >>
-                else_block: option!(else_block) >>
-                (ExprIf {
-                    cond: Box::new(cond),
-                    if_true: Block {
-                        stmts: then_block.0,
-                        brace_token: then_block.1,
-                    },
-                    if_token: if_,
-                    else_token: else_block.as_ref().map(|p| Else((p.0).0)),
-                    if_false: else_block.map(|p| Box::new(p.1.into())),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            if_: syn!(If) >>
+            cond: expr_no_struct >>
+            then_block: braces!(call!(Block::parse_within)) >>
+            else_block: option!(else_block) >>
+            (ExprIf {
+                cond: Box::new(cond),
+                if_true: Block {
+                    stmts: then_block.0,
+                    brace_token: then_block.1,
+                },
+                if_token: if_,
+                else_token: else_block.as_ref().map(|p| Else((p.0).0)),
+                if_false: else_block.map(|p| Box::new(p.1.into())),
+            })
+        ));
     }
 
     named!(else_block -> (Else, ExprKind), do_parse!(
@@ -997,98 +977,86 @@
 
 
     impl Synom for ExprForLoop {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lbl: option!(tuple!(label, syn!(Colon))) >>
-                for_: syn!(For) >>
-                pat: syn!(Pat) >>
-                in_: syn!(In) >>
-                expr: expr_no_struct >>
-                loop_block: syn!(Block) >>
-                (ExprForLoop {
-                    for_token: for_,
-                    in_token: in_,
-                    pat: Box::new(pat),
-                    expr: Box::new(expr),
-                    body: loop_block,
-                    colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
-                    label: lbl.map(|p| p.0),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lbl: option!(tuple!(label, syn!(Colon))) >>
+            for_: syn!(For) >>
+            pat: syn!(Pat) >>
+            in_: syn!(In) >>
+            expr: expr_no_struct >>
+            loop_block: syn!(Block) >>
+            (ExprForLoop {
+                for_token: for_,
+                in_token: in_,
+                pat: Box::new(pat),
+                expr: Box::new(expr),
+                body: loop_block,
+                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                label: lbl.map(|p| p.0),
+            })
+        ));
     }
 
     impl Synom for ExprLoop {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lbl: option!(tuple!(label, syn!(Colon))) >>
-                loop_: syn!(Loop) >>
-                loop_block: syn!(Block) >>
-                (ExprLoop {
-                    loop_token: loop_,
-                    body: loop_block,
-                    colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
-                    label: lbl.map(|p| p.0),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lbl: option!(tuple!(label, syn!(Colon))) >>
+            loop_: syn!(Loop) >>
+            loop_block: syn!(Block) >>
+            (ExprLoop {
+                loop_token: loop_,
+                body: loop_block,
+                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                label: lbl.map(|p| p.0),
+            })
+        ));
     }
 
     impl Synom for ExprMatch {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                match_: syn!(Match) >>
-                obj: expr_no_struct >>
-                res: braces!(do_parse!(
-                    mut arms: many0!(do_parse!(
-                        arm: syn!(Arm) >>
-                            cond!(arm_requires_comma(&arm), syn!(Comma)) >>
-                            cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
-                            (arm)
-                    )) >>
-                    last_arm: option!(syn!(Arm)) >>
-                    ({
-                        arms.extend(last_arm);
-                        arms
-                    })
+        named!(parse -> Self, do_parse!(
+            match_: syn!(Match) >>
+            obj: expr_no_struct >>
+            res: braces!(do_parse!(
+                mut arms: many0!(do_parse!(
+                    arm: syn!(Arm) >>
+                        cond!(arm_requires_comma(&arm), syn!(Comma)) >>
+                        cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
+                        (arm)
                 )) >>
+                last_arm: option!(syn!(Arm)) >>
                 ({
-                    let (mut arms, brace) = res;
-                    ExprMatch {
-                        expr: Box::new(obj),
-                        match_token: match_,
-                        brace_token: brace,
-                        arms: {
-                            for arm in &mut arms {
-                                if arm_requires_comma(arm) {
-                                    arm.comma = Some(tokens::Comma::default());
-                                }
-                            }
-                            arms
-                        },
-                    }
+                    arms.extend(last_arm);
+                    arms
                 })
-            }
-        }
+            )) >>
+            ({
+                let (mut arms, brace) = res;
+                ExprMatch {
+                    expr: Box::new(obj),
+                    match_token: match_,
+                    brace_token: brace,
+                    arms: {
+                        for arm in &mut arms {
+                            if arm_requires_comma(arm) {
+                                arm.comma = Some(tokens::Comma::default());
+                            }
+                        }
+                        arms
+                    },
+                }
+            })
+        ));
     }
 
     impl Synom for ExprCatch {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                do_: syn!(Do) >>
-                catch_: syn!(Catch) >>
-                catch_block: syn!(Block) >>
-                (ExprCatch {
-                    block: catch_block,
-                    do_token: do_,
-                    catch_token: catch_,
-                }.into())
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            do_: syn!(Do) >>
+            catch_: syn!(Catch) >>
+            catch_block: syn!(Block) >>
+            (ExprCatch {
+                block: catch_block,
+                do_token: do_,
+                catch_token: catch_,
+            }.into())
+        ));
     }
 
     fn arm_requires_comma(arm: &Arm) -> bool {
@@ -1100,34 +1068,31 @@
     }
 
     impl Synom for Arm {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                pats: call!(Delimited::parse_separated_nonempty) >>
-                guard: option!(tuple!(syn!(If), syn!(Expr))) >>
-                rocket: syn!(Rocket) >>
-                body: alt!(
-                    map!(syn!(Block), |blk| {
-                        ExprKind::Block(ExprBlock {
-                            unsafety: Unsafety::Normal,
-                            block: blk,
-                        }).into()
-                    })
-                    |
-                    syn!(Expr)
-                ) >>
-                (Arm {
-                    rocket_token: rocket,
-                    if_token: guard.as_ref().map(|p| If((p.0).0)),
-                    attrs: attrs,
-                    pats: pats,
-                    guard: guard.map(|p| Box::new(p.1)),
-                    body: Box::new(body),
-                    comma: None,
+        named!(parse -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            pats: call!(Delimited::parse_separated_nonempty) >>
+            guard: option!(tuple!(syn!(If), syn!(Expr))) >>
+            rocket: syn!(Rocket) >>
+            body: alt!(
+                map!(syn!(Block), |blk| {
+                    ExprKind::Block(ExprBlock {
+                        unsafety: Unsafety::Normal,
+                        block: blk,
+                    }).into()
                 })
-            }
-        }
+                |
+                syn!(Expr)
+            ) >>
+            (Arm {
+                rocket_token: rocket,
+                if_token: guard.as_ref().map(|p| If((p.0).0)),
+                attrs: attrs,
+                pats: pats,
+                guard: guard.map(|p| Box::new(p.1)),
+                body: Box::new(body),
+                comma: None,
+            })
+        ));
     }
 
     named_ambiguous_expr!(expr_closure -> ExprKind, allow_struct, do_parse!(
@@ -1184,61 +1149,52 @@
     ));
 
     impl Synom for ExprWhile {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lbl: option!(tuple!(label, syn!(Colon))) >>
-                while_: syn!(While) >>
-                cond: expr_no_struct >>
-                while_block: syn!(Block) >>
-                (ExprWhile {
-                    while_token: while_,
-                    colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
-                    cond: Box::new(cond),
-                    body: while_block,
-                    label: lbl.map(|p| p.0),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lbl: option!(tuple!(label, syn!(Colon))) >>
+            while_: syn!(While) >>
+            cond: expr_no_struct >>
+            while_block: syn!(Block) >>
+            (ExprWhile {
+                while_token: while_,
+                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                cond: Box::new(cond),
+                body: while_block,
+                label: lbl.map(|p| p.0),
+            })
+        ));
     }
 
     impl Synom for ExprWhileLet {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lbl: option!(tuple!(label, syn!(Colon))) >>
-                while_: syn!(While) >>
-                let_: syn!(Let) >>
-                pat: syn!(Pat) >>
-                eq: syn!(Eq) >>
-                value: expr_no_struct >>
-                while_block: syn!(Block) >>
-                (ExprWhileLet {
-                    eq_token: eq,
-                    let_token: let_,
-                    while_token: while_,
-                    colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
-                    pat: Box::new(pat),
-                    expr: Box::new(value),
-                    body: while_block,
-                    label: lbl.map(|p| p.0),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lbl: option!(tuple!(label, syn!(Colon))) >>
+            while_: syn!(While) >>
+            let_: syn!(Let) >>
+            pat: syn!(Pat) >>
+            eq: syn!(Eq) >>
+            value: expr_no_struct >>
+            while_block: syn!(Block) >>
+            (ExprWhileLet {
+                eq_token: eq,
+                let_token: let_,
+                while_token: while_,
+                colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
+                pat: Box::new(pat),
+                expr: Box::new(value),
+                body: while_block,
+                label: lbl.map(|p| p.0),
+            })
+        ));
     }
 
     impl Synom for ExprContinue {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                cont: syn!(Continue) >>
-                lbl: option!(label) >>
-                (ExprContinue {
-                    continue_token: cont,
-                    label: lbl,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            cont: syn!(Continue) >>
+            lbl: option!(label) >>
+            (ExprContinue {
+                continue_token: cont,
+                label: lbl,
+            })
+        ));
     }
 
     named_ambiguous_expr!(expr_break -> ExprKind, allow_struct, do_parse!(
@@ -1262,101 +1218,89 @@
     ));
 
     impl Synom for ExprStruct {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                path: syn!(Path) >>
-                data: braces!(do_parse!(
-                    fields: call!(Delimited::parse_terminated) >>
-                    base: option!(
-                        cond!(fields.is_empty() || fields.trailing_delim(),
-                            do_parse!(
-                                dots: syn!(Dot2) >>
-                                base: syn!(Expr) >>
-                                (dots, base)
-                            )
+        named!(parse -> Self, do_parse!(
+            path: syn!(Path) >>
+            data: braces!(do_parse!(
+                fields: call!(Delimited::parse_terminated) >>
+                base: option!(
+                    cond!(fields.is_empty() || fields.trailing_delim(),
+                        do_parse!(
+                            dots: syn!(Dot2) >>
+                            base: syn!(Expr) >>
+                            (dots, base)
                         )
-                    ) >>
-                    (fields, base)
-                )) >>
-                ({
-                    let ((fields, base), brace) = data;
-                    let (dots, rest) = match base.and_then(|b| b) {
-                        Some((dots, base)) => (Some(dots), Some(base)),
-                        None => (None, None),
-                    };
-                    ExprStruct {
-                        brace_token: brace,
-                        path: path,
-                        fields: fields,
-                        dot2_token: dots,
-                        rest: rest.map(Box::new),
-                    }
-                })
-            }
-        }
+                    )
+                ) >>
+                (fields, base)
+            )) >>
+            ({
+                let ((fields, base), brace) = data;
+                let (dots, rest) = match base.and_then(|b| b) {
+                    Some((dots, base)) => (Some(dots), Some(base)),
+                    None => (None, None),
+                };
+                ExprStruct {
+                    brace_token: brace,
+                    path: path,
+                    fields: fields,
+                    dot2_token: dots,
+                    rest: rest.map(Box::new),
+                }
+            })
+        ));
     }
 
     impl Synom for FieldValue {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    name: wordlike >>
-                    colon: syn!(Colon) >>
-                    value: syn!(Expr) >>
-                    (FieldValue {
-                        ident: name,
-                        expr: value,
-                        is_shorthand: false,
-                        attrs: Vec::new(),
-                        colon_token: Some(colon),
-                    })
-                )
-                |
-                map!(syn!(Ident), |name: Ident| FieldValue {
-                    ident: name.clone(),
-                    expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
-                    is_shorthand: true,
+        named!(parse -> Self, alt!(
+            do_parse!(
+                name: wordlike >>
+                colon: syn!(Colon) >>
+                value: syn!(Expr) >>
+                (FieldValue {
+                    ident: name,
+                    expr: value,
+                    is_shorthand: false,
                     attrs: Vec::new(),
-                    colon_token: None,
+                    colon_token: Some(colon),
                 })
-            }
-        }
+            )
+            |
+            map!(syn!(Ident), |name: Ident| FieldValue {
+                ident: name.clone(),
+                expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
+                is_shorthand: true,
+                attrs: Vec::new(),
+                colon_token: None,
+            })
+        ));
     }
 
     impl Synom for ExprRepeat {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                data: brackets!(do_parse!(
-                    value: syn!(Expr) >>
-                    semi: syn!(Semi) >>
-                    times: syn!(Expr) >>
-                    (value, semi, times)
-                )) >>
-                (ExprRepeat {
-                    expr: Box::new((data.0).0),
-                    amt: Box::new((data.0).2),
-                    bracket_token: data.1,
-                    semi_token: (data.0).1,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            data: brackets!(do_parse!(
+                value: syn!(Expr) >>
+                semi: syn!(Semi) >>
+                times: syn!(Expr) >>
+                (value, semi, times)
+            )) >>
+            (ExprRepeat {
+                expr: Box::new((data.0).0),
+                amt: Box::new((data.0).2),
+                bracket_token: data.1,
+                semi_token: (data.0).1,
+            })
+        ));
     }
 
     impl Synom for ExprBlock {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                rules: syn!(Unsafety) >>
-                b: syn!(Block) >>
-                (ExprBlock {
-                    unsafety: rules,
-                    block: b,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            rules: syn!(Unsafety) >>
+            b: syn!(Block) >>
+            (ExprBlock {
+                unsafety: rules,
+                block: b,
+            })
+        ));
     }
 
     named_ambiguous_expr!(expr_range -> ExprKind, allow_struct, do_parse!(
@@ -1366,27 +1310,22 @@
     ));
 
     impl Synom for RangeLimits {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Dot3) => { RangeLimits::Closed }
-                |
-                syn!(Dot2) => { RangeLimits::HalfOpen }
-            }
-        }
+        named!(parse -> Self, alt!(
+            // Must come before Dot2
+            syn!(Dot3) => { RangeLimits::Closed }
+            |
+            syn!(Dot2) => { RangeLimits::HalfOpen }
+        ));
     }
 
     impl Synom for ExprPath {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                pair: qpath >>
-                (ExprPath {
-                    qself: pair.0,
-                    path: pair.1,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            pair: qpath >>
+            (ExprPath {
+                qself: pair.0,
+                path: pair.1,
+            })
+        ));
     }
 
     named_ambiguous_expr!(expr_addr_of -> ExprKind, allow_struct, do_parse!(
@@ -1426,49 +1365,40 @@
     ));
 
     impl Synom for Block {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                stmts: braces!(call!(Block::parse_within)) >>
-                (Block {
-                    stmts: stmts.0,
-                    brace_token: stmts.1,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            stmts: braces!(call!(Block::parse_within)) >>
+            (Block {
+                stmts: stmts.0,
+                brace_token: stmts.1,
+            })
+        ));
     }
 
     impl Block {
-        pub fn parse_within(input: &[TokenTree]) -> IResult<&[TokenTree], Vec<Stmt>> {
-            do_parse! {
-                input,
-                many0!(syn!(Semi)) >>
-                mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
-                last: option!(syn!(Expr)) >>
-                (match last {
-                    None => standalone,
-                    Some(last) => {
-                        standalone.push(Stmt::Expr(Box::new(last)));
-                        standalone
-                    }
-                })
-            }
-        }
+        named!(pub parse_within -> Vec<Stmt>, do_parse!(
+            many0!(syn!(Semi)) >>
+            mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
+            last: option!(syn!(Expr)) >>
+            (match last {
+                None => standalone,
+                Some(last) => {
+                    standalone.push(Stmt::Expr(Box::new(last)));
+                    standalone
+                }
+            })
+        ));
     }
 
     impl Synom for Stmt {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                stmt_mac
-                |
-                stmt_local
-                |
-                stmt_item
-                |
-                stmt_expr
-            }
-        }
+        named!(parse -> Self, alt!(
+            stmt_mac
+            |
+            stmt_local
+            |
+            stmt_item
+            |
+            stmt_expr
+        ));
     }
 
     named!(stmt_mac -> Stmt, do_parse!(
@@ -1541,7 +1471,7 @@
             if let Some(s) = semi {
                 Stmt::Semi(Box::new(e), s)
             } else if requires_semi(&e) {
-                return IResult::Error;
+                return parse_error();
             } else {
                 Stmt::Expr(Box::new(e))
             }
@@ -1549,174 +1479,153 @@
     ));
 
     impl Synom for Pat {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(PatWild) => { Pat::Wild } // must be before pat_ident
-                |
-                syn!(PatBox) => { Pat::Box }  // must be before pat_ident
-                |
-                syn!(PatRange) => { Pat::Range } // must be before pat_lit
-                |
-                syn!(PatTupleStruct) => { Pat::TupleStruct }  // must be before pat_ident
-                |
-                syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
-                |
-                syn!(Mac) => { Pat::Mac } // must be before pat_ident
-                |
-                syn!(PatLit) => { Pat::Lit } // must be before pat_ident
-                |
-                syn!(PatIdent) => { Pat::Ident } // must be before pat_path
-                |
-                syn!(PatPath) => { Pat::Path }
-                |
-                syn!(PatTuple) => { Pat::Tuple }
-                |
-                syn!(PatRef) => { Pat::Ref }
-                |
-                syn!(PatSlice) => { Pat::Slice }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(PatWild) => { Pat::Wild } // must be before pat_ident
+            |
+            syn!(PatBox) => { Pat::Box }  // must be before pat_ident
+            |
+            syn!(PatRange) => { Pat::Range } // must be before pat_lit
+            |
+            syn!(PatTupleStruct) => { Pat::TupleStruct }  // must be before pat_ident
+            |
+            syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
+            |
+            syn!(Mac) => { Pat::Mac } // must be before pat_ident
+            |
+            syn!(PatLit) => { Pat::Lit } // must be before pat_ident
+            |
+            syn!(PatIdent) => { Pat::Ident } // must be before pat_path
+            |
+            syn!(PatPath) => { Pat::Path }
+            |
+            syn!(PatTuple) => { Pat::Tuple }
+            |
+            syn!(PatRef) => { Pat::Ref }
+            |
+            syn!(PatSlice) => { Pat::Slice }
+        ));
     }
 
     impl Synom for PatWild {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                syn!(Underscore),
-                |u| PatWild { underscore_token: u }
-            }
-        }
+        named!(parse -> Self, map!(
+            syn!(Underscore),
+            |u| PatWild { underscore_token: u }
+        ));
     }
 
     impl Synom for PatBox {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                boxed: syn!(Box_) >>
-                pat: syn!(Pat) >>
-                (PatBox {
-                    pat: Box::new(pat),
-                    box_token: boxed,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            boxed: syn!(Box_) >>
+            pat: syn!(Pat) >>
+            (PatBox {
+                pat: Box::new(pat),
+                box_token: boxed,
+            })
+        ));
     }
 
     impl Synom for PatIdent {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                mode: option!(syn!(Ref)) >>
-                mutability: syn!(Mutability) >>
-                name: alt!(
-                    syn!(Ident)
-                    |
-                    syn!(Self_) => { Into::into }
-                ) >>
-                not!(syn!(Lt)) >>
-                not!(syn!(Colon2)) >>
-                subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
-                (PatIdent {
-                    mode: match mode {
-                        Some(mode) => BindingMode::ByRef(mode, mutability),
-                        None => BindingMode::ByValue(mutability),
-                    },
-                    ident: name,
-                    at_token: subpat.as_ref().map(|p| At((p.0).0)),
-                    subpat: subpat.map(|p| Box::new(p.1)),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            mode: option!(syn!(Ref)) >>
+            mutability: syn!(Mutability) >>
+            name: alt!(
+                syn!(Ident)
+                |
+                syn!(Self_) => { Into::into }
+            ) >>
+            not!(syn!(Lt)) >>
+            not!(syn!(Colon2)) >>
+            subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
+            (PatIdent {
+                mode: match mode {
+                    Some(mode) => BindingMode::ByRef(mode, mutability),
+                    None => BindingMode::ByValue(mutability),
+                },
+                ident: name,
+                at_token: subpat.as_ref().map(|p| At((p.0).0)),
+                subpat: subpat.map(|p| Box::new(p.1)),
+            })
+        ));
     }
 
     impl Synom for PatTupleStruct {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                path: syn!(Path) >>
-                tuple: syn!(PatTuple) >>
-                (PatTupleStruct {
-                    path: path,
-                    pat: tuple,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            path: syn!(Path) >>
+            tuple: syn!(PatTuple) >>
+            (PatTupleStruct {
+                path: path,
+                pat: tuple,
+            })
+        ));
     }
 
     impl Synom for PatStruct {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                path: syn!(Path) >>
-                data: braces!(do_parse!(
-                    fields: call!(Delimited::parse_terminated) >>
-                    base: option!(
-                        cond!(fields.is_empty() || fields.trailing_delim(),
-                              syn!(Dot2))
-                    ) >>
-                    (fields, base)
-                )) >>
-                (PatStruct {
-                    path: path,
-                    fields: (data.0).0,
-                    brace_token: data.1,
-                    dot2_token: (data.0).1.and_then(|m| m),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            path: syn!(Path) >>
+            data: braces!(do_parse!(
+                fields: call!(Delimited::parse_terminated) >>
+                base: option!(
+                    cond!(fields.is_empty() || fields.trailing_delim(),
+                          syn!(Dot2))
+                ) >>
+                (fields, base)
+            )) >>
+            (PatStruct {
+                path: path,
+                fields: (data.0).0,
+                brace_token: data.1,
+                dot2_token: (data.0).1.and_then(|m| m),
+            })
+        ));
     }
 
     impl Synom for FieldPat {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    ident: wordlike >>
-                    colon: syn!(Colon) >>
-                    pat: syn!(Pat) >>
-                    (FieldPat {
+        named!(parse -> Self, alt!(
+            do_parse!(
+                ident: wordlike >>
+                colon: syn!(Colon) >>
+                pat: syn!(Pat) >>
+                (FieldPat {
+                    ident: ident,
+                    pat: Box::new(pat),
+                    is_shorthand: false,
+                    attrs: Vec::new(),
+                    colon_token: Some(colon),
+                })
+            )
+            |
+            do_parse!(
+                boxed: option!(syn!(Box_)) >>
+                mode: option!(syn!(Ref)) >>
+                mutability: syn!(Mutability) >>
+                ident: syn!(Ident) >>
+                ({
+                    let mut pat: Pat = PatIdent {
+                        mode: if let Some(mode) = mode {
+                            BindingMode::ByRef(mode, mutability)
+                        } else {
+                            BindingMode::ByValue(mutability)
+                        },
+                        ident: ident.clone(),
+                        subpat: None,
+                        at_token: None,
+                    }.into();
+                    if let Some(boxed) = boxed {
+                        pat = PatBox {
+                            pat: Box::new(pat),
+                            box_token: boxed,
+                        }.into();
+                    }
+                    FieldPat {
                         ident: ident,
                         pat: Box::new(pat),
-                        is_shorthand: false,
+                        is_shorthand: true,
                         attrs: Vec::new(),
-                        colon_token: Some(colon),
-                    })
-                )
-                |
-                do_parse!(
-                    boxed: option!(syn!(Box_)) >>
-                    mode: option!(syn!(Ref)) >>
-                    mutability: syn!(Mutability) >>
-                    ident: syn!(Ident) >>
-                    ({
-                        let mut pat: Pat = PatIdent {
-                            mode: if let Some(mode) = mode {
-                                BindingMode::ByRef(mode, mutability)
-                            } else {
-                                BindingMode::ByValue(mutability)
-                            },
-                            ident: ident.clone(),
-                            subpat: None,
-                            at_token: None,
-                        }.into();
-                        if let Some(boxed) = boxed {
-                            pat = PatBox {
-                                pat: Box::new(pat),
-                                box_token: boxed,
-                            }.into();
-                        }
-                        FieldPat {
-                            ident: ident,
-                            pat: Box::new(pat),
-                            is_shorthand: true,
-                            attrs: Vec::new(),
-                            colon_token: None,
-                        }
-                    })
-                )
-            }
-        }
+                        colon_token: None,
+                    }
+                })
+            )
+        ));
     }
 
     named!(wordlike -> Ident, alt!(
@@ -1729,114 +1638,99 @@
                 if s.parse::<u32>().is_ok() {
                     Ident::new(s.into(), lit.span)
                 } else {
-                    return IResult::Error
+                    return parse_error();
                 }
             })
         )
     ));
 
     impl Synom for PatPath {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                syn!(ExprPath),
-                |p: ExprPath| PatPath { qself: p.qself, path: p.path }
-            }
-        }
+        named!(parse -> Self, map!(
+            syn!(ExprPath),
+            |p: ExprPath| PatPath { qself: p.qself, path: p.path }
+        ));
     }
 
     impl Synom for PatTuple {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                data: parens!(do_parse!(
-                    elems: call!(Delimited::parse_terminated) >>
-                    dotdot: map!(cond!(
-                        elems.is_empty() || elems.trailing_delim(),
-                        option!(do_parse!(
-                            dots: syn!(Dot2) >>
-                            trailing: option!(syn!(Comma)) >>
-                            (dots, trailing)
-                        ))
-                    ), |x: Option<_>| x.and_then(|x| x)) >>
-                    rest: cond!(match dotdot {
-                                    Some((_, Some(_))) => true,
-                                    _ => false,
-                                },
-                                call!(Delimited::parse_terminated)) >>
-                    (elems, dotdot, rest)
-                )) >>
-                ({
-                    let ((mut elems, dotdot, rest), parens) = data;
-                    let (dotdot, trailing) = match dotdot {
-                        Some((a, b)) => (Some(a), Some(b)),
-                        None => (None, None),
-                    };
-                    PatTuple {
-                        paren_token: parens,
-                        dots_pos: dotdot.as_ref().map(|_| elems.len()),
-                        dot2_token: dotdot,
-                        comma_token: trailing.and_then(|b| b),
-                        pats: {
-                            if let Some(rest) = rest {
-                                for elem in rest {
-                                    elems.push(elem);
-                                }
+        named!(parse -> Self, do_parse!(
+            data: parens!(do_parse!(
+                elems: call!(Delimited::parse_terminated) >>
+                dotdot: map!(cond!(
+                    elems.is_empty() || elems.trailing_delim(),
+                    option!(do_parse!(
+                        dots: syn!(Dot2) >>
+                        trailing: option!(syn!(Comma)) >>
+                        (dots, trailing)
+                    ))
+                ), |x: Option<_>| x.and_then(|x| x)) >>
+                rest: cond!(match dotdot {
+                                Some((_, Some(_))) => true,
+                                _ => false,
+                            },
+                            call!(Delimited::parse_terminated)) >>
+                (elems, dotdot, rest)
+            )) >>
+            ({
+                let ((mut elems, dotdot, rest), parens) = data;
+                let (dotdot, trailing) = match dotdot {
+                    Some((a, b)) => (Some(a), Some(b)),
+                    None => (None, None),
+                };
+                PatTuple {
+                    paren_token: parens,
+                    dots_pos: dotdot.as_ref().map(|_| elems.len()),
+                    dot2_token: dotdot,
+                    comma_token: trailing.and_then(|b| b),
+                    pats: {
+                        if let Some(rest) = rest {
+                            for elem in rest {
+                                elems.push(elem);
                             }
-                            elems
-                        },
-                    }
-                })
-            }
-        }
+                        }
+                        elems
+                    },
+                }
+            })
+        ));
     }
 
     impl Synom for PatRef {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                and: syn!(And) >>
-                mutability: syn!(Mutability) >>
-                pat: syn!(Pat) >>
-                (PatRef {
-                    pat: Box::new(pat),
-                    mutbl: mutability,
-                    and_token: and,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            and: syn!(And) >>
+            mutability: syn!(Mutability) >>
+            pat: syn!(Pat) >>
+            (PatRef {
+                pat: Box::new(pat),
+                mutbl: mutability,
+                and_token: and,
+            })
+        ));
     }
 
     impl Synom for PatLit {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lit: pat_lit_expr >>
-                (if let ExprKind::Path(_) = lit.node {
-                    return IResult::Error; // these need to be parsed by pat_path
-                } else {
-                    PatLit {
-                        expr: Box::new(lit),
-                    }
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lit: pat_lit_expr >>
+            (if let ExprKind::Path(_) = lit.node {
+                return parse_error(); // these need to be parsed by pat_path
+            } else {
+                PatLit {
+                    expr: Box::new(lit),
+                }
+            })
+        ));
     }
 
     impl Synom for PatRange {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lo: pat_lit_expr >>
-                limits: syn!(RangeLimits) >>
-                hi: pat_lit_expr >>
-                (PatRange {
-                    lo: Box::new(lo),
-                    hi: Box::new(hi),
-                    limits: limits,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lo: pat_lit_expr >>
+            limits: syn!(RangeLimits) >>
+            hi: pat_lit_expr >>
+            (PatRange {
+                lo: Box::new(lo),
+                hi: Box::new(hi),
+                limits: limits,
+            })
+        ));
     }
 
     named!(pat_lit_expr -> Expr, do_parse!(
@@ -1857,59 +1751,53 @@
     ));
 
     impl Synom for PatSlice {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                brackets!(do_parse!(
-                    before: call!(Delimited::parse_terminated) >>
-                    middle: option!(do_parse!(
-                        dots: syn!(Dot2) >>
-                        trailing: option!(syn!(Comma)) >>
-                        (dots, trailing)
-                    )) >>
-                    after: cond!(
-                        match middle {
-                            Some((_, ref trailing)) => trailing.is_some(),
-                            _ => false,
-                        },
-                        call!(Delimited::parse_terminated)
-                    ) >>
-                    (before, middle, after)
-                )),
-                |((before, middle, after), brackets)| {
-                    let mut before: Delimited<Pat, tokens::Comma> = before;
-                    let after: Option<Delimited<Pat, tokens::Comma>> = after;
-                    let middle: Option<(Dot2, Option<Comma>)> = middle;
-                    PatSlice {
-                        dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
-                        comma_token: middle.as_ref().and_then(|m| {
-                            m.1.as_ref().map(|m| Comma(m.0))
-                        }),
-                        bracket_token: brackets,
-                        middle: middle.and_then(|_| {
-                            if !before.is_empty() && !before.trailing_delim() {
-                                Some(Box::new(before.pop().unwrap().into_item()))
-                            } else {
-                                None
-                            }
-                        }),
-                        front: before,
-                        back: after.unwrap_or_default(),
-                    }
+        named!(parse -> Self, map!(
+            brackets!(do_parse!(
+                before: call!(Delimited::parse_terminated) >>
+                middle: option!(do_parse!(
+                    dots: syn!(Dot2) >>
+                    trailing: option!(syn!(Comma)) >>
+                    (dots, trailing)
+                )) >>
+                after: cond!(
+                    match middle {
+                        Some((_, ref trailing)) => trailing.is_some(),
+                        _ => false,
+                    },
+                    call!(Delimited::parse_terminated)
+                ) >>
+                (before, middle, after)
+            )),
+            |((before, middle, after), brackets)| {
+                let mut before: Delimited<Pat, tokens::Comma> = before;
+                let after: Option<Delimited<Pat, tokens::Comma>> = after;
+                let middle: Option<(Dot2, Option<Comma>)> = middle;
+                PatSlice {
+                    dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
+                    comma_token: middle.as_ref().and_then(|m| {
+                        m.1.as_ref().map(|m| Comma(m.0))
+                    }),
+                    bracket_token: brackets,
+                    middle: middle.and_then(|_| {
+                        if !before.is_empty() && !before.trailing_delim() {
+                            Some(Box::new(before.pop().unwrap().into_item()))
+                        } else {
+                            None
+                        }
+                    }),
+                    front: before,
+                    back: after.unwrap_or_default(),
                 }
             }
-        }
+        ));
     }
 
     impl Synom for CaptureBy {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Move) => { CaptureBy::Value }
-                |
-                epsilon!() => { |_| CaptureBy::Ref }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Move) => { CaptureBy::Value }
+            |
+            epsilon!() => { |_| CaptureBy::Ref }
+        ));
     }
 
     named!(label -> Ident, map!(syn!(Lifetime), |lt: Lifetime| lt.ident));
diff --git a/src/generics.rs b/src/generics.rs
index 71cd8f6..2ab61bf 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -211,144 +211,129 @@
 pub mod parsing {
     use super::*;
 
-    use synom::{IResult, Synom};
+    use synom::{PResult, Cursor, Synom, parse_error};
     use synom::tokens::*;
-    use proc_macro2::{TokenTree, TokenKind};
+    use proc_macro2::TokenKind;
 
     impl Synom for Generics {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                alt!(
-                    do_parse!(
-                        lt: syn!(Lt) >>
-                        lifetimes: call!(Delimited::parse_terminated) >>
-                        ty_params: cond!(
-                            lifetimes.is_empty() || lifetimes.trailing_delim(),
-                            call!(Delimited::parse_terminated)
-                        ) >>
-                        gt: syn!(Gt) >>
-                        (lifetimes, ty_params, Some(lt), Some(gt))
-                    )
-                    |
-                    epsilon!() => { |_| (Delimited::new(), None, None, None) }
-                ),
-                |(lifetimes, ty_params, lt, gt): (_, Option<_>, _, _)| Generics {
-                    lifetimes: lifetimes,
-                    ty_params: ty_params.unwrap_or_default(),
-                    where_clause: WhereClause::default(),
-                    gt_token: gt,
-                    lt_token: lt,
-                }
+        named!(parse -> Self, map!(
+            alt!(
+                do_parse!(
+                    lt: syn!(Lt) >>
+                    lifetimes: call!(Delimited::parse_terminated) >>
+                    ty_params: cond!(
+                        lifetimes.is_empty() || lifetimes.trailing_delim(),
+                        call!(Delimited::parse_terminated)
+                    ) >>
+                    gt: syn!(Gt) >>
+                    (lifetimes, ty_params, Some(lt), Some(gt))
+                )
+                |
+                epsilon!() => { |_| (Delimited::new(), None, None, None) }
+            ),
+            |(lifetimes, ty_params, lt, gt): (_, Option<_>, _, _)| Generics {
+                lifetimes: lifetimes,
+                ty_params: ty_params.unwrap_or_default(),
+                where_clause: WhereClause::default(),
+                gt_token: gt,
+                lt_token: lt,
             }
-        }
+        ));
     }
 
     impl Synom for Lifetime {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
+        fn parse(input: Cursor) -> PResult<Self> {
             let mut tokens = input.iter();
             let token = match tokens.next() {
                 Some(token) => token,
-                None => return IResult::Error,
+                None => return parse_error(),
             };
             if let TokenKind::Word(s) = token.kind {
                 if s.as_str().starts_with('\'') {
-                    return IResult::Done(tokens.as_slice(), Lifetime {
+                    return Ok((tokens.as_slice(), Lifetime {
                         ident: Ident {
                             span: Span(token.span),
                             sym: s,
                         },
-                    })
+                    }))
                 }
             }
-            IResult::Error
+            parse_error()
         }
     }
 
     impl Synom for LifetimeDef {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                life: syn!(Lifetime) >>
-                colon: option!(syn!(Colon)) >>
-                bounds: cond!(
-                    colon.is_some(),
-                    call!(Delimited::parse_separated_nonempty)
-                ) >>
-                (LifetimeDef {
-                    attrs: attrs,
-                    lifetime: life,
-                    bounds: bounds.unwrap_or_default(),
-                    colon_token: colon.map(|_| tokens::Colon::default()),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            life: syn!(Lifetime) >>
+            colon: option!(syn!(Colon)) >>
+            bounds: cond!(
+                colon.is_some(),
+                call!(Delimited::parse_separated_nonempty)
+            ) >>
+            (LifetimeDef {
+                attrs: attrs,
+                lifetime: life,
+                bounds: bounds.unwrap_or_default(),
+                colon_token: colon.map(|_| tokens::Colon::default()),
+            })
+        ));
     }
 
     impl Synom for BoundLifetimes {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                for_: syn!(For) >>
-                lt: syn!(Lt) >>
-                lifetimes: call!(Delimited::parse_terminated) >>
-                gt: syn!(Gt) >>
-                (BoundLifetimes {
-                    for_token: for_,
-                    lt_token: lt,
-                    gt_token: gt,
-                    lifetimes: lifetimes,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            for_: syn!(For) >>
+            lt: syn!(Lt) >>
+            lifetimes: call!(Delimited::parse_terminated) >>
+            gt: syn!(Gt) >>
+            (BoundLifetimes {
+                for_token: for_,
+                lt_token: lt,
+                gt_token: gt,
+                lifetimes: lifetimes,
+            })
+        ));
     }
 
     impl Synom for TyParam {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                attrs: many0!(call!(Attribute::parse_outer)) >>
-                id: syn!(Ident) >>
-                colon: option!(syn!(Colon)) >>
-                bounds: cond!(
-                    colon.is_some(),
-                    call!(Delimited::parse_separated_nonempty)
-                ) >>
-                default: option!(do_parse!(
-                    eq: syn!(Eq) >>
-                    ty: syn!(Ty) >>
-                    (eq, ty)
-                )) >>
-                (TyParam {
-                    attrs: attrs,
-                    ident: id,
-                    bounds: bounds.unwrap_or_default(),
-                    colon_token: colon,
-                    eq_token: default.as_ref().map(|d| tokens::Eq((d.0).0)),
-                    default: default.map(|d| d.1),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            attrs: many0!(call!(Attribute::parse_outer)) >>
+            id: syn!(Ident) >>
+            colon: option!(syn!(Colon)) >>
+            bounds: cond!(
+                colon.is_some(),
+                call!(Delimited::parse_separated_nonempty)
+            ) >>
+            default: option!(do_parse!(
+                eq: syn!(Eq) >>
+                ty: syn!(Ty) >>
+                (eq, ty)
+            )) >>
+            (TyParam {
+                attrs: attrs,
+                ident: id,
+                bounds: bounds.unwrap_or_default(),
+                colon_token: colon,
+                eq_token: default.as_ref().map(|d| tokens::Eq((d.0).0)),
+                default: default.map(|d| d.1),
+            })
+        ));
     }
 
     impl Synom for TyParamBound {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    question: syn!(Question) >>
-                    poly: syn!(PolyTraitRef) >>
-                    (TyParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
-                )
-                |
-                syn!(Lifetime) => { TyParamBound::Region }
-                |
-                syn!(PolyTraitRef) => {
-                    |poly| TyParamBound::Trait(poly, TraitBoundModifier::None)
-                }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                question: syn!(Question) >>
+                poly: syn!(PolyTraitRef) >>
+                (TyParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
+            )
+            |
+            syn!(Lifetime) => { TyParamBound::Region }
+            |
+            syn!(PolyTraitRef) => {
+                |poly| TyParamBound::Trait(poly, TraitBoundModifier::None)
             }
-        }
+        ));
 
         fn description() -> Option<&'static str> {
             Some("type parameter buond")
@@ -356,21 +341,18 @@
     }
 
     impl Synom for WhereClause {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    where_: syn!(Where) >>
-                    predicates: call!(Delimited::parse_terminated) >>
-                    (WhereClause {
-                        predicates: predicates,
-                        where_token: Some(where_),
-                    })
-                )
-                |
-                epsilon!() => { |_| WhereClause::default() }
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                where_: syn!(Where) >>
+                predicates: call!(Delimited::parse_terminated) >>
+                (WhereClause {
+                    predicates: predicates,
+                    where_token: Some(where_),
+                })
+            )
+            |
+            epsilon!() => { |_| WhereClause::default() }
+        ));
 
         fn description() -> Option<&'static str> {
             Some("where clause")
@@ -378,37 +360,34 @@
     }
 
     impl Synom for WherePredicate {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    ident: syn!(Lifetime) >>
-                    colon: option!(syn!(Colon)) >>
-                    bounds: cond!(
-                        colon.is_some(),
-                        call!(Delimited::parse_separated)
-                    ) >>
-                    (WherePredicate::RegionPredicate(WhereRegionPredicate {
-                        lifetime: ident,
-                        bounds: bounds.unwrap_or_default(),
-                        colon_token: colon,
-                    }))
-                )
-                |
-                do_parse!(
-                    bound_lifetimes: option!(syn!(BoundLifetimes)) >>
-                    bounded_ty: syn!(Ty) >>
-                    colon: syn!(Colon) >>
-                    bounds: call!(Delimited::parse_separated_nonempty) >>
-                    (WherePredicate::BoundPredicate(WhereBoundPredicate {
-                        bound_lifetimes: bound_lifetimes,
-                        bounded_ty: bounded_ty,
-                        bounds: bounds,
-                        colon_token: colon,
-                    }))
-                )
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                ident: syn!(Lifetime) >>
+                colon: option!(syn!(Colon)) >>
+                bounds: cond!(
+                    colon.is_some(),
+                    call!(Delimited::parse_separated)
+                ) >>
+                (WherePredicate::RegionPredicate(WhereRegionPredicate {
+                    lifetime: ident,
+                    bounds: bounds.unwrap_or_default(),
+                    colon_token: colon,
+                }))
+            )
+            |
+            do_parse!(
+                bound_lifetimes: option!(syn!(BoundLifetimes)) >>
+                bounded_ty: syn!(Ty) >>
+                colon: syn!(Colon) >>
+                bounds: call!(Delimited::parse_separated_nonempty) >>
+                (WherePredicate::BoundPredicate(WhereBoundPredicate {
+                    bound_lifetimes: bound_lifetimes,
+                    bounded_ty: bounded_ty,
+                    bounds: bounds,
+                    colon_token: colon,
+                }))
+            )
+        ));
     }
 }
 
diff --git a/src/ident.rs b/src/ident.rs
index 3ffacc7..dcd8dd1 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -114,22 +114,22 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use proc_macro2::{TokenTree, TokenKind};
-    use synom::{Synom, IResult};
+    use proc_macro2::TokenKind;
+    use synom::{Synom, PResult, Cursor, parse_error};
 
     impl Synom for Ident {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
+        fn parse(input: Cursor) -> PResult<Self> {
             let mut tokens = input.iter();
             let token = match tokens.next() {
                 Some(token) => token,
-                None => return IResult::Error,
+                None => return parse_error(),
             };
             let word = match token.kind {
                 TokenKind::Word(s) => s,
-                _ => return IResult::Error,
+                _ => return parse_error(),
             };
             if word.as_str().starts_with('\'') {
-                return IResult::Error
+                return parse_error();
             }
             match word.as_str() {
                 // From https://doc.rust-lang.org/grammar.html#keywords
@@ -139,14 +139,14 @@
                 "mut" | "offsetof" | "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
                 "return" | "Self" | "self" | "sizeof" | "static" | "struct" | "super" | "trait" |
                 "true" | "type" | "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" |
-                "while" | "yield" => return IResult::Error,
+                "while" | "yield" => return parse_error(),
                 _ => {}
             }
 
-            IResult::Done(tokens.as_slice(), Ident {
+            Ok((tokens.as_slice(), Ident {
                 span: Span(token.span),
                 sym: word,
-            })
+            }))
         }
 
         fn description() -> Option<&'static str> {
diff --git a/src/item.rs b/src/item.rs
index d6d1521..a433512 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -418,44 +418,40 @@
 pub mod parsing {
     use super::*;
 
-    use proc_macro2::TokenTree;
-    use synom::{IResult, Synom};
+    use synom::Synom;
     use synom::tokens::*;
     use synom::tokens;
 
     impl Synom for Item {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                item_extern_crate
-                |
-                item_use
-                |
-                item_static
-                |
-                item_const
-                |
-                item_fn
-                |
-                item_mod
-                |
-                item_foreign_mod
-                |
-                item_ty
-                |
-                item_struct_or_enum
-                |
-                item_union
-                |
-                item_trait
-                |
-                item_default_impl
-                |
-                item_impl
-                |
-                item_mac
-            }
-        }
+        named!(parse -> Self, alt!(
+            item_extern_crate
+            |
+            item_use
+            |
+            item_static
+            |
+            item_const
+            |
+            item_fn
+            |
+            item_mod
+            |
+            item_foreign_mod
+            |
+            item_ty
+            |
+            item_struct_or_enum
+            |
+            item_union
+            |
+            item_trait
+            |
+            item_default_impl
+            |
+            item_impl
+            |
+            item_mac
+        ));
 
         fn description() -> Option<&'static str> {
             Some("item")
@@ -528,100 +524,85 @@
     ));
 
     impl Synom for ViewPath {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(PathGlob) => { ViewPath::Glob }
-                |
-                syn!(PathList) => { ViewPath::List }
-                |
-                syn!(PathSimple) => { ViewPath::Simple } // must be last
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(PathGlob) => { ViewPath::Glob }
+            |
+            syn!(PathList) => { ViewPath::List }
+            |
+            syn!(PathSimple) => { ViewPath::Simple } // must be last
+        ));
     }
 
     impl Synom for PathSimple {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                path: syn!(Path) >>
-                rename: option!(tuple!(syn!(As), syn!(Ident))) >>
-                (PathSimple {
-                    path: path,
-                    as_token: rename.as_ref().map(|p| As((p.0).0)),
-                    rename: rename.map(|p| p.1),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            path: syn!(Path) >>
+            rename: option!(tuple!(syn!(As), syn!(Ident))) >>
+            (PathSimple {
+                path: path,
+                as_token: rename.as_ref().map(|p| As((p.0).0)),
+                rename: rename.map(|p| p.1),
+            })
+        ));
     }
 
     impl Synom for PathGlob {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                path: syn!(Path) >>
-                colon2: syn!(Colon2) >>
-                star: syn!(Star) >>
-                (PathGlob {
-                    path: path,
-                    colon2_token: colon2,
-                    star_token: star,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            path: syn!(Path) >>
+            colon2: syn!(Colon2) >>
+            star: syn!(Star) >>
+            (PathGlob {
+                path: path,
+                colon2_token: colon2,
+                star_token: star,
+            })
+        ));
     }
 
     impl Synom for PathList {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    path: syn!(Path) >>
-                    colon2: syn!(Colon2) >>
-                    items: braces!(call!(Delimited::parse_terminated)) >>
-                    (PathList {
-                        path: path,
-                        items: items.0,
-                        brace_token: items.1,
-                        colon2_token: colon2,
-                    })
-                )
-                |
-                do_parse!(
-                    global: option!(syn!(Colon2)) >>
-                    items: braces!(call!(Delimited::parse_terminated)) >>
-                    (PathList {
-                        path: Path {
-                            global: global.is_some(),
-                            segments: Delimited::new(),
-                            leading_colon: None,
-                        },
-                        colon2_token: global.unwrap_or_default(),
-                        brace_token: items.1,
-                        items: items.0,
-                    })
-                )
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                path: syn!(Path) >>
+                colon2: syn!(Colon2) >>
+                items: braces!(call!(Delimited::parse_terminated)) >>
+                (PathList {
+                    path: path,
+                    items: items.0,
+                    brace_token: items.1,
+                    colon2_token: colon2,
+                })
+            )
+            |
+            do_parse!(
+                global: option!(syn!(Colon2)) >>
+                items: braces!(call!(Delimited::parse_terminated)) >>
+                (PathList {
+                    path: Path {
+                        global: global.is_some(),
+                        segments: Delimited::new(),
+                        leading_colon: None,
+                    },
+                    colon2_token: global.unwrap_or_default(),
+                    brace_token: items.1,
+                    items: items.0,
+                })
+            )
+        ));
     }
 
     impl Synom for PathListItem {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                name: alt!(
-                    syn!(Ident)
-                    |
-                    map!(syn!(Self_), Into::into)
-                ) >>
-                rename: option!(tuple!(syn!(As), syn!(Ident))) >>
-                (PathListItem {
-                    name: name,
-                    as_token: rename.as_ref().map(|p| As((p.0).0)),
-                    rename: rename.map(|p| p.1),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            name: alt!(
+                syn!(Ident)
+                |
+                map!(syn!(Self_), Into::into)
+            ) >>
+            rename: option!(tuple!(syn!(As), syn!(Ident))) >>
+            (PathListItem {
+                name: name,
+                as_token: rename.as_ref().map(|p| As((p.0).0)),
+                rename: rename.map(|p| p.1),
+            })
+        ));
     }
 
     named!(item_static -> Item, do_parse!(
@@ -725,47 +706,44 @@
     ));
 
     impl Synom for FnArg {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    and: syn!(And) >>
-                    lt: option!(syn!(Lifetime)) >>
-                    mutability: syn!(Mutability) >>
-                    self_: syn!(Self_) >>
-                    not!(syn!(Colon)) >>
-                    (ArgSelfRef {
-                        lifetime: lt,
-                        mutbl: mutability,
-                        and_token: and,
-                        self_token: self_,
-                    }.into())
-                )
-                |
-                do_parse!(
-                    mutability: syn!(Mutability) >>
-                    self_: syn!(Self_) >>
-                    not!(syn!(Colon)) >>
-                    (ArgSelf {
-                        mutbl: mutability,
-                        self_token: self_,
-                    }.into())
-                )
-                |
-                do_parse!(
-                    pat: syn!(Pat) >>
-                    colon: syn!(Colon) >>
-                    ty: syn!(Ty) >>
-                    (ArgCaptured {
-                        pat: pat,
-                        ty: ty,
-                        colon_token: colon,
-                    }.into())
-                )
-                |
-                syn!(Ty) => { FnArg::Ignored }
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                and: syn!(And) >>
+                lt: option!(syn!(Lifetime)) >>
+                mutability: syn!(Mutability) >>
+                self_: syn!(Self_) >>
+                not!(syn!(Colon)) >>
+                (ArgSelfRef {
+                    lifetime: lt,
+                    mutbl: mutability,
+                    and_token: and,
+                    self_token: self_,
+                }.into())
+            )
+            |
+            do_parse!(
+                mutability: syn!(Mutability) >>
+                self_: syn!(Self_) >>
+                not!(syn!(Colon)) >>
+                (ArgSelf {
+                    mutbl: mutability,
+                    self_token: self_,
+                }.into())
+            )
+            |
+            do_parse!(
+                pat: syn!(Pat) >>
+                colon: syn!(Colon) >>
+                ty: syn!(Ty) >>
+                (ArgCaptured {
+                    pat: pat,
+                    ty: ty,
+                    colon_token: colon,
+                }.into())
+            )
+            |
+            syn!(Ty) => { FnArg::Ignored }
+        ));
     }
 
     named!(item_mod -> Item, do_parse!(
@@ -828,14 +806,11 @@
     ));
 
     impl Synom for ForeignItem {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                foreign_fn
-                |
-                foreign_static
-            }
-        }
+        named!(parse -> Self, alt!(
+            foreign_fn
+            |
+            foreign_static
+        ));
     }
 
     named!(foreign_fn -> ForeignItem, do_parse!(
@@ -1036,18 +1011,15 @@
     ));
 
     impl Synom for TraitItem {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                trait_item_const
-                |
-                trait_item_method
-                |
-                trait_item_type
-                |
-                trait_item_mac
-            }
-        }
+        named!(parse -> Self, alt!(
+            trait_item_const
+            |
+            trait_item_method
+            |
+            trait_item_type
+            |
+            trait_item_mac
+        ));
     }
 
     named!(trait_item_const -> TraitItem, do_parse!(
@@ -1205,18 +1177,15 @@
     ));
 
     impl Synom for ImplItem {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                impl_item_const
-                |
-                impl_item_method
-                |
-                impl_item_type
-                |
-                impl_item_macro
-            }
-        }
+        named!(parse -> Self, alt!(
+            impl_item_const
+            |
+            impl_item_method
+            |
+            impl_item_type
+            |
+            impl_item_macro
+        ));
     }
 
     named!(impl_item_const -> ImplItem, do_parse!(
@@ -1335,36 +1304,27 @@
     ));
 
     impl Synom for ImplPolarity {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Bang) => { ImplPolarity::Negative }
-                |
-                epsilon!() => { |_| ImplPolarity::Positive }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Bang) => { ImplPolarity::Negative }
+            |
+            epsilon!() => { |_| ImplPolarity::Positive }
+        ));
     }
 
     impl Synom for Constness {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Const) => { Constness::Const }
-                |
-                epsilon!() => { |_| Constness::NotConst }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Const) => { Constness::Const }
+            |
+            epsilon!() => { |_| Constness::NotConst }
+        ));
     }
 
     impl Synom for Defaultness {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Default_) => { Defaultness::Default }
-                |
-                epsilon!() => { |_| Defaultness::Final }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Default_) => { Defaultness::Default }
+            |
+            epsilon!() => { |_| Defaultness::Final }
+        ));
     }
 }
 
diff --git a/src/krate.rs b/src/krate.rs
index 3894982..7239bc3 100644
--- a/src/krate.rs
+++ b/src/krate.rs
@@ -12,8 +12,7 @@
 pub mod parsing {
     use super::*;
 
-    use synom::{IResult, Synom, ParseError};
-    use proc_macro2::TokenTree;
+    use synom::{Synom, ParseError};
 
     impl Synom for Crate {
         named!(parse -> Self, do_parse!(
diff --git a/src/lit.rs b/src/lit.rs
index 0be32d5..c9b4229 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -101,26 +101,25 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use proc_macro2::TokenTree;
-    use synom::{Synom, IResult};
+    use synom::{Synom, PResult, Cursor, parse_error};
 
     impl Synom for Lit {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
+        fn parse(input: Cursor) -> PResult<Self> {
             let mut tokens = input.iter();
             let token = match tokens.next() {
                 Some(token) => token,
-                None => return IResult::Error,
+                None => return parse_error(),
             };
             let kind = match token.kind {
                 TokenKind::Literal(ref l) => LitKind::Other(l.clone()),
                 TokenKind::Word(ref s) if s.as_str() == "true" => LitKind::Bool(true),
                 TokenKind::Word(ref s) if s.as_str() == "false" => LitKind::Bool(false),
-                _ => return IResult::Error,
+                _ => return parse_error(),
             };
-            IResult::Done(tokens.as_slice(), Lit {
+            Ok((tokens.as_slice(), Lit {
                 span: Span(token.span),
                 value: kind,
-            })
+            }))
         }
     }
 }
diff --git a/src/mac.rs b/src/mac.rs
index 5e6d02e..b822051 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -137,36 +137,33 @@
 
     use proc_macro2::{TokenKind, TokenTree};
     use synom::tokens::*;
-    use synom::{Synom, IResult};
+    use synom::{Synom, PResult, Cursor, parse_error};
 
     impl Synom for Mac {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                what: syn!(Path) >>
-                bang: syn!(Bang) >>
-                body: call!(::TokenTree::parse_delimited) >>
-                (Mac {
-                    path: what,
-                    bang_token: bang,
-                    tokens: vec![body],
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            what: syn!(Path) >>
+            bang: syn!(Bang) >>
+            body: call!(::TokenTree::parse_delimited) >>
+            (Mac {
+                path: what,
+                bang_token: bang,
+                tokens: vec![body],
+            })
+        ));
     }
 
     impl ::TokenTree {
-        pub fn parse_list(input: &[TokenTree]) -> IResult<&[TokenTree], Vec<Self>> {
-            IResult::Done(&[], input.iter().cloned().map(::TokenTree).collect())
+        pub fn parse_list(input: Cursor) -> PResult<Vec<Self>> {
+            Ok((&[], input.iter().cloned().map(::TokenTree).collect()))
         }
 
-        pub fn parse_delimited(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
+        pub fn parse_delimited(input: Cursor) -> PResult<Self> {
             let mut tokens = input.iter();
             match tokens.next() {
                 Some(token @ &TokenTree { kind: TokenKind::Sequence(..), .. }) => {
-                    IResult::Done(tokens.as_slice(), ::TokenTree(token.clone()))
+                    Ok((tokens.as_slice(), ::TokenTree(token.clone())))
                 }
-                _ => IResult::Error,
+                _ => parse_error(),
             }
         }
     }
diff --git a/src/op.rs b/src/op.rs
index e059929..a044359 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -77,89 +77,80 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use synom::{TokenTree, IResult, Synom};
+    use synom::Synom;
     use synom::tokens::*;
 
     impl BinOp {
-        pub fn parse_binop(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(AndAnd) => { BinOp::And }
-                |
-                syn!(OrOr) => { BinOp::Or }
-                |
-                syn!(Shl) => { BinOp::Shl }
-                |
-                syn!(Shr) => { BinOp::Shr }
-                |
-                syn!(EqEq) => { BinOp::Eq }
-                |
-                syn!(Le) => { BinOp::Le }
-                |
-                syn!(Ne) => { BinOp::Ne }
-                |
-                syn!(Ge) => { BinOp::Ge }
-                |
-                syn!(Add) => { BinOp::Add }
-                |
-                syn!(Sub) => { BinOp::Sub }
-                |
-                syn!(Star) => { BinOp::Mul }
-                |
-                syn!(Div) => { BinOp::Div }
-                |
-                syn!(Rem) => { BinOp::Rem }
-                |
-                syn!(Caret) => { BinOp::BitXor }
-                |
-                syn!(And) => { BinOp::BitAnd }
-                |
-                syn!(Or) => { BinOp::BitOr }
-                |
-                syn!(Lt) => { BinOp::Lt }
-                |
-                syn!(Gt) => { BinOp::Gt }
-            }
-        }
+        named!(pub parse_binop -> Self, alt!(
+            syn!(AndAnd) => { BinOp::And }
+            |
+            syn!(OrOr) => { BinOp::Or }
+            |
+            syn!(Shl) => { BinOp::Shl }
+            |
+            syn!(Shr) => { BinOp::Shr }
+            |
+            syn!(EqEq) => { BinOp::Eq }
+            |
+            syn!(Le) => { BinOp::Le }
+            |
+            syn!(Ne) => { BinOp::Ne }
+            |
+            syn!(Ge) => { BinOp::Ge }
+            |
+            syn!(Add) => { BinOp::Add }
+            |
+            syn!(Sub) => { BinOp::Sub }
+            |
+            syn!(Star) => { BinOp::Mul }
+            |
+            syn!(Div) => { BinOp::Div }
+            |
+            syn!(Rem) => { BinOp::Rem }
+            |
+            syn!(Caret) => { BinOp::BitXor }
+            |
+            syn!(And) => { BinOp::BitAnd }
+            |
+            syn!(Or) => { BinOp::BitOr }
+            |
+            syn!(Lt) => { BinOp::Lt }
+            |
+            syn!(Gt) => { BinOp::Gt }
+        ));
 
         #[cfg(feature = "full")]
-        pub fn parse_assign_op(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(AddEq) => { BinOp::AddEq }
-                |
-                syn!(SubEq) => { BinOp::SubEq }
-                |
-                syn!(MulEq) => { BinOp::MulEq }
-                |
-                syn!(DivEq) => { BinOp::DivEq }
-                |
-                syn!(RemEq) => { BinOp::RemEq }
-                |
-                syn!(CaretEq) => { BinOp::BitXorEq }
-                |
-                syn!(AndEq) => { BinOp::BitAndEq }
-                |
-                syn!(OrEq) => { BinOp::BitOrEq }
-                |
-                syn!(ShlEq) => { BinOp::ShlEq }
-                |
-                syn!(ShrEq) => { BinOp::ShrEq }
-            }
-        }
+        named!(pub parse_assign_op -> Self, alt!(
+            syn!(AddEq) => { BinOp::AddEq }
+            |
+            syn!(SubEq) => { BinOp::SubEq }
+            |
+            syn!(MulEq) => { BinOp::MulEq }
+            |
+            syn!(DivEq) => { BinOp::DivEq }
+            |
+            syn!(RemEq) => { BinOp::RemEq }
+            |
+            syn!(CaretEq) => { BinOp::BitXorEq }
+            |
+            syn!(AndEq) => { BinOp::BitAndEq }
+            |
+            syn!(OrEq) => { BinOp::BitOrEq }
+            |
+            syn!(ShlEq) => { BinOp::ShlEq }
+            |
+            syn!(ShrEq) => { BinOp::ShrEq }
+        ));
     }
 
     impl Synom for UnOp {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Star) => { UnOp::Deref }
-                |
-                syn!(Bang) => { UnOp::Not }
-                |
-                syn!(Sub) => { UnOp::Neg }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Star) => { UnOp::Deref }
+            |
+            syn!(Bang) => { UnOp::Not }
+            |
+            syn!(Sub) => { UnOp::Neg }
+        ));
     }
 }
 
diff --git a/src/ty.rs b/src/ty.rs
index 0ee4188..284ffb3 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -314,53 +314,38 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    // use {TyParamBound, TraitBoundModifier};
-    // #[cfg(feature = "full")]
-    // use ConstExpr;
-    // #[cfg(feature = "full")]
-    // use constant::parsing::const_expr;
-    // #[cfg(feature = "full")]
-    // use expr::parsing::expr;
-    // use generics::parsing::{lifetime, ty_param_bound, bound_lifetimes};
-    // use ident::parsing::ident;
-    // use lit::parsing::string;
-    // use mac::parsing::mac;
-    use proc_macro2::TokenTree;
-    use synom::{IResult, Synom};
+    use synom::Synom;
     use synom::tokens::*;
 
     impl Synom for Ty {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                // must be before mac
-                syn!(TyParen) => { Ty::Paren }
-                |
-                // must be before path
-                syn!(Mac) => { Ty::Mac }
-                |
-                // must be before ty_poly_trait_ref
-                ty_path
-                |
-                syn!(TySlice) => { Ty::Slice }
-                |
-                syn!(TyArray) => { Ty::Array }
-                |
-                syn!(TyPtr) => { Ty::Ptr }
-                |
-                syn!(TyRptr) => { Ty::Rptr }
-                |
-                syn!(TyBareFn) => { Ty::BareFn }
-                |
-                syn!(TyNever) => { Ty::Never }
-                |
-                syn!(TyTup) => { Ty::Tup }
-                |
-                ty_poly_trait_ref
-                |
-                syn!(TyImplTrait) => { Ty::ImplTrait }
-            }
-        }
+        named!(parse -> Self, alt!(
+            // must be before mac
+            syn!(TyParen) => { Ty::Paren }
+            |
+            // must be before path
+            syn!(Mac) => { Ty::Mac }
+            |
+            // must be before ty_poly_trait_ref
+            ty_path
+            |
+            syn!(TySlice) => { Ty::Slice }
+            |
+            syn!(TyArray) => { Ty::Array }
+            |
+            syn!(TyPtr) => { Ty::Ptr }
+            |
+            syn!(TyRptr) => { Ty::Rptr }
+            |
+            syn!(TyBareFn) => { Ty::BareFn }
+            |
+            syn!(TyNever) => { Ty::Never }
+            |
+            syn!(TyTup) => { Ty::Tup }
+            |
+            ty_poly_trait_ref
+            |
+            syn!(TyImplTrait) => { Ty::ImplTrait }
+        ));
 
         fn description() -> Option<&'static str> {
             Some("type")
@@ -368,38 +353,32 @@
     }
 
     impl Synom for TySlice {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                brackets!(syn!(Ty)),
-                |(ty, b)| TySlice {
-                    ty: Box::new(ty),
-                    bracket_token: b,
-                }
+        named!(parse -> Self, map!(
+            brackets!(syn!(Ty)),
+            |(ty, b)| TySlice {
+                ty: Box::new(ty),
+                bracket_token: b,
             }
-        }
+        ));
     }
 
     impl Synom for TyArray {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                brackets!(do_parse!(
-                    elem: syn!(Ty) >>
+        named!(parse -> Self, map!(
+            brackets!(do_parse!(
+                elem: syn!(Ty) >>
                     semi: syn!(Semi) >>
                     len: array_len >>
                     (elem, semi, len)
-                )),
-                |((elem, semi, len), brackets)| {
-                    TyArray {
-                        ty: Box::new(elem),
-                        amt: len,
-                        bracket_token: brackets,
-                        semi_token: semi,
-                    }
+            )),
+            |((elem, semi, len), brackets)| {
+                TyArray {
+                    ty: Box::new(elem),
+                    amt: len,
+                    bracket_token: brackets,
+                    semi_token: semi,
                 }
             }
-        }
+        ));
     }
 
     #[cfg(not(feature = "full"))]
@@ -413,101 +392,86 @@
     ));
 
     impl Synom for TyPtr {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                star: syn!(Star) >>
-                mutability: alt!(
-                    syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
-                    |
-                    syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
-                ) >>
-                target: syn!(Ty) >>
-                (TyPtr {
-                    const_token: mutability.1,
-                    star_token: star,
-                    ty: Box::new(MutTy {
-                        ty: target,
-                        mutability: mutability.0,
-                    }),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            star: syn!(Star) >>
+            mutability: alt!(
+                syn!(Const) => { |c| (Mutability::Immutable, Some(c)) }
+                |
+                syn!(Mut) => { |m| (Mutability::Mutable(m), None) }
+            ) >>
+            target: syn!(Ty) >>
+            (TyPtr {
+                const_token: mutability.1,
+                star_token: star,
+                ty: Box::new(MutTy {
+                    ty: target,
+                    mutability: mutability.0,
+                }),
+            })
+        ));
     }
 
     impl Synom for TyRptr {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                amp: syn!(And) >>
-                life: option!(syn!(Lifetime)) >>
-                mutability: syn!(Mutability) >>
-                target: syn!(Ty) >>
-                (TyRptr {
-                    lifetime: life,
-                    ty: Box::new(MutTy {
-                        ty: target,
-                        mutability: mutability,
-                    }),
-                    and_token: amp,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            amp: syn!(And) >>
+            life: option!(syn!(Lifetime)) >>
+            mutability: syn!(Mutability) >>
+            target: syn!(Ty) >>
+            (TyRptr {
+                lifetime: life,
+                ty: Box::new(MutTy {
+                    ty: target,
+                    mutability: mutability,
+                }),
+                and_token: amp,
+            })
+        ));
     }
 
     impl Synom for TyBareFn {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                lifetimes: option!(syn!(BoundLifetimes)) >>
-                unsafety: syn!(Unsafety) >>
-                abi: option!(syn!(Abi)) >>
-                fn_: syn!(Fn_) >>
-                parens: parens!(do_parse!(
-                    inputs: call!(Delimited::parse_terminated) >>
-                    variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
-                                                   syn!(Dot3))) >>
-                    (inputs, variadic)
-                )) >>
-                output: syn!(FunctionRetTy) >>
-                (TyBareFn {
-                    ty: Box::new(BareFnTy {
-                        unsafety: unsafety,
-                        abi: abi,
-                        lifetimes: lifetimes,
-                        output: output,
-                        variadic: (parens.0).1,
-                        fn_token: fn_,
-                        paren_token: parens.1,
-                        inputs: (parens.0).0,
-                    }),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            lifetimes: option!(syn!(BoundLifetimes)) >>
+            unsafety: syn!(Unsafety) >>
+            abi: option!(syn!(Abi)) >>
+            fn_: syn!(Fn_) >>
+            parens: parens!(do_parse!(
+                inputs: call!(Delimited::parse_terminated) >>
+                variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
+                                                syn!(Dot3))) >>
+                (inputs, variadic)
+            )) >>
+            output: syn!(FunctionRetTy) >>
+            (TyBareFn {
+                ty: Box::new(BareFnTy {
+                    unsafety: unsafety,
+                    abi: abi,
+                    lifetimes: lifetimes,
+                    output: output,
+                    variadic: (parens.0).1,
+                    fn_token: fn_,
+                    paren_token: parens.1,
+                    inputs: (parens.0).0,
+                }),
+            })
+        ));
     }
 
     impl Synom for TyNever {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            map! {
-                input,
-                syn!(Bang),
-                |b| TyNever { bang_token: b }
-            }
-        }
+        named!(parse -> Self, map!(
+            syn!(Bang),
+            |b| TyNever { bang_token: b }
+        ));
     }
 
     impl Synom for TyTup {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                data: parens!(call!(Delimited::parse_terminated)) >>
-                (TyTup {
-                    tys: data.0,
-                    paren_token: data.1,
-                    lone_comma: None, // TODO: does this just not parse?
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            data: parens!(call!(Delimited::parse_terminated)) >>
+            (TyTup {
+                tys: data.0,
+                paren_token: data.1,
+                lone_comma: None, // TODO: does this just not parse?
+            })
+        ));
     }
 
     named!(ty_path -> Ty, do_parse!(
@@ -592,33 +556,27 @@
     ));
 
     impl Synom for ParenthesizedParameterData {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                data: parens!(call!(Delimited::parse_terminated)) >>
-                output: syn!(FunctionRetTy) >>
-                (ParenthesizedParameterData {
-                    paren_token: data.1,
-                    inputs: data.0,
-                    output: output,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            data: parens!(call!(Delimited::parse_terminated)) >>
+            output: syn!(FunctionRetTy) >>
+            (ParenthesizedParameterData {
+                paren_token: data.1,
+                inputs: data.0,
+                output: output,
+            })
+        ));
     }
 
     impl Synom for FunctionRetTy {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    arrow: syn!(RArrow) >>
-                    ty: syn!(Ty) >>
-                    (FunctionRetTy::Ty(ty, arrow))
-                )
-                |
-                epsilon!() => { |_| FunctionRetTy::Default }
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                arrow: syn!(RArrow) >>
+                ty: syn!(Ty) >>
+                (FunctionRetTy::Ty(ty, arrow))
+            )
+            |
+            epsilon!() => { |_| FunctionRetTy::Default }
+        ));
     }
 
     named!(ty_poly_trait_ref -> Ty, map!(
@@ -627,113 +585,95 @@
     ));
 
     impl Synom for TyImplTrait {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                impl_: syn!(Impl) >>
-                elem: call!(Delimited::parse_separated_nonempty) >>
-                (TyImplTrait {
-                    impl_token: impl_,
-                    bounds: elem,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            impl_: syn!(Impl) >>
+            elem: call!(Delimited::parse_separated_nonempty) >>
+            (TyImplTrait {
+                impl_token: impl_,
+                bounds: elem,
+            })
+        ));
     }
 
     impl Synom for TyParen {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                data: parens!(syn!(Ty)) >>
-                (TyParen {
-                    paren_token: data.1,
-                    ty: Box::new(data.0),
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            data: parens!(syn!(Ty)) >>
+            (TyParen {
+                paren_token: data.1,
+                ty: Box::new(data.0),
+            })
+        ));
     }
 
     impl Synom for Mutability {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Mut) => { Mutability::Mutable }
-                |
-                epsilon!() => { |_| Mutability::Immutable }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Mut) => { Mutability::Mutable }
+            |
+            epsilon!() => { |_| Mutability::Immutable }
+        ));
     }
 
     impl Synom for Path {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                global: option!(syn!(Colon2)) >>
-                segments: call!(Delimited::parse_separated_nonempty) >>
-                (Path {
-                    global: global.is_some(),
-                    segments: segments,
-                    leading_colon: global,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            global: option!(syn!(Colon2)) >>
+            segments: call!(Delimited::parse_separated_nonempty) >>
+            (Path {
+                global: global.is_some(),
+                segments: segments,
+                leading_colon: global,
+            })
+        ));
     }
 
     impl Synom for PathSegment {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                do_parse!(
-                    id: option!(syn!(Ident)) >>
-                    lt: syn!(Lt) >>
-                    lifetimes: call!(Delimited::parse_terminated) >>
-                    types: cond!(
-                        lifetimes.is_empty() || lifetimes.trailing_delim(),
-                        call!(Delimited::parse_terminated_with,
-                              ty_no_eq_after)
-                    ) >>
-                    bindings: cond!(
-                        match types {
-                            Some(ref t) => t.is_empty() || t.trailing_delim(),
-                            None => lifetimes.is_empty() || lifetimes.trailing_delim(),
-                        },
-                        call!(Delimited::parse_terminated)
-                    ) >>
-                    gt: syn!(Gt) >>
-                    (PathSegment {
-                        ident: id.unwrap_or_else(|| "".into()),
-                        parameters: PathParameters::AngleBracketed(
-                            AngleBracketedParameterData {
-                                gt_token: Some(gt),
-                                lt_token: Some(lt),
-                                lifetimes: lifetimes,
-                                types: types.unwrap_or_default(),
-                                bindings: bindings.unwrap_or_default(),
-                            }
-                        ),
-                    })
-                )
-                |
-                mod_style_path_segment
-            }
-        }
+        named!(parse -> Self, alt!(
+            do_parse!(
+                id: option!(syn!(Ident)) >>
+                lt: syn!(Lt) >>
+                lifetimes: call!(Delimited::parse_terminated) >>
+                types: cond!(
+                    lifetimes.is_empty() || lifetimes.trailing_delim(),
+                    call!(Delimited::parse_terminated_with,
+                            ty_no_eq_after)
+                ) >>
+                bindings: cond!(
+                    match types {
+                        Some(ref t) => t.is_empty() || t.trailing_delim(),
+                        None => lifetimes.is_empty() || lifetimes.trailing_delim(),
+                    },
+                    call!(Delimited::parse_terminated)
+                ) >>
+                gt: syn!(Gt) >>
+                (PathSegment {
+                    ident: id.unwrap_or_else(|| "".into()),
+                    parameters: PathParameters::AngleBracketed(
+                        AngleBracketedParameterData {
+                            gt_token: Some(gt),
+                            lt_token: Some(lt),
+                            lifetimes: lifetimes,
+                            types: types.unwrap_or_default(),
+                            bindings: bindings.unwrap_or_default(),
+                        }
+                    ),
+                })
+            )
+            |
+            mod_style_path_segment
+        ));
     }
     named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
 
     impl Path {
-        pub fn parse_mod_style(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                global: option!(syn!(Colon2)) >>
-                segments: call!(Delimited::parse_separated_nonempty_with,
-                                mod_style_path_segment) >>
-                (Path {
-                    global: global.is_some(),
-                    segments: segments,
-                    leading_colon: global,
-                })
-            }
-        }
+        named!(pub parse_mod_style -> Self, do_parse!(
+            global: option!(syn!(Colon2)) >>
+            segments: call!(Delimited::parse_separated_nonempty_with,
+                            mod_style_path_segment) >>
+            (Path {
+                global: global.is_some(),
+                segments: segments,
+                leading_colon: global,
+            })
+        ));
     }
 
     named!(mod_style_path_segment -> PathSegment, alt!(
@@ -749,93 +689,78 @@
     ));
 
     impl Synom for TypeBinding {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                id: syn!(Ident) >>
-                eq: syn!(Eq) >>
-                ty: syn!(Ty) >>
-                (TypeBinding {
-                    ident: id,
-                    eq_token: eq,
-                    ty: ty,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            id: syn!(Ident) >>
+            eq: syn!(Eq) >>
+            ty: syn!(Ty) >>
+            (TypeBinding {
+                ident: id,
+                eq_token: eq,
+                ty: ty,
+            })
+        ));
     }
 
     impl Synom for PolyTraitRef {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                bound_lifetimes: option!(syn!(BoundLifetimes)) >>
-                trait_ref: syn!(Path) >>
-                parenthesized: option!(cond_reduce!(
-                    trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
-                    syn!(ParenthesizedParameterData)
-                )) >>
-                ({
-                    let mut trait_ref = trait_ref;
-                    if let Some(parenthesized) = parenthesized {
-                        let parenthesized = PathParameters::Parenthesized(parenthesized);
-                        let len = trait_ref.segments.len();
-                        trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
-                    }
-                    PolyTraitRef {
-                        bound_lifetimes: bound_lifetimes,
-                        trait_ref: trait_ref,
-                    }
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            bound_lifetimes: option!(syn!(BoundLifetimes)) >>
+            trait_ref: syn!(Path) >>
+            parenthesized: option!(cond_reduce!(
+                trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
+                syn!(ParenthesizedParameterData)
+            )) >>
+            ({
+                let mut trait_ref = trait_ref;
+                if let Some(parenthesized) = parenthesized {
+                    let parenthesized = PathParameters::Parenthesized(parenthesized);
+                    let len = trait_ref.segments.len();
+                    trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
+                }
+                PolyTraitRef {
+                    bound_lifetimes: bound_lifetimes,
+                    trait_ref: trait_ref,
+                }
+            })
+        ));
     }
 
     impl Synom for BareFnArg {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                name: option!(do_parse!(
-                    name: syn!(Ident) >>
-                    not!(syn!(Colon2)) >>
-                    colon: syn!(Colon) >>
-                    (name, colon)
-                )) >>
-                ty: syn!(Ty) >>
-                (BareFnArg {
-                    name: name,
-                    ty: ty,
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            name: option!(do_parse!(
+            name: syn!(Ident) >>
+                not!(syn!(Colon2)) >>
+                colon: syn!(Colon) >>
+                (name, colon)
+            )) >>
+            ty: syn!(Ty) >>
+            (BareFnArg {
+                name: name,
+                ty: ty,
+            })
+        ));
     }
 
     impl Synom for Unsafety {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            alt! {
-                input,
-                syn!(Unsafe) => { Unsafety::Unsafe }
-                |
-                epsilon!() => { |_| Unsafety::Normal }
-            }
-        }
+        named!(parse -> Self, alt!(
+            syn!(Unsafe) => { Unsafety::Unsafe }
+            |
+            epsilon!() => { |_| Unsafety::Normal }
+        ));
     }
 
     impl Synom for Abi {
-        fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
-            do_parse! {
-                input,
-                extern_: syn!(Extern) >>
-                // TODO: this parses all literals, not just strings
-                name: option!(syn!(Lit)) >>
-                (Abi {
-                    extern_token: extern_,
-                    kind: match name {
-                        Some(name) => AbiKind::Named(name),
-                        None => AbiKind::Default,
-                    },
-                })
-            }
-        }
+        named!(parse -> Self, do_parse!(
+            extern_: syn!(Extern) >>
+            // TODO: this parses all literals, not just strings
+            name: option!(syn!(Lit)) >>
+            (Abi {
+                extern_token: extern_,
+                kind: match name {
+                    Some(name) => AbiKind::Named(name),
+                    None => AbiKind::Default,
+                },
+            })
+        ));
     }
 }