Rewrite tokenization with `proc-macro2` tokens

This ended up being a bit larger of a commit than I intended! I imagine that
this'll be one of the larger of the commits working towards #142. The purpose of
this commit is to use an updated version of the `quote` crate which doesn't work
with strings but rather works with tokens form the `proc-macro2` crate. The
`proc-macro2` crate itself is based on the proposed API for `proc_macro` itself,
and will continue to mirror it. The hope is that we'll flip an easy switch
eventually to use compiler tokens, whereas for now we'll stick to string parsing
at the lowest layer.

The largest change here is the addition of span information to the AST. Building
on the previous PRs to refactor the AST this makes it relatively easy from a
user perspective to digest and use the AST still, it's just a few extra fields
on the side. The fallout from this was then quite large throughout the
`printing` feature of the crate. The `parsing`, `fold`, and `visit` features
then followed suit to get updated as well.

This commit also changes the the semantics of the AST somewhat as well.
Previously it was inferred what tokens should be printed, for example if you
have a closure argument `syn` would automatically not print the colon in `a: b`
if the type listed was "infer this type". Now the colon is a separate field and
must be in sync with the type listed as the colon/type will be printed
unconditionally (emitting no output if both are `None`).
diff --git a/tests/test_expr.rs b/tests/test_expr.rs
index 1fe0180..6216191 100644
--- a/tests/test_expr.rs
+++ b/tests/test_expr.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "extra-traits")]
+
 extern crate syn;
 use syn::*;
 
@@ -98,7 +100,7 @@
         });
 
         assert_let!(Stmt::Local(ref local) = block.stmts[2]; {
-            assert_let!(Pat::Ident(BindingMode::ByValue(Mutability::Mutable), ref ident, None) = *local.pat; {
+            assert_let!(Pat::Ident(PatIdent { mode: BindingMode::ByValue(Mutability::Mutable(_)), ref ident, .. }) = *local.pat; {
                 assert_eq!(ident, "catch");
             });
         });
@@ -111,8 +113,8 @@
             });
         });
 
-        assert_let!(Stmt::Semi(ref expr) = block.stmts[5]; {
-            assert_let!(Expr { node: ExprKind::Assign(ExprAssign { ref left, ref right }), .. } = **expr; {
+        assert_let!(Stmt::Semi(ref expr, _) = block.stmts[5]; {
+            assert_let!(Expr { node: ExprKind::Assign(ExprAssign { ref left, ref right, .. }), .. } = **expr; {
                 assert_let!(Expr { node: ExprKind::Path(ExprPath { qself: None, ref path }), .. } = **left; {
                     assert_eq!(*path, "catch".into());
                 });
@@ -125,7 +127,7 @@
             });
         });
 
-        assert_let!(Stmt::Semi(ref expr) = block.stmts[7]; {
+        assert_let!(Stmt::Semi(ref expr, _) = block.stmts[7]; {
             assert_let!(Expr { node: ExprKind::Match(ExprMatch { ref expr, .. }), .. } = **expr; {
                 assert_let!(Expr { node: ExprKind::Path(ExprPath { qself: None, ref path }), .. } = **expr; {
                     assert_eq!(*path, "catch".into());
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index 92ae9e9..e18d2ef 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -9,47 +9,68 @@
 #[test]
 fn test_split_for_impl() {
     // <'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug
-    let generics = Generics {
-        lifetimes: vec![LifetimeDef {
-                            attrs: Vec::new(),
-                            lifetime: Lifetime::new("'a"),
-                            bounds: Vec::new(),
-                        },
-                        LifetimeDef {
-                            attrs: Vec::new(),
-                            lifetime: Lifetime::new("'b"),
-                            bounds: vec![Lifetime::new("'a")],
-                        }],
-        ty_params: vec![TyParam {
-                            attrs: vec![Attribute {
-                                            style: AttrStyle::Outer,
-                                            path: "may_dangle".into(),
-                                            tts: vec![],
-                                            is_sugared_doc: false,
-                                        }],
-                            ident: Ident::new("T"),
-                            bounds: vec![TyParamBound::Region(Lifetime::new("'a"))],
-                            default: Some(TyTup { tys: Vec::new() }.into()),
-                        }],
+    let mut generics = Generics {
+        gt_token: Some(Default::default()),
+        lt_token: Some(Default::default()),
+        lifetimes: vec![
+            LifetimeDef {
+                attrs: Default::default(),
+                lifetime: Lifetime::new("'a"),
+                bounds: Default::default(),
+                colon_token: None,
+            },
+            LifetimeDef {
+                attrs: Default::default(),
+                lifetime: Lifetime::new("'b"),
+                bounds: vec![Lifetime::new("'a")].into(),
+                colon_token: Some(tokens::Colon::default()),
+            },
+        ].into(),
+        ty_params: vec![
+            TyParam {
+                attrs: vec![Attribute {
+                    bracket_token: Default::default(),
+                    pound_token: Default::default(),
+                    style: AttrStyle::Outer,
+                    path: "may_dangle".into(),
+                    tts: vec![],
+                    is_sugared_doc: false,
+                }],
+                ident: "T".into(),
+                bounds: vec![TyParamBound::Region(Lifetime::new("'a"))].into(),
+                default: Some(TyTup {
+                    tys: Default::default(),
+                    lone_comma: None,
+                    paren_token: Default::default(),
+                }.into()),
+                colon_token: Some(Default::default()),
+                eq_token: Default::default(),
+            },
+        ].into(),
         where_clause: WhereClause {
-            predicates: vec![WherePredicate::BoundPredicate(WhereBoundPredicate {
-                                                                bound_lifetimes: Vec::new(),
-                                                                bounded_ty: TyPath {
-                                                                    qself: None,
-                                                                    path: "T".into(),
-                                                                }.into(),
-                                                                bounds: vec![
+            where_token: Some(Default::default()),
+            predicates: vec![
+                WherePredicate::BoundPredicate(WhereBoundPredicate {
+                    bound_lifetimes: None,
+                    colon_token: Default::default(),
+                    bounded_ty: TyPath {
+                        qself: None,
+                        path: "T".into(),
+                    }.into(),
+                    bounds: vec![
                         TyParamBound::Trait(
                             PolyTraitRef {
-                                bound_lifetimes: Vec::new(),
+                                bound_lifetimes: None,
                                 trait_ref: "Debug".into(),
                             },
                             TraitBoundModifier::None,
                         ),
-                    ],
-                                                            })],
+                    ].into(),
+                })
+            ].into(),
         },
     };
+    generics.lifetimes.push_trailing(Default::default());
 
     let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
     let tokens = quote! {
@@ -72,21 +93,23 @@
 fn test_ty_param_bound() {
     let tokens = quote!('a);
     let expected = TyParamBound::Region(Lifetime::new("'a"));
-    assert_eq!(expected, parse_ty_param_bound(tokens.as_str()).unwrap());
+    assert_eq!(expected, parse_ty_param_bound(&tokens.to_string()).unwrap());
 
     let tokens = quote!(Debug);
-    let expected = TyParamBound::Trait(PolyTraitRef {
-                                           bound_lifetimes: Vec::new(),
-                                           trait_ref: "Debug".into(),
-                                       },
-                                       TraitBoundModifier::None);
-    assert_eq!(expected, parse_ty_param_bound(tokens.as_str()).unwrap());
+    let expected = TyParamBound::Trait(
+        PolyTraitRef {
+            bound_lifetimes: None,
+            trait_ref: "Debug".into(),
+        },
+        TraitBoundModifier::None);
+    assert_eq!(expected, parse_ty_param_bound(&tokens.to_string()).unwrap());
 
     let tokens = quote!(?Sized);
-    let expected = TyParamBound::Trait(PolyTraitRef {
-                                           bound_lifetimes: Vec::new(),
-                                           trait_ref: "Sized".into(),
-                                       },
-                                       TraitBoundModifier::Maybe);
-    assert_eq!(expected, parse_ty_param_bound(tokens.as_str()).unwrap());
+    let expected = TyParamBound::Trait(
+        PolyTraitRef {
+            bound_lifetimes: None,
+            trait_ref: "Sized".into(),
+        },
+        TraitBoundModifier::Maybe(Default::default()));
+    assert_eq!(expected, parse_ty_param_bound(&tokens.to_string()).unwrap());
 }
diff --git a/tests/test_macro_input.rs b/tests/test_macro_input.rs
index 653fbe2..4237060 100644
--- a/tests/test_macro_input.rs
+++ b/tests/test_macro_input.rs
@@ -5,7 +5,39 @@
 #![cfg(feature = "extra-traits")]
 
 extern crate syn;
+extern crate proc_macro2;
+
 use syn::*;
+use proc_macro2::{TokenKind, OpKind, Delimiter, Literal};
+use proc_macro2::Delimiter::{Parenthesis, Brace};
+
+fn op(c: char) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Op(c, OpKind::Alone),
+    })
+}
+
+fn lit<T: Into<Literal>>(t: T) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Literal(t.into()),
+    })
+}
+
+fn word(sym: &str) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Word(sym.into()),
+    })
+}
+
+fn delimited(delim: Delimiter, tokens: Vec<TokenTree>) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Sequence(delim, tokens.into_iter().map(|t| t.0).collect()),
+    })
+}
 
 #[test]
 fn test_unit() {
@@ -13,10 +45,14 @@
 
     let expected = MacroInput {
         ident: "Unit".into(),
-        vis: Visibility::Inherited,
+        vis: Visibility::Inherited(VisInherited {}),
         attrs: Vec::new(),
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+            data: VariantData::Unit,
+        }),
     };
 
     assert_eq!(expected, parse_macro_input(raw).unwrap());
@@ -28,63 +64,80 @@
         #[derive(Debug, Clone)]
         pub struct Item {
             pub ident: Ident,
-            pub attrs: Vec<Attribute>,
+            pub attrs: Vec<Attribute>
         }
     ";
 
     let expected = MacroInput {
         ident: "Item".into(),
-        vis: Visibility::Public,
+        vis: Visibility::Public(VisPublic {
+            pub_token: Default::default(),
+        }),
         attrs: vec![Attribute {
+            bracket_token: Default::default(),
+            pound_token: Default::default(),
             style: AttrStyle::Outer,
             path: "derive".into(),
             tts: vec![
-                TokenTree::Delimited(Delimited { delim: DelimToken::Paren, tts: vec![
-                    TokenTree::Token(Token::Ident("Debug".into())),
-                    TokenTree::Token(Token::Comma),
-                    TokenTree::Token(Token::Ident("Clone".into())),
-                ]})
+                delimited(Parenthesis, vec![
+                    word("Debug"),
+                    op(','),
+                    word("Clone"),
+                ]),
             ],
             is_sugared_doc: false,
         }],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Struct(vec![
-            Field {
-                ident: Some("ident".into()),
-                vis: Visibility::Public,
-                attrs: Vec::new(),
-                ty: TyPath {
-                    qself: None,
-                    path: "Ident".into(),
-                }.into(),
-            },
-            Field {
-                ident: Some("attrs".into()),
-                vis: Visibility::Public,
-                attrs: Vec::new(),
-                ty: TyPath {
-                    qself: None,
-                    path: Path {
-                        global: false,
-                        segments: vec![
-                            PathSegment {
-                                ident: "Vec".into(),
-                                parameters: PathParameters::AngleBracketed(
-                                    AngleBracketedParameterData {
-                                        lifetimes: Vec::new(),
-                                        types: vec![TyPath {
-                                            qself: None,
-                                            path: "Attribute".into(),
-                                        }.into()],
-                                        bindings: Vec::new(),
-                                    },
-                                ),
-                            }
-                        ],
-                    },
-                }.into(),
-            },
-        ]))
+        body: Body::Struct(BodyStruct {
+            semi_token: None,
+            struct_token: Default::default(),
+            data: VariantData::Struct(vec![
+                Field {
+                    ident: Some("ident".into()),
+                    colon_token: Some(Default::default()),
+                    vis: Visibility::Public(VisPublic {
+                        pub_token: Default::default(),
+                    }),
+                    attrs: Vec::new(),
+                    ty: TyPath {
+                        qself: None,
+                        path: "Ident".into(),
+                    }.into(),
+                },
+                Field {
+                    ident: Some("attrs".into()),
+                    colon_token: Some(Default::default()),
+                    vis: Visibility::Public(VisPublic {
+                        pub_token: Default::default(),
+                    }),
+                    attrs: Vec::new(),
+                    ty: TyPath {
+                        qself: None,
+                        path: Path {
+                            leading_colon: None,
+                            global: false,
+                            segments: vec![
+                                PathSegment {
+                                    ident: "Vec".into(),
+                                    parameters: PathParameters::AngleBracketed(
+                                        AngleBracketedParameterData {
+                                            gt_token: Some(Default::default()),
+                                            lt_token: Some(Default::default()),
+                                            lifetimes: Default::default(),
+                                            types: vec![Ty::from(TyPath {
+                                                qself: None,
+                                                path: "Attribute".into(),
+                                            })].into(),
+                                            bindings: Default::default(),
+                                        },
+                                    ),
+                                }
+                            ].into(),
+                        },
+                    }.into(),
+                },
+            ].into(), Default::default()),
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -93,10 +146,11 @@
 
     let expected_meta_item: MetaItem = MetaItemList {
         ident: "derive".into(),
+        paren_token: Default::default(),
         nested: vec![
             NestedMetaItem::MetaItem(MetaItem::Word("Debug".into())),
             NestedMetaItem::MetaItem(MetaItem::Word("Clone".into())),
-        ],
+        ].into(),
     }.into();
 
     assert_eq!(expected_meta_item, actual.attrs[0].meta_item().unwrap());
@@ -115,27 +169,30 @@
 
             // Smuggling data into a proc_macro_derive,
             // in the style of https://github.com/dtolnay/proc-macro-hack
-            ProcMacroHack = (0, "data").0,
+            ProcMacroHack = (0, "data").0
         }
     "#;
 
     let expected = MacroInput {
         ident: "Result".into(),
-        vis: Visibility::Public,
+        vis: Visibility::Public(VisPublic {
+            pub_token: Default::default(),
+        }),
         attrs: vec![
             Attribute {
+                bracket_token: Default::default(),
+                pound_token: Default::default(),
                 style: AttrStyle::Outer,
                 path: "doc".into(),
                 tts: vec![
-                    TokenTree::Token(Token::Eq),
-                    TokenTree::Token(Token::Literal(Lit::Str(
-                        "/// See the std::result module documentation for details.".into(),
-                        StrStyle::Cooked,
-                    ))),
+                    op('='),
+                    lit(Literal::doccomment("/// See the std::result module documentation for details.")),
                 ],
                 is_sugared_doc: true,
             },
             Attribute {
+                bracket_token: Default::default(),
+                pound_token: Default::default(),
                 style: AttrStyle::Outer,
                 path: "must_use".into(),
                 tts: vec![],
@@ -143,81 +200,114 @@
             },
         ],
         generics: Generics {
-            lifetimes: Vec::new(),
-            ty_params: vec![TyParam {
-                                attrs: Vec::new(),
-                                ident: "T".into(),
-                                bounds: Vec::new(),
-                                default: None,
-                            },
-                            TyParam {
-                                attrs: Vec::new(),
-                                ident: "E".into(),
-                                bounds: Vec::new(),
-                                default: None,
-                            }],
-            where_clause: WhereClause { predicates: Vec::new() },
-        },
-        body: Body::Enum(vec![
-            Variant {
-                ident: "Ok".into(),
-                attrs: Vec::new(),
-                data: VariantData::Tuple(vec![
-                    Field {
-                        ident: None,
-                        vis: Visibility::Inherited,
-                        attrs: Vec::new(),
-                        ty: TyPath { qself: None, path: "T".into() }.into(),
-                    },
-                ]),
-                discriminant: None,
-            },
-            Variant {
-                ident: "Err".into(),
-                attrs: Vec::new(),
-                data: VariantData::Tuple(vec![
-                    Field {
-                        ident: None,
-                        vis: Visibility::Inherited,
-                        attrs: Vec::new(),
-                        ty: TyPath { qself: None, path: "E".into() }.into(),
-                    },
-                ]),
-                discriminant: None,
-            },
-            Variant {
-                ident: "Surprise".into(),
-                attrs: Vec::new(),
-                data: VariantData::Unit,
-                discriminant: Some(ConstExpr::Lit(Lit::Int(0, IntTy::Isize))),
-            },
-            Variant {
-                ident: "ProcMacroHack".into(),
-                attrs: Vec::new(),
-                data: VariantData::Unit,
-                discriminant: Some(ConstExpr::Other(Expr {
-                    node: ExprTupField {
-                        expr: Box::new(Expr {
-                            node: ExprTup {
-                                args: vec![
-                                    Expr {
-                                        node: ExprKind::Lit(Lit::Int(0, IntTy::Unsuffixed)),
-                                        attrs: Vec::new(),
-                                    },
-                                    Expr {
-                                        node: ExprKind::Lit(Lit::Str("data".into(), StrStyle::Cooked)),
-                                        attrs: Vec::new(),
-                                    },
-                                ],
-                            }.into(),
-                            attrs: Vec::new(),
-                        }),
-                        field: 0
-                    }.into(),
+            lifetimes: Default::default(),
+            lt_token: Some(Default::default()),
+            gt_token: Some(Default::default()),
+            ty_params: vec![
+                TyParam {
                     attrs: Vec::new(),
-                })),
-            },
-        ]),
+                    ident: "T".into(),
+                    bounds: Default::default(),
+                    default: None,
+                    colon_token: None,
+                    eq_token: None,
+                },
+                TyParam {
+                    attrs: Vec::new(),
+                    ident: "E".into(),
+                    bounds: Default::default(),
+                    colon_token: None,
+                    eq_token: None,
+                    default: None,
+                },
+            ].into(),
+            where_clause: WhereClause::default(),
+        },
+        body: Body::Enum(BodyEnum {
+            variants: vec![
+                Variant {
+                    ident: "Ok".into(),
+                    attrs: Vec::new(),
+                    eq_token: None,
+                    data: VariantData::Tuple(vec![
+                        Field {
+                            colon_token: None,
+                            ident: None,
+                            vis: Visibility::Inherited(VisInherited {}),
+                            attrs: Vec::new(),
+                            ty: TyPath { qself: None, path: "T".into() }.into(),
+                        },
+                    ].into(), Default::default()),
+                    discriminant: None,
+                },
+                Variant {
+                    ident: "Err".into(),
+                    attrs: Vec::new(),
+                    eq_token: None,
+                    data: VariantData::Tuple(vec![
+                        Field {
+                            ident: None,
+                            colon_token: None,
+                            vis: Visibility::Inherited(VisInherited {}),
+                            attrs: Vec::new(),
+                            ty: TyPath { qself: None, path: "E".into() }.into(),
+                        },
+                    ].into(), Default::default()),
+                    discriminant: None,
+                },
+                Variant {
+                    ident: "Surprise".into(),
+                    attrs: Vec::new(),
+                    data: VariantData::Unit,
+                    eq_token: Some(Default::default()),
+                    discriminant: Some(ConstExpr::Lit(Lit {
+                        value: LitKind::Other(0isize.into()),
+                        span: Default::default(),
+                    })),
+                },
+                Variant {
+                    ident: "ProcMacroHack".into(),
+                    attrs: Vec::new(),
+                    data: VariantData::Unit,
+                    eq_token: Some(Default::default()),
+                    discriminant: Some(ConstExpr::Other(Expr {
+                        node: ExprTupField {
+                            expr: Box::new(Expr {
+                                node: ExprTup {
+                                    lone_comma: None,
+                                    paren_token: Default::default(),
+                                    args: vec![
+                                        Expr {
+                                            node: ExprKind::Lit(Lit {
+                                                value: LitKind::Other(Literal::integer("0")),
+                                                span: Default::default(),
+                                            }),
+                                            attrs: Vec::new(),
+                                        },
+                                        Expr {
+                                            node: ExprKind::Lit(Lit {
+                                                value: LitKind::Other("data".into()),
+                                                span: Default::default(),
+                                            }),
+                                            attrs: Vec::new(),
+                                        },
+                                    ].into(),
+                                }.into(),
+                                attrs: Vec::new(),
+                            }),
+                            dot_token: Default::default(),
+                            field: Lit {
+                                value: LitKind::Other(Literal::integer("0")),
+                                span: Default::default(),
+                            },
+                        }.into(),
+                        attrs: Vec::new(),
+                    })),
+                },
+            ].into(),
+            brace_token: Default::default(),
+            enum_token: Default::default(),
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -227,10 +317,11 @@
     let expected_meta_items = vec![
         MetaNameValue {
             ident: "doc".into(),
-            lit: Lit::Str(
-                "/// See the std::result module documentation for details.".into(),
-                StrStyle::Cooked,
-            ),
+            eq_token: Default::default(),
+            lit: Lit {
+                value: LitKind::Other(Literal::doccomment("/// See the std::result module documentation for details.")),
+                span: Default::default(),
+            },
         }.into(),
         MetaItem::Word("must_use".into()),
     ];
@@ -250,30 +341,43 @@
 
     let expected = MacroInput {
         ident: "Dummy".into(),
-        vis: Visibility::Inherited,
+        vis: Visibility::Inherited(VisInherited {}),
         attrs: vec![Attribute {
+            bracket_token: Default::default(),
+            pound_token: Default::default(),
             style: AttrStyle::Outer,
-            path: Path { global: true, segments: vec!["attr_args".into(), "identity".into()] },
+            path: Path {
+                global: true,
+                leading_colon: Some(Default::default()),
+                segments: vec![
+                    PathSegment::from("attr_args"),
+                    PathSegment::from("identity"),
+                ].into(),
+            },
             tts: vec![
-                TokenTree::Token(Token::Ident("fn".into())),
-                TokenTree::Token(Token::Ident("main".into())),
-                TokenTree::Delimited(Delimited { delim: DelimToken::Paren, tts: vec![] }),
-                TokenTree::Delimited(Delimited { delim: DelimToken::Brace, tts: vec![
-                    TokenTree::Token(Token::Ident("assert_eq".into())),
-                    TokenTree::Token(Token::Not),
-                    TokenTree::Delimited(Delimited { delim: DelimToken::Paren, tts: vec![
-                        TokenTree::Token(Token::Ident("foo".into())),
-                        TokenTree::Delimited(Delimited { delim: DelimToken::Paren, tts: vec![] }),
-                        TokenTree::Token(Token::Comma),
-                        TokenTree::Token(Token::Literal(Lit::Str("Hello, world!".into(), StrStyle::Cooked))),
-                    ]}),
-                    TokenTree::Token(Token::Semi),
-                ]})
+                word("fn"),
+                word("main"),
+                delimited(Parenthesis, vec![]),
+                delimited(Brace, vec![
+                    word("assert_eq"),
+                    op('!'),
+                    delimited(Parenthesis, vec![
+                        word("foo"),
+                        delimited(Parenthesis, vec![]),
+                        op(','),
+                        lit("Hello, world!"),
+                    ]),
+                    op(';'),
+                ]),
             ],
             is_sugared_doc: false,
         }],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            data: VariantData::Unit,
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -292,19 +396,31 @@
 
     let expected = MacroInput {
         ident: "S".into(),
-        vis: Visibility::Inherited,
+        vis: Visibility::Inherited(VisInherited {}),
         attrs: vec![Attribute {
+            bracket_token: Default::default(),
+            pound_token: Default::default(),
             style: AttrStyle::Outer,
-            path: Path { global: false, segments: vec!["inert".into()] },
+            path: Path {
+                global: false,
+                leading_colon: None,
+                segments: vec![
+                    PathSegment::from("inert"),
+                ].into(),
+            },
             tts: vec![
-                TokenTree::Token(Token::Lt),
-                TokenTree::Token(Token::Ident("T".into())),
-                TokenTree::Token(Token::Gt),
+                op('<'),
+                word("T"),
+                op('>'),
             ],
             is_sugared_doc: false,
         }],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            data: VariantData::Unit,
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -323,15 +439,28 @@
 
     let expected = MacroInput {
         ident: "S".into(),
-        vis: Visibility::Inherited,
+        vis: Visibility::Inherited(VisInherited {}),
         attrs: vec![Attribute {
+            bracket_token: Default::default(),
+            pound_token: Default::default(),
             style: AttrStyle::Outer,
-            path: Path { global: false, segments: vec!["foo".into(), "self".into()] },
+            path: Path {
+                global: false,
+                leading_colon: None,
+                segments: vec![
+                    PathSegment::from("foo"),
+                    PathSegment::from("self"),
+                ].into(),
+            },
             tts: vec![],
             is_sugared_doc: false,
         }],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            data: VariantData::Unit,
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -350,15 +479,40 @@
 
     let expected = MacroInput {
         ident: "Z".into(),
-        vis: Visibility::Restricted(Box::new("m".into())),
+        vis: Visibility::Restricted(VisRestricted {
+            path: Box::new("m".into()),
+            in_token: Some(Default::default()),
+            paren_token: Default::default(),
+            pub_token: Default::default(),
+        }),
         attrs: vec![],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Tuple(vec![Field {
-            ident: None,
-            vis: Visibility::Restricted(Box::new(Path { global: false, segments: vec!["m".into(), "n".into()] })),
-            attrs: vec![],
-            ty: TyPath { qself: None, path: "u8".into() }.into(),
-        }])),
+        body: Body::Struct(BodyStruct {
+            data: VariantData::Tuple(vec![Field {
+                ident: None,
+                vis: Visibility::Restricted(VisRestricted {
+                    path: Box::new(Path {
+                        global: false,
+                        leading_colon: None,
+                        segments: vec![
+                            PathSegment::from("m"),
+                            PathSegment::from("n"),
+                        ].into(),
+                    }),
+                    in_token: Some(Default::default()),
+                    paren_token: Default::default(),
+                    pub_token: Default::default(),
+                }),
+                colon_token: None,
+                attrs: vec![],
+                ty: TyPath {
+                    qself: None,
+                    path: "u8".into(),
+                }.into(),
+            }].into(), Default::default()),
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -374,10 +528,18 @@
 
     let expected = MacroInput {
         ident: "S".into(),
-        vis: Visibility::Crate,
+        vis: Visibility::Crate(VisCrate {
+            pub_token: Default::default(),
+            crate_token: Default::default(),
+            paren_token: Default::default(),
+        }),
         attrs: vec![],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+            data: VariantData::Unit,
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -393,10 +555,19 @@
 
     let expected = MacroInput {
         ident: "S".into(),
-        vis: Visibility::Restricted(Box::new("super".into())),
+        vis: Visibility::Restricted(VisRestricted {
+            path: Box::new("super".into()),
+            in_token: None,
+            paren_token: Default::default(),
+            pub_token: Default::default(),
+        }),
         attrs: vec![],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+            data: VariantData::Unit,
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
@@ -412,10 +583,19 @@
 
     let expected = MacroInput {
         ident: "S".into(),
-        vis: Visibility::Restricted(Box::new("super".into())),
+        vis: Visibility::Restricted(VisRestricted {
+            path: Box::new("super".into()),
+            in_token: Some(Default::default()),
+            paren_token: Default::default(),
+            pub_token: Default::default(),
+        }),
         attrs: vec![],
         generics: Generics::default(),
-        body: Body::Struct(VariantData::Unit),
+        body: Body::Struct(BodyStruct {
+            semi_token: Some(Default::default()),
+            struct_token: Default::default(),
+            data: VariantData::Unit,
+        }),
     };
 
     let actual = parse_macro_input(raw).unwrap();
diff --git a/tests/test_meta_item.rs b/tests/test_meta_item.rs
index 72cec3a..acf1710 100644
--- a/tests/test_meta_item.rs
+++ b/tests/test_meta_item.rs
@@ -1,7 +1,17 @@
 #![cfg(feature = "extra-traits")]
 
 extern crate syn;
+extern crate proc_macro2;
+
 use syn::*;
+use proc_macro2::Literal;
+
+fn lit<T: Into<Literal>>(t: T) -> Lit {
+    Lit {
+        value: LitKind::Other(t.into()),
+        span: Default::default(),
+    }
+}
 
 #[test]
 fn test_meta_item_word() {
@@ -12,7 +22,8 @@
 fn test_meta_item_name_value() {
     run_test("#[foo = 5]", MetaNameValue {
         ident: "foo".into(),
-        lit: Lit::Int(5, IntTy::Unsuffixed),
+        eq_token: Default::default(),
+        lit: lit(Literal::integer("5")),
     })
 }
 
@@ -20,9 +31,10 @@
 fn test_meta_item_list_lit() {
     run_test("#[foo(5)]", MetaItemList {
         ident: "foo".into(),
+        paren_token: Default::default(),
         nested: vec![
-            NestedMetaItem::Literal(Lit::Int(5, IntTy::Unsuffixed)),
-        ],
+            NestedMetaItem::Literal(lit(Literal::integer("5"))),
+        ].into(),
     })
 }
 
@@ -30,9 +42,10 @@
 fn test_meta_item_list_word() {
     run_test("#[foo(bar)]", MetaItemList {
         ident: "foo".into(),
+        paren_token: Default::default(),
         nested: vec![
             NestedMetaItem::MetaItem(MetaItem::Word("bar".into())),
-        ],
+        ].into(),
     })
 }
 
@@ -40,12 +53,14 @@
 fn test_meta_item_list_name_value() {
     run_test("#[foo(bar = 5)]", MetaItemList {
         ident: "foo".into(),
+        paren_token: Default::default(),
         nested: vec![
             NestedMetaItem::MetaItem(MetaNameValue {
                 ident: "bar".into(),
-                lit: Lit::Int(5, IntTy::Unsuffixed),
+                eq_token: Default::default(),
+                lit: lit(Literal::integer("5"))
             }.into()),
-        ],
+        ].into(),
     })
 }
 
@@ -53,23 +68,27 @@
 fn test_meta_item_multiple() {
     run_test("#[foo(word, name = 5, list(name2 = 6), word2)]", MetaItemList {
         ident: "foo".into(),
+        paren_token: Default::default(),
         nested: vec![
             NestedMetaItem::MetaItem(MetaItem::Word("word".into())),
             NestedMetaItem::MetaItem(MetaNameValue {
                 ident: "name".into(),
-                lit: Lit::Int(5, IntTy::Unsuffixed),
+                eq_token: Default::default(),
+                lit: lit(Literal::integer("5")),
             }.into()),
             NestedMetaItem::MetaItem(MetaItemList {
                 ident: "list".into(),
+                paren_token: Default::default(),
                 nested: vec![
                     NestedMetaItem::MetaItem(MetaNameValue {
                         ident: "name2".into(),
-                        lit: Lit::Int(6, IntTy::Unsuffixed),
+                        eq_token: Default::default(),
+                        lit: lit(Literal::integer("6")),
                     }.into())
-                ],
+                ].into(),
             }.into()),
             NestedMetaItem::MetaItem(MetaItem::Word("word2".into())),
-        ],
+        ].into(),
     })
 }
 
diff --git a/tests/test_token_trees.rs b/tests/test_token_trees.rs
index 33dbdda..3616a70 100644
--- a/tests/test_token_trees.rs
+++ b/tests/test_token_trees.rs
@@ -1,9 +1,32 @@
 #![cfg(feature = "extra-traits")]
 
 extern crate syn;
-use syn::TokenTree::{self, Token};
-use syn::DelimToken::*;
-use syn::Token::*;
+extern crate proc_macro2;
+
+use syn::TokenTree;
+use proc_macro2::{TokenKind, OpKind, Delimiter};
+use proc_macro2::Delimiter::*;
+
+fn op(c: char) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Op(c, OpKind::Alone),
+    })
+}
+
+fn delimited(delim: Delimiter, tokens: Vec<TokenTree>) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Sequence(delim, tokens.into_iter().map(|t| t.0).collect()),
+    })
+}
+
+fn word(sym: &str) -> TokenTree {
+    TokenTree(proc_macro2::TokenTree {
+        span: Default::default(),
+        kind: TokenKind::Word(sym.into()),
+    })
+}
 
 #[test]
 fn test_struct() {
@@ -15,43 +38,39 @@
         }
     ";
 
-    let expected =
-        vec![Token(Pound),
-             delimited(Bracket,
-                       vec![ident("derive"),
-                            delimited(Paren, vec![ident("Debug"), Token(Comma), ident("Clone")])]),
-             ident("pub"),
-             ident("struct"),
-             ident("Item"),
-             delimited(Brace,
-                       vec![ident("pub"),
-                            ident("ident"),
-                            Token(Colon),
-                            ident("Ident"),
-                            Token(Comma),
+    let expected = vec![
+        op('#'),
+        delimited(Bracket, vec![
+           word("derive"),
+           delimited(Parenthesis, vec![
+               word("Debug"),
+               op(','),
+               word("Clone"),
+           ]),
+        ]),
+        word("pub"),
+        word("struct"),
+        word("Item"),
+        delimited(Brace, vec![
+           word("pub"),
+           word("ident"),
+           op(':'),
+           word("Ident"),
+           op(','),
 
-                            ident("pub"),
-                            ident("attrs"),
-                            Token(Colon),
-                            ident("Vec"),
-                            Token(Lt),
-                            ident("Attribute"),
-                            Token(Gt),
-                            Token(Comma)])];
+           word("pub"),
+           word("attrs"),
+           op(':'),
+           word("Vec"),
+           op('<'),
+           word("Attribute"),
+           op('>'),
+           op(','),
+        ],
+    )];
 
     let result = syn::parse_token_trees(raw).unwrap();
     if result != expected {
         panic!("{:#?}\n!=\n{:#?}", result, expected);
     }
 }
-
-fn delimited(delim: syn::DelimToken, tts: Vec<TokenTree>) -> TokenTree {
-    TokenTree::Delimited(syn::Delimited {
-                             delim: delim,
-                             tts: tts,
-                         })
-}
-
-fn ident(s: &str) -> TokenTree {
-    TokenTree::Token(Ident(syn::Ident::new(s)))
-}