Represent existential types in syntax tree
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 8bfa9fe..fe1088a 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -403,6 +403,10 @@
         fold_impl_item_const(self, i)
     }
     #[cfg(feature = "full")]
+    fn fold_impl_item_existential(&mut self, i: ImplItemExistential) -> ImplItemExistential {
+        fold_impl_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn fold_impl_item_macro(&mut self, i: ImplItemMacro) -> ImplItemMacro {
         fold_impl_item_macro(self, i)
     }
@@ -435,6 +439,10 @@
         fold_item_enum(self, i)
     }
     #[cfg(feature = "full")]
+    fn fold_item_existential(&mut self, i: ItemExistential) -> ItemExistential {
+        fold_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn fold_item_extern_crate(&mut self, i: ItemExternCrate) -> ItemExternCrate {
         fold_item_extern_crate(self, i)
     }
@@ -720,6 +728,10 @@
         fold_trait_item_const(self, i)
     }
     #[cfg(feature = "full")]
+    fn fold_trait_item_existential(&mut self, i: TraitItemExistential) -> TraitItemExistential {
+        fold_trait_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn fold_trait_item_macro(&mut self, i: TraitItemMacro) -> TraitItemMacro {
         fold_trait_item_macro(self, i)
     }
@@ -1861,6 +1873,9 @@
             ImplItem::Method(_visitor.fold_impl_item_method(_binding_0))
         }
         ImplItem::Type(_binding_0) => ImplItem::Type(_visitor.fold_impl_item_type(_binding_0)),
+        ImplItem::Existential(_binding_0) => {
+            ImplItem::Existential(_visitor.fold_impl_item_existential(_binding_0))
+        }
         ImplItem::Macro(_binding_0) => ImplItem::Macro(_visitor.fold_impl_item_macro(_binding_0)),
         ImplItem::Verbatim(_binding_0) => {
             ImplItem::Verbatim(_visitor.fold_impl_item_verbatim(_binding_0))
@@ -1886,6 +1901,22 @@
     }
 }
 #[cfg(feature = "full")]
+pub fn fold_impl_item_existential<V: Fold + ?Sized>(
+    _visitor: &mut V,
+    _i: ImplItemExistential,
+) -> ImplItemExistential {
+    ImplItemExistential {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        existential_token: Token![existential](tokens_helper(_visitor, &_i.existential_token.span)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+        ident: _visitor.fold_ident(_i.ident),
+        generics: _visitor.fold_generics(_i.generics),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+        bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
 pub fn fold_impl_item_macro<V: Fold + ?Sized>(
     _visitor: &mut V,
     _i: ImplItemMacro,
@@ -1952,6 +1983,9 @@
             Item::ForeignMod(_visitor.fold_item_foreign_mod(_binding_0))
         }
         Item::Type(_binding_0) => Item::Type(_visitor.fold_item_type(_binding_0)),
+        Item::Existential(_binding_0) => {
+            Item::Existential(_visitor.fold_item_existential(_binding_0))
+        }
         Item::Struct(_binding_0) => Item::Struct(_visitor.fold_item_struct(_binding_0)),
         Item::Enum(_binding_0) => Item::Enum(_visitor.fold_item_enum(_binding_0)),
         Item::Union(_binding_0) => Item::Union(_visitor.fold_item_union(_binding_0)),
@@ -1989,6 +2023,23 @@
     }
 }
 #[cfg(feature = "full")]
+pub fn fold_item_existential<V: Fold + ?Sized>(
+    _visitor: &mut V,
+    _i: ItemExistential,
+) -> ItemExistential {
+    ItemExistential {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        vis: _visitor.fold_visibility(_i.vis),
+        existential_token: Token![existential](tokens_helper(_visitor, &_i.existential_token.span)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+        ident: _visitor.fold_ident(_i.ident),
+        generics: _visitor.fold_generics(_i.generics),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+        bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
 pub fn fold_item_extern_crate<V: Fold + ?Sized>(
     _visitor: &mut V,
     _i: ItemExternCrate,
@@ -2621,6 +2672,9 @@
             TraitItem::Method(_visitor.fold_trait_item_method(_binding_0))
         }
         TraitItem::Type(_binding_0) => TraitItem::Type(_visitor.fold_trait_item_type(_binding_0)),
+        TraitItem::Existential(_binding_0) => {
+            TraitItem::Existential(_visitor.fold_trait_item_existential(_binding_0))
+        }
         TraitItem::Macro(_binding_0) => {
             TraitItem::Macro(_visitor.fold_trait_item_macro(_binding_0))
         }
@@ -2650,6 +2704,22 @@
     }
 }
 #[cfg(feature = "full")]
+pub fn fold_trait_item_existential<V: Fold + ?Sized>(
+    _visitor: &mut V,
+    _i: TraitItemExistential,
+) -> TraitItemExistential {
+    TraitItemExistential {
+        attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+        existential_token: Token![existential](tokens_helper(_visitor, &_i.existential_token.span)),
+        type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+        ident: _visitor.fold_ident(_i.ident),
+        generics: _visitor.fold_generics(_i.generics),
+        colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+        bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+        semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+    }
+}
+#[cfg(feature = "full")]
 pub fn fold_trait_item_macro<V: Fold + ?Sized>(
     _visitor: &mut V,
     _i: TraitItemMacro,
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index a21e108..7d15422 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -403,6 +403,10 @@
         visit_impl_item_const(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_impl_item_existential(&mut self, i: &'ast ImplItemExistential) {
+        visit_impl_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_impl_item_macro(&mut self, i: &'ast ImplItemMacro) {
         visit_impl_item_macro(self, i)
     }
@@ -435,6 +439,10 @@
         visit_item_enum(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_item_existential(&mut self, i: &'ast ItemExistential) {
+        visit_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_item_extern_crate(&mut self, i: &'ast ItemExternCrate) {
         visit_item_extern_crate(self, i)
     }
@@ -717,6 +725,10 @@
         visit_trait_item_const(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_trait_item_existential(&mut self, i: &'ast TraitItemExistential) {
+        visit_trait_item_existential(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_trait_item_macro(&mut self, i: &'ast TraitItemMacro) {
         visit_trait_item_macro(self, i)
     }
@@ -2050,6 +2062,9 @@
         ImplItem::Type(ref _binding_0) => {
             _visitor.visit_impl_item_type(_binding_0);
         }
+        ImplItem::Existential(ref _binding_0) => {
+            _visitor.visit_impl_item_existential(_binding_0);
+        }
         ImplItem::Macro(ref _binding_0) => {
             _visitor.visit_impl_item_macro(_binding_0);
         }
@@ -2079,6 +2094,27 @@
     tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
+pub fn visit_impl_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast ImplItemExistential,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    tokens_helper(_visitor, &_i.existential_token.span);
+    tokens_helper(_visitor, &_i.type_token.span);
+    _visitor.visit_ident(&_i.ident);
+    _visitor.visit_generics(&_i.generics);
+    if let Some(ref it) = _i.colon_token {
+        tokens_helper(_visitor, &it.spans)
+    };
+    for el in Punctuated::pairs(&_i.bounds) {
+        let it = el.value();
+        _visitor.visit_type_param_bound(it)
+    }
+    tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_impl_item_macro<'ast, V: Visit<'ast> + ?Sized>(
     _visitor: &mut V,
     _i: &'ast ImplItemMacro,
@@ -2164,6 +2200,9 @@
         Item::Type(ref _binding_0) => {
             _visitor.visit_item_type(_binding_0);
         }
+        Item::Existential(ref _binding_0) => {
+            _visitor.visit_item_existential(_binding_0);
+        }
         Item::Struct(ref _binding_0) => {
             _visitor.visit_item_struct(_binding_0);
         }
@@ -2220,6 +2259,28 @@
     }
 }
 #[cfg(feature = "full")]
+pub fn visit_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast ItemExistential,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    _visitor.visit_visibility(&_i.vis);
+    tokens_helper(_visitor, &_i.existential_token.span);
+    tokens_helper(_visitor, &_i.type_token.span);
+    _visitor.visit_ident(&_i.ident);
+    _visitor.visit_generics(&_i.generics);
+    if let Some(ref it) = _i.colon_token {
+        tokens_helper(_visitor, &it.spans)
+    };
+    for el in Punctuated::pairs(&_i.bounds) {
+        let it = el.value();
+        _visitor.visit_type_param_bound(it)
+    }
+    tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_item_extern_crate<'ast, V: Visit<'ast> + ?Sized>(
     _visitor: &mut V,
     _i: &'ast ItemExternCrate,
@@ -2999,6 +3060,9 @@
         TraitItem::Type(ref _binding_0) => {
             _visitor.visit_trait_item_type(_binding_0);
         }
+        TraitItem::Existential(ref _binding_0) => {
+            _visitor.visit_trait_item_existential(_binding_0);
+        }
         TraitItem::Macro(ref _binding_0) => {
             _visitor.visit_trait_item_macro(_binding_0);
         }
@@ -3026,6 +3090,27 @@
     tokens_helper(_visitor, &_i.semi_token.spans);
 }
 #[cfg(feature = "full")]
+pub fn visit_trait_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+    _visitor: &mut V,
+    _i: &'ast TraitItemExistential,
+) {
+    for it in &_i.attrs {
+        _visitor.visit_attribute(it)
+    }
+    tokens_helper(_visitor, &_i.existential_token.span);
+    tokens_helper(_visitor, &_i.type_token.span);
+    _visitor.visit_ident(&_i.ident);
+    _visitor.visit_generics(&_i.generics);
+    if let Some(ref it) = _i.colon_token {
+        tokens_helper(_visitor, &it.spans)
+    };
+    for el in Punctuated::pairs(&_i.bounds) {
+        let it = el.value();
+        _visitor.visit_type_param_bound(it)
+    }
+    tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_trait_item_macro<'ast, V: Visit<'ast> + ?Sized>(
     _visitor: &mut V,
     _i: &'ast TraitItemMacro,
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index f1b3b1a..8263b61 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -407,6 +407,10 @@
         visit_impl_item_const_mut(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_impl_item_existential_mut(&mut self, i: &mut ImplItemExistential) {
+        visit_impl_item_existential_mut(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_impl_item_macro_mut(&mut self, i: &mut ImplItemMacro) {
         visit_impl_item_macro_mut(self, i)
     }
@@ -439,6 +443,10 @@
         visit_item_enum_mut(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_item_existential_mut(&mut self, i: &mut ItemExistential) {
+        visit_item_existential_mut(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_item_extern_crate_mut(&mut self, i: &mut ItemExternCrate) {
         visit_item_extern_crate_mut(self, i)
     }
@@ -721,6 +729,10 @@
         visit_trait_item_const_mut(self, i)
     }
     #[cfg(feature = "full")]
+    fn visit_trait_item_existential_mut(&mut self, i: &mut TraitItemExistential) {
+        visit_trait_item_existential_mut(self, i)
+    }
+    #[cfg(feature = "full")]
     fn visit_trait_item_macro_mut(&mut self, i: &mut TraitItemMacro) {
         visit_trait_item_macro_mut(self, i)
     }
@@ -2018,6 +2030,9 @@
         ImplItem::Type(ref mut _binding_0) => {
             _visitor.visit_impl_item_type_mut(_binding_0);
         }
+        ImplItem::Existential(ref mut _binding_0) => {
+            _visitor.visit_impl_item_existential_mut(_binding_0);
+        }
         ImplItem::Macro(ref mut _binding_0) => {
             _visitor.visit_impl_item_macro_mut(_binding_0);
         }
@@ -2044,6 +2059,27 @@
     tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
+pub fn visit_impl_item_existential_mut<V: VisitMut + ?Sized>(
+    _visitor: &mut V,
+    _i: &mut ImplItemExistential,
+) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.existential_token.span);
+    tokens_helper(_visitor, &mut _i.type_token.span);
+    _visitor.visit_ident_mut(&mut _i.ident);
+    _visitor.visit_generics_mut(&mut _i.generics);
+    if let Some(ref mut it) = _i.colon_token {
+        tokens_helper(_visitor, &mut it.spans)
+    };
+    for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+        let it = el.value_mut();
+        _visitor.visit_type_param_bound_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_impl_item_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ImplItemMacro) {
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
@@ -2120,6 +2156,9 @@
         Item::Type(ref mut _binding_0) => {
             _visitor.visit_item_type_mut(_binding_0);
         }
+        Item::Existential(ref mut _binding_0) => {
+            _visitor.visit_item_existential_mut(_binding_0);
+        }
         Item::Struct(ref mut _binding_0) => {
             _visitor.visit_item_struct_mut(_binding_0);
         }
@@ -2176,6 +2215,28 @@
     }
 }
 #[cfg(feature = "full")]
+pub fn visit_item_existential_mut<V: VisitMut + ?Sized>(
+    _visitor: &mut V,
+    _i: &mut ItemExistential,
+) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    _visitor.visit_visibility_mut(&mut _i.vis);
+    tokens_helper(_visitor, &mut _i.existential_token.span);
+    tokens_helper(_visitor, &mut _i.type_token.span);
+    _visitor.visit_ident_mut(&mut _i.ident);
+    _visitor.visit_generics_mut(&mut _i.generics);
+    if let Some(ref mut it) = _i.colon_token {
+        tokens_helper(_visitor, &mut it.spans)
+    };
+    for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+        let it = el.value_mut();
+        _visitor.visit_type_param_bound_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_item_extern_crate_mut<V: VisitMut + ?Sized>(
     _visitor: &mut V,
     _i: &mut ItemExternCrate,
@@ -2934,6 +2995,9 @@
         TraitItem::Type(ref mut _binding_0) => {
             _visitor.visit_trait_item_type_mut(_binding_0);
         }
+        TraitItem::Existential(ref mut _binding_0) => {
+            _visitor.visit_trait_item_existential_mut(_binding_0);
+        }
         TraitItem::Macro(ref mut _binding_0) => {
             _visitor.visit_trait_item_macro_mut(_binding_0);
         }
@@ -2958,6 +3022,27 @@
     tokens_helper(_visitor, &mut _i.semi_token.spans);
 }
 #[cfg(feature = "full")]
+pub fn visit_trait_item_existential_mut<V: VisitMut + ?Sized>(
+    _visitor: &mut V,
+    _i: &mut TraitItemExistential,
+) {
+    for it in &mut _i.attrs {
+        _visitor.visit_attribute_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.existential_token.span);
+    tokens_helper(_visitor, &mut _i.type_token.span);
+    _visitor.visit_ident_mut(&mut _i.ident);
+    _visitor.visit_generics_mut(&mut _i.generics);
+    if let Some(ref mut it) = _i.colon_token {
+        tokens_helper(_visitor, &mut it.spans)
+    };
+    for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+        let it = el.value_mut();
+        _visitor.visit_type_param_bound_mut(it)
+    }
+    tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
 pub fn visit_trait_item_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemMacro) {
     for it in &mut _i.attrs {
         _visitor.visit_attribute_mut(it)
diff --git a/src/item.rs b/src/item.rs
index 09469b5..cb6184d 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -136,6 +136,21 @@
             pub semi_token: Token![;],
         }),
 
+        /// An existential type: `existential type Iter: Iterator<Item = u8>`.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub Existential(ItemExistential {
+            pub attrs: Vec<Attribute>,
+            pub vis: Visibility,
+            pub existential_token: Token![existential],
+            pub type_token: Token![type],
+            pub ident: Ident,
+            pub generics: Generics,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Punctuated<TypeParamBound, Token![+]>,
+            pub semi_token: Token![;],
+        }),
+
         /// A struct definition: `struct Foo<A> { x: A }`.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
@@ -516,6 +531,20 @@
             pub semi_token: Token![;],
         }),
 
+        /// An existential type within the definition of a trait.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub Existential(TraitItemExistential {
+            pub attrs: Vec<Attribute>,
+            pub existential_token: Token![existential],
+            pub type_token: Token![type],
+            pub ident: Ident,
+            pub generics: Generics,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Punctuated<TypeParamBound, Token![+]>,
+            pub semi_token: Token![;],
+        }),
+
         /// A macro invocation within the definition of a trait.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
@@ -607,6 +636,20 @@
             pub semi_token: Token![;],
         }),
 
+        /// An existential type within an impl block.
+        ///
+        /// *This type is available if Syn is built with the `"full"` feature.*
+        pub Existential(ImplItemExistential {
+            pub attrs: Vec<Attribute>,
+            pub existential_token: Token![existential],
+            pub type_token: Token![type],
+            pub ident: Ident,
+            pub generics: Generics,
+            pub colon_token: Option<Token![:]>,
+            pub bounds: Punctuated<TypeParamBound, Token![+]>,
+            pub semi_token: Token![;],
+        }),
+
         /// A macro invocation within an impl block.
         ///
         /// *This type is available if Syn is built with the `"full"` feature.*
@@ -744,7 +787,7 @@
         |
         syn!(ItemType) => { Item::Type }
         |
-        call!(unstable_existential_type) => { Item::Verbatim }
+        syn!(ItemExistential) => { Item::Existential }
         |
         syn!(ItemStruct) => { Item::Struct }
         |
@@ -1219,29 +1262,37 @@
         })
     ));
 
-    named!(existential_type_helper(vis: bool) -> TokenStream, do_parse!(
-        begin: call!(verbatim::grab_cursor) >>
-        many0!(Attribute::parse_outer) >>
-        cond_reduce!(vis, syn!(Visibility)) >>
-        custom_keyword!(existential) >>
-        keyword!(type) >>
-        syn!(Ident) >>
-        syn!(Generics) >>
-        option!(syn!(WhereClause)) >>
+    named!(existential_type(vis: bool) -> ItemExistential, do_parse!(
+        attrs: many0!(Attribute::parse_outer) >>
+        vis: cond_reduce!(vis, syn!(Visibility)) >>
+        existential_token: keyword!(existential) >>
+        type_token: keyword!(type) >>
+        ident: syn!(Ident) >>
+        generics: syn!(Generics) >>
+        where_clause: option!(syn!(WhereClause)) >>
         colon: option!(punct!(:)) >>
-        cond!(
+        bounds: cond!(
             colon.is_some(),
             Punctuated::<TypeParamBound, Token![+]>::parse_separated_nonempty
         ) >>
-        punct!(;) >>
-        end: call!(verbatim::grab_cursor) >>
-        (verbatim::token_range(begin..end))
+        semi: punct!(;) >>
+        (ItemExistential {
+            attrs: attrs,
+            vis: vis,
+            existential_token: existential_token,
+            type_token: type_token,
+            ident: ident,
+            generics: Generics {
+                where_clause: where_clause,
+                ..generics
+            },
+            colon_token: colon,
+            bounds: bounds.unwrap_or_else(Punctuated::new),
+            semi_token: semi,
+        })
     ));
 
-    named!(unstable_existential_type -> ItemVerbatim, map!(
-        call!(existential_type_helper, true),
-        |tts| ItemVerbatim { tts: tts }
-    ));
+    impl_synom!(ItemExistential "existential type" call!(existential_type, true));
 
     impl_synom!(ItemStruct "struct item" switch!(
         map!(syn!(DeriveInput), Into::into),
@@ -1315,7 +1366,7 @@
         |
         syn!(TraitItemType) => { TraitItem::Type }
         |
-        call!(unstable_trait_existential_type) => { TraitItem::Verbatim }
+        syn!(TraitItemExistential) => { TraitItem::Existential }
         |
         syn!(TraitItemMacro) => { TraitItem::Macro }
     ));
@@ -1420,9 +1471,18 @@
         })
     ));
 
-    named!(unstable_trait_existential_type -> TraitItemVerbatim, map!(
-        call!(existential_type_helper, false),
-        |tts| TraitItemVerbatim { tts: tts }
+    impl_synom!(TraitItemExistential "trait item existential type" map!(
+        call!(existential_type, false),
+        |ety| TraitItemExistential {
+            attrs: ety.attrs,
+            existential_token: ety.existential_token,
+            type_token: ety.type_token,
+            ident: ety.ident,
+            generics: ety.generics,
+            colon_token: ety.colon_token,
+            bounds: ety.bounds,
+            semi_token: ety.semi_token,
+        }
     ));
 
     impl_synom!(TraitItemMacro "trait item macro" do_parse!(
@@ -1485,7 +1545,7 @@
         |
         syn!(ImplItemType) => { ImplItem::Type }
         |
-        call!(unstable_impl_existential_type) => { ImplItem::Verbatim }
+        syn!(ImplItemExistential) => { ImplItem::Existential }
         |
         syn!(ImplItemMacro) => { ImplItem::Macro }
     ));
@@ -1593,9 +1653,18 @@
         })
     ));
 
-    named!(unstable_impl_existential_type -> ImplItemVerbatim, map!(
-        call!(existential_type_helper, true),
-        |tts| ImplItemVerbatim { tts: tts }
+    impl_synom!(ImplItemExistential "existential type in impl block" map!(
+        call!(existential_type, true),
+        |ety| ImplItemExistential {
+            attrs: ety.attrs,
+            existential_token: ety.existential_token,
+            type_token: ety.type_token,
+            ident: ety.ident,
+            generics: ety.generics,
+            colon_token: ety.colon_token,
+            bounds: ety.bounds,
+            semi_token: ety.semi_token,
+        }
     ));
 
     impl_synom!(ImplItemMacro "macro in impl block" do_parse!(
@@ -1737,6 +1806,23 @@
         }
     }
 
+    impl ToTokens for ItemExistential {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            tokens.append_all(self.attrs.outer());
+            self.vis.to_tokens(tokens);
+            self.existential_token.to_tokens(tokens);
+            self.type_token.to_tokens(tokens);
+            self.ident.to_tokens(tokens);
+            self.generics.to_tokens(tokens);
+            self.generics.where_clause.to_tokens(tokens);
+            if !self.bounds.is_empty() {
+                TokensOrDefault(&self.colon_token).to_tokens(tokens);
+                self.bounds.to_tokens(tokens);
+            }
+            self.semi_token.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for ItemEnum {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -1959,6 +2045,22 @@
         }
     }
 
+    impl ToTokens for TraitItemExistential {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            tokens.append_all(self.attrs.outer());
+            self.existential_token.to_tokens(tokens);
+            self.type_token.to_tokens(tokens);
+            self.ident.to_tokens(tokens);
+            self.generics.to_tokens(tokens);
+            self.generics.where_clause.to_tokens(tokens);
+            if !self.bounds.is_empty() {
+                TokensOrDefault(&self.colon_token).to_tokens(tokens);
+                self.bounds.to_tokens(tokens);
+            }
+            self.semi_token.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for TraitItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2016,6 +2118,22 @@
         }
     }
 
+    impl ToTokens for ImplItemExistential {
+        fn to_tokens(&self, tokens: &mut TokenStream) {
+            tokens.append_all(self.attrs.outer());
+            self.existential_token.to_tokens(tokens);
+            self.type_token.to_tokens(tokens);
+            self.ident.to_tokens(tokens);
+            self.generics.to_tokens(tokens);
+            self.generics.where_clause.to_tokens(tokens);
+            if !self.bounds.is_empty() {
+                TokensOrDefault(&self.colon_token).to_tokens(tokens);
+                self.bounds.to_tokens(tokens);
+            }
+            self.semi_token.to_tokens(tokens);
+        }
+    }
+
     impl ToTokens for ImplItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
diff --git a/src/lib.rs b/src/lib.rs
index b4d2c5c..0b25ec2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -369,11 +369,12 @@
 pub use item::{
     ArgCaptured, ArgSelf, ArgSelfRef, FnArg, FnDecl, ForeignItem, ForeignItemFn, ForeignItemMacro,
     ForeignItemStatic, ForeignItemType, ForeignItemVerbatim, ImplItem, ImplItemConst,
-    ImplItemMacro, ImplItemMethod, ImplItemType, ImplItemVerbatim, Item, ItemConst, ItemEnum,
-    ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMacro2, ItemMod, ItemStatic,
-    ItemStruct, ItemTrait, ItemType, ItemUnion, ItemUse, ItemVerbatim, MethodSig, TraitItem,
-    TraitItemConst, TraitItemMacro, TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob,
-    UseGroup, UseName, UsePath, UseRename, UseTree,
+    ImplItemExistential, ImplItemMacro, ImplItemMethod, ImplItemType, ImplItemVerbatim, Item,
+    ItemConst, ItemEnum, ItemExistential, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl,
+    ItemMacro, ItemMacro2, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemType, ItemUnion,
+    ItemUse, ItemVerbatim, MethodSig, TraitItem, TraitItemConst, TraitItemExistential,
+    TraitItemMacro, TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName,
+    UsePath, UseRename, UseTree,
 };
 
 #[cfg(feature = "full")]
diff --git a/src/token.rs b/src/token.rs
index dd8a84b..4ec3743 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -435,101 +435,102 @@
 
 tokens! {
     punct: {
-        "+"        pub struct Add/1        /// `+`
-        "+="       pub struct AddEq/2      /// `+=`
-        "&"        pub struct And/1        /// `&`
-        "&&"       pub struct AndAnd/2     /// `&&`
-        "&="       pub struct AndEq/2      /// `&=`
-        "@"        pub struct At/1         /// `@`
-        "!"        pub struct Bang/1       /// `!`
-        "^"        pub struct Caret/1      /// `^`
-        "^="       pub struct CaretEq/2    /// `^=`
-        ":"        pub struct Colon/1      /// `:`
-        "::"       pub struct Colon2/2     /// `::`
-        ","        pub struct Comma/1      /// `,`
-        "/"        pub struct Div/1        /// `/`
-        "/="       pub struct DivEq/2      /// `/=`
-        "$"        pub struct Dollar/1     /// `$`
-        "."        pub struct Dot/1        /// `.`
-        ".."       pub struct Dot2/2       /// `..`
-        "..."      pub struct Dot3/3       /// `...`
-        "..="      pub struct DotDotEq/3   /// `..=`
-        "="        pub struct Eq/1         /// `=`
-        "=="       pub struct EqEq/2       /// `==`
-        ">="       pub struct Ge/2         /// `>=`
-        ">"        pub struct Gt/1         /// `>`
-        "<="       pub struct Le/2         /// `<=`
-        "<"        pub struct Lt/1         /// `<`
-        "*="       pub struct MulEq/2      /// `*=`
-        "!="       pub struct Ne/2         /// `!=`
-        "|"        pub struct Or/1         /// `|`
-        "|="       pub struct OrEq/2       /// `|=`
-        "||"       pub struct OrOr/2       /// `||`
-        "#"        pub struct Pound/1      /// `#`
-        "?"        pub struct Question/1   /// `?`
-        "->"       pub struct RArrow/2     /// `->`
-        "<-"       pub struct LArrow/2     /// `<-`
-        "%"        pub struct Rem/1        /// `%`
-        "%="       pub struct RemEq/2      /// `%=`
-        "=>"       pub struct FatArrow/2   /// `=>`
-        ";"        pub struct Semi/1       /// `;`
-        "<<"       pub struct Shl/2        /// `<<`
-        "<<="      pub struct ShlEq/3      /// `<<=`
-        ">>"       pub struct Shr/2        /// `>>`
-        ">>="      pub struct ShrEq/3      /// `>>=`
-        "*"        pub struct Star/1       /// `*`
-        "-"        pub struct Sub/1        /// `-`
-        "-="       pub struct SubEq/2      /// `-=`
+        "+"           pub struct Add/1        /// `+`
+        "+="          pub struct AddEq/2      /// `+=`
+        "&"           pub struct And/1        /// `&`
+        "&&"          pub struct AndAnd/2     /// `&&`
+        "&="          pub struct AndEq/2      /// `&=`
+        "@"           pub struct At/1         /// `@`
+        "!"           pub struct Bang/1       /// `!`
+        "^"           pub struct Caret/1      /// `^`
+        "^="          pub struct CaretEq/2    /// `^=`
+        ":"           pub struct Colon/1      /// `:`
+        "::"          pub struct Colon2/2     /// `::`
+        ","           pub struct Comma/1      /// `,`
+        "/"           pub struct Div/1        /// `/`
+        "/="          pub struct DivEq/2      /// `/=`
+        "$"           pub struct Dollar/1     /// `$`
+        "."           pub struct Dot/1        /// `.`
+        ".."          pub struct Dot2/2       /// `..`
+        "..."         pub struct Dot3/3       /// `...`
+        "..="         pub struct DotDotEq/3   /// `..=`
+        "="           pub struct Eq/1         /// `=`
+        "=="          pub struct EqEq/2       /// `==`
+        ">="          pub struct Ge/2         /// `>=`
+        ">"           pub struct Gt/1         /// `>`
+        "<="          pub struct Le/2         /// `<=`
+        "<"           pub struct Lt/1         /// `<`
+        "*="          pub struct MulEq/2      /// `*=`
+        "!="          pub struct Ne/2         /// `!=`
+        "|"           pub struct Or/1         /// `|`
+        "|="          pub struct OrEq/2       /// `|=`
+        "||"          pub struct OrOr/2       /// `||`
+        "#"           pub struct Pound/1      /// `#`
+        "?"           pub struct Question/1   /// `?`
+        "->"          pub struct RArrow/2     /// `->`
+        "<-"          pub struct LArrow/2     /// `<-`
+        "%"           pub struct Rem/1        /// `%`
+        "%="          pub struct RemEq/2      /// `%=`
+        "=>"          pub struct FatArrow/2   /// `=>`
+        ";"           pub struct Semi/1       /// `;`
+        "<<"          pub struct Shl/2        /// `<<`
+        "<<="         pub struct ShlEq/3      /// `<<=`
+        ">>"          pub struct Shr/2        /// `>>`
+        ">>="         pub struct ShrEq/3      /// `>>=`
+        "*"           pub struct Star/1       /// `*`
+        "-"           pub struct Sub/1        /// `-`
+        "-="          pub struct SubEq/2      /// `-=`
     }
     delimiter: {
-        "{"        pub struct Brace        /// `{...}`
-        "["        pub struct Bracket      /// `[...]`
-        "("        pub struct Paren        /// `(...)`
-        " "        pub struct Group        /// None-delimited group
+        "{"           pub struct Brace        /// `{...}`
+        "["           pub struct Bracket      /// `[...]`
+        "("           pub struct Paren        /// `(...)`
+        " "           pub struct Group        /// None-delimited group
     }
     keyword: {
-        "as"       pub struct As           /// `as`
-        "async"    pub struct Async        /// `async`
-        "auto"     pub struct Auto         /// `auto`
-        "box"      pub struct Box          /// `box`
-        "break"    pub struct Break        /// `break`
-        "Self"     pub struct CapSelf      /// `Self`
-        "const"    pub struct Const        /// `const`
-        "continue" pub struct Continue     /// `continue`
-        "crate"    pub struct Crate        /// `crate`
-        "default"  pub struct Default      /// `default`
-        "dyn"      pub struct Dyn          /// `dyn`
-        "else"     pub struct Else         /// `else`
-        "enum"     pub struct Enum         /// `enum`
-        "extern"   pub struct Extern       /// `extern`
-        "fn"       pub struct Fn           /// `fn`
-        "for"      pub struct For          /// `for`
-        "if"       pub struct If           /// `if`
-        "impl"     pub struct Impl         /// `impl`
-        "in"       pub struct In           /// `in`
-        "let"      pub struct Let          /// `let`
-        "loop"     pub struct Loop         /// `loop`
-        "macro"    pub struct Macro        /// `macro`
-        "match"    pub struct Match        /// `match`
-        "mod"      pub struct Mod          /// `mod`
-        "move"     pub struct Move         /// `move`
-        "mut"      pub struct Mut          /// `mut`
-        "pub"      pub struct Pub          /// `pub`
-        "ref"      pub struct Ref          /// `ref`
-        "return"   pub struct Return       /// `return`
-        "self"     pub struct Self_        /// `self`
-        "static"   pub struct Static       /// `static`
-        "struct"   pub struct Struct       /// `struct`
-        "super"    pub struct Super        /// `super`
-        "trait"    pub struct Trait        /// `trait`
-        "try"      pub struct Try          /// `try`
-        "type"     pub struct Type         /// `type`
-        "union"    pub struct Union        /// `union`
-        "unsafe"   pub struct Unsafe       /// `unsafe`
-        "use"      pub struct Use          /// `use`
-        "where"    pub struct Where        /// `where`
-        "while"    pub struct While        /// `while`
-        "yield"    pub struct Yield        /// `yield`
+        "as"          pub struct As           /// `as`
+        "async"       pub struct Async        /// `async`
+        "auto"        pub struct Auto         /// `auto`
+        "box"         pub struct Box          /// `box`
+        "break"       pub struct Break        /// `break`
+        "Self"        pub struct CapSelf      /// `Self`
+        "const"       pub struct Const        /// `const`
+        "continue"    pub struct Continue     /// `continue`
+        "crate"       pub struct Crate        /// `crate`
+        "default"     pub struct Default      /// `default`
+        "dyn"         pub struct Dyn          /// `dyn`
+        "else"        pub struct Else         /// `else`
+        "enum"        pub struct Enum         /// `enum`
+        "existential" pub struct Existential  /// `existential`
+        "extern"      pub struct Extern       /// `extern`
+        "fn"          pub struct Fn           /// `fn`
+        "for"         pub struct For          /// `for`
+        "if"          pub struct If           /// `if`
+        "impl"        pub struct Impl         /// `impl`
+        "in"          pub struct In           /// `in`
+        "let"         pub struct Let          /// `let`
+        "loop"        pub struct Loop         /// `loop`
+        "macro"       pub struct Macro        /// `macro`
+        "match"       pub struct Match        /// `match`
+        "mod"         pub struct Mod          /// `mod`
+        "move"        pub struct Move         /// `move`
+        "mut"         pub struct Mut          /// `mut`
+        "pub"         pub struct Pub          /// `pub`
+        "ref"         pub struct Ref          /// `ref`
+        "return"      pub struct Return       /// `return`
+        "self"        pub struct Self_        /// `self`
+        "static"      pub struct Static       /// `static`
+        "struct"      pub struct Struct       /// `struct`
+        "super"       pub struct Super        /// `super`
+        "trait"       pub struct Trait        /// `trait`
+        "try"         pub struct Try          /// `try`
+        "type"        pub struct Type         /// `type`
+        "union"       pub struct Union        /// `union`
+        "unsafe"      pub struct Unsafe       /// `unsafe`
+        "use"         pub struct Use          /// `use`
+        "where"       pub struct Where        /// `where`
+        "while"       pub struct While        /// `while`
+        "yield"       pub struct Yield        /// `yield`
     }
 }
 
@@ -544,93 +545,94 @@
 #[macro_export]
 #[cfg_attr(rustfmt, rustfmt_skip)]
 macro_rules! Token {
-    (+)        => { $crate::token::Add };
-    (+=)       => { $crate::token::AddEq };
-    (&)        => { $crate::token::And };
-    (&&)       => { $crate::token::AndAnd };
-    (&=)       => { $crate::token::AndEq };
-    (@)        => { $crate::token::At };
-    (!)        => { $crate::token::Bang };
-    (^)        => { $crate::token::Caret };
-    (^=)       => { $crate::token::CaretEq };
-    (:)        => { $crate::token::Colon };
-    (::)       => { $crate::token::Colon2 };
-    (,)        => { $crate::token::Comma };
-    (/)        => { $crate::token::Div };
-    (/=)       => { $crate::token::DivEq };
-    (.)        => { $crate::token::Dot };
-    (..)       => { $crate::token::Dot2 };
-    (...)      => { $crate::token::Dot3 };
-    (..=)      => { $crate::token::DotDotEq };
-    (=)        => { $crate::token::Eq };
-    (==)       => { $crate::token::EqEq };
-    (>=)       => { $crate::token::Ge };
-    (>)        => { $crate::token::Gt };
-    (<=)       => { $crate::token::Le };
-    (<)        => { $crate::token::Lt };
-    (*=)       => { $crate::token::MulEq };
-    (!=)       => { $crate::token::Ne };
-    (|)        => { $crate::token::Or };
-    (|=)       => { $crate::token::OrEq };
-    (||)       => { $crate::token::OrOr };
-    (#)        => { $crate::token::Pound };
-    (?)        => { $crate::token::Question };
-    (->)       => { $crate::token::RArrow };
-    (<-)       => { $crate::token::LArrow };
-    (%)        => { $crate::token::Rem };
-    (%=)       => { $crate::token::RemEq };
-    (=>)       => { $crate::token::FatArrow };
-    (;)        => { $crate::token::Semi };
-    (<<)       => { $crate::token::Shl };
-    (<<=)      => { $crate::token::ShlEq };
-    (>>)       => { $crate::token::Shr };
-    (>>=)      => { $crate::token::ShrEq };
-    (*)        => { $crate::token::Star };
-    (-)        => { $crate::token::Sub };
-    (-=)       => { $crate::token::SubEq };
-    (_)        => { $crate::token::Underscore };
-    (as)       => { $crate::token::As };
-    (async)    => { $crate::token::Async };
-    (auto)     => { $crate::token::Auto };
-    (box)      => { $crate::token::Box };
-    (break)    => { $crate::token::Break };
-    (Self)     => { $crate::token::CapSelf };
-    (const)    => { $crate::token::Const };
-    (continue) => { $crate::token::Continue };
-    (crate)    => { $crate::token::Crate };
-    (default)  => { $crate::token::Default };
-    (dyn)      => { $crate::token::Dyn };
-    (else)     => { $crate::token::Else };
-    (enum)     => { $crate::token::Enum };
-    (extern)   => { $crate::token::Extern };
-    (fn)       => { $crate::token::Fn };
-    (for)      => { $crate::token::For };
-    (if)       => { $crate::token::If };
-    (impl)     => { $crate::token::Impl };
-    (in)       => { $crate::token::In };
-    (let)      => { $crate::token::Let };
-    (loop)     => { $crate::token::Loop };
-    (macro)    => { $crate::token::Macro };
-    (match)    => { $crate::token::Match };
-    (mod)      => { $crate::token::Mod };
-    (move)     => { $crate::token::Move };
-    (mut)      => { $crate::token::Mut };
-    (pub)      => { $crate::token::Pub };
-    (ref)      => { $crate::token::Ref };
-    (return)   => { $crate::token::Return };
-    (self)     => { $crate::token::Self_ };
-    (static)   => { $crate::token::Static };
-    (struct)   => { $crate::token::Struct };
-    (super)    => { $crate::token::Super };
-    (trait)    => { $crate::token::Trait };
-    (try)      => { $crate::token::Try };
-    (type)     => { $crate::token::Type };
-    (union)    => { $crate::token::Union };
-    (unsafe)   => { $crate::token::Unsafe };
-    (use)      => { $crate::token::Use };
-    (where)    => { $crate::token::Where };
-    (while)    => { $crate::token::While };
-    (yield)    => { $crate::token::Yield };
+    (+)           => { $crate::token::Add };
+    (+=)          => { $crate::token::AddEq };
+    (&)           => { $crate::token::And };
+    (&&)          => { $crate::token::AndAnd };
+    (&=)          => { $crate::token::AndEq };
+    (@)           => { $crate::token::At };
+    (!)           => { $crate::token::Bang };
+    (^)           => { $crate::token::Caret };
+    (^=)          => { $crate::token::CaretEq };
+    (:)           => { $crate::token::Colon };
+    (::)          => { $crate::token::Colon2 };
+    (,)           => { $crate::token::Comma };
+    (/)           => { $crate::token::Div };
+    (/=)          => { $crate::token::DivEq };
+    (.)           => { $crate::token::Dot };
+    (..)          => { $crate::token::Dot2 };
+    (...)         => { $crate::token::Dot3 };
+    (..=)         => { $crate::token::DotDotEq };
+    (=)           => { $crate::token::Eq };
+    (==)          => { $crate::token::EqEq };
+    (>=)          => { $crate::token::Ge };
+    (>)           => { $crate::token::Gt };
+    (<=)          => { $crate::token::Le };
+    (<)           => { $crate::token::Lt };
+    (*=)          => { $crate::token::MulEq };
+    (!=)          => { $crate::token::Ne };
+    (|)           => { $crate::token::Or };
+    (|=)          => { $crate::token::OrEq };
+    (||)          => { $crate::token::OrOr };
+    (#)           => { $crate::token::Pound };
+    (?)           => { $crate::token::Question };
+    (->)          => { $crate::token::RArrow };
+    (<-)          => { $crate::token::LArrow };
+    (%)           => { $crate::token::Rem };
+    (%=)          => { $crate::token::RemEq };
+    (=>)          => { $crate::token::FatArrow };
+    (;)           => { $crate::token::Semi };
+    (<<)          => { $crate::token::Shl };
+    (<<=)         => { $crate::token::ShlEq };
+    (>>)          => { $crate::token::Shr };
+    (>>=)         => { $crate::token::ShrEq };
+    (*)           => { $crate::token::Star };
+    (-)           => { $crate::token::Sub };
+    (-=)          => { $crate::token::SubEq };
+    (_)           => { $crate::token::Underscore };
+    (as)          => { $crate::token::As };
+    (async)       => { $crate::token::Async };
+    (auto)        => { $crate::token::Auto };
+    (box)         => { $crate::token::Box };
+    (break)       => { $crate::token::Break };
+    (Self)        => { $crate::token::CapSelf };
+    (const)       => { $crate::token::Const };
+    (continue)    => { $crate::token::Continue };
+    (crate)       => { $crate::token::Crate };
+    (default)     => { $crate::token::Default };
+    (dyn)         => { $crate::token::Dyn };
+    (else)        => { $crate::token::Else };
+    (enum)        => { $crate::token::Enum };
+    (existential) => { $crate::token::Existential };
+    (extern)      => { $crate::token::Extern };
+    (fn)          => { $crate::token::Fn };
+    (for)         => { $crate::token::For };
+    (if)          => { $crate::token::If };
+    (impl)        => { $crate::token::Impl };
+    (in)          => { $crate::token::In };
+    (let)         => { $crate::token::Let };
+    (loop)        => { $crate::token::Loop };
+    (macro)       => { $crate::token::Macro };
+    (match)       => { $crate::token::Match };
+    (mod)         => { $crate::token::Mod };
+    (move)        => { $crate::token::Move };
+    (mut)         => { $crate::token::Mut };
+    (pub)         => { $crate::token::Pub };
+    (ref)         => { $crate::token::Ref };
+    (return)      => { $crate::token::Return };
+    (self)        => { $crate::token::Self_ };
+    (static)      => { $crate::token::Static };
+    (struct)      => { $crate::token::Struct };
+    (super)       => { $crate::token::Super };
+    (trait)       => { $crate::token::Trait };
+    (try)         => { $crate::token::Try };
+    (type)        => { $crate::token::Type };
+    (union)       => { $crate::token::Union };
+    (unsafe)      => { $crate::token::Unsafe };
+    (use)         => { $crate::token::Use };
+    (where)       => { $crate::token::Where };
+    (while)       => { $crate::token::While };
+    (yield)       => { $crate::token::Yield };
 }
 
 /// Parse a single Rust punctuation token.
@@ -702,48 +704,49 @@
 #[macro_export]
 #[cfg_attr(rustfmt, rustfmt_skip)]
 macro_rules! keyword {
-    ($i:expr, as)       => { call!($i, <$crate::token::As as $crate::synom::Synom>::parse) };
-    ($i:expr, async)    => { call!($i, <$crate::token::Async as $crate::synom::Synom>::parse) };
-    ($i:expr, auto)     => { call!($i, <$crate::token::Auto as $crate::synom::Synom>::parse) };
-    ($i:expr, box)      => { call!($i, <$crate::token::Box as $crate::synom::Synom>::parse) };
-    ($i:expr, break)    => { call!($i, <$crate::token::Break as $crate::synom::Synom>::parse) };
-    ($i:expr, Self)     => { call!($i, <$crate::token::CapSelf as $crate::synom::Synom>::parse) };
-    ($i:expr, const)    => { call!($i, <$crate::token::Const as $crate::synom::Synom>::parse) };
-    ($i:expr, continue) => { call!($i, <$crate::token::Continue as $crate::synom::Synom>::parse) };
-    ($i:expr, crate)    => { call!($i, <$crate::token::Crate as $crate::synom::Synom>::parse) };
-    ($i:expr, default)  => { call!($i, <$crate::token::Default as $crate::synom::Synom>::parse) };
-    ($i:expr, dyn)      => { call!($i, <$crate::token::Dyn as $crate::synom::Synom>::parse) };
-    ($i:expr, else)     => { call!($i, <$crate::token::Else as $crate::synom::Synom>::parse) };
-    ($i:expr, enum)     => { call!($i, <$crate::token::Enum as $crate::synom::Synom>::parse) };
-    ($i:expr, extern)   => { call!($i, <$crate::token::Extern as $crate::synom::Synom>::parse) };
-    ($i:expr, fn)       => { call!($i, <$crate::token::Fn as $crate::synom::Synom>::parse) };
-    ($i:expr, for)      => { call!($i, <$crate::token::For as $crate::synom::Synom>::parse) };
-    ($i:expr, if)       => { call!($i, <$crate::token::If as $crate::synom::Synom>::parse) };
-    ($i:expr, impl)     => { call!($i, <$crate::token::Impl as $crate::synom::Synom>::parse) };
-    ($i:expr, in)       => { call!($i, <$crate::token::In as $crate::synom::Synom>::parse) };
-    ($i:expr, let)      => { call!($i, <$crate::token::Let as $crate::synom::Synom>::parse) };
-    ($i:expr, loop)     => { call!($i, <$crate::token::Loop as $crate::synom::Synom>::parse) };
-    ($i:expr, macro)    => { call!($i, <$crate::token::Macro as $crate::synom::Synom>::parse) };
-    ($i:expr, match)    => { call!($i, <$crate::token::Match as $crate::synom::Synom>::parse) };
-    ($i:expr, mod)      => { call!($i, <$crate::token::Mod as $crate::synom::Synom>::parse) };
-    ($i:expr, move)     => { call!($i, <$crate::token::Move as $crate::synom::Synom>::parse) };
-    ($i:expr, mut)      => { call!($i, <$crate::token::Mut as $crate::synom::Synom>::parse) };
-    ($i:expr, pub)      => { call!($i, <$crate::token::Pub as $crate::synom::Synom>::parse) };
-    ($i:expr, ref)      => { call!($i, <$crate::token::Ref as $crate::synom::Synom>::parse) };
-    ($i:expr, return)   => { call!($i, <$crate::token::Return as $crate::synom::Synom>::parse) };
-    ($i:expr, self)     => { call!($i, <$crate::token::Self_ as $crate::synom::Synom>::parse) };
-    ($i:expr, static)   => { call!($i, <$crate::token::Static as $crate::synom::Synom>::parse) };
-    ($i:expr, struct)   => { call!($i, <$crate::token::Struct as $crate::synom::Synom>::parse) };
-    ($i:expr, super)    => { call!($i, <$crate::token::Super as $crate::synom::Synom>::parse) };
-    ($i:expr, trait)    => { call!($i, <$crate::token::Trait as $crate::synom::Synom>::parse) };
-    ($i:expr, try)      => { call!($i, <$crate::token::Try as $crate::synom::Synom>::parse) };
-    ($i:expr, type)     => { call!($i, <$crate::token::Type as $crate::synom::Synom>::parse) };
-    ($i:expr, union)    => { call!($i, <$crate::token::Union as $crate::synom::Synom>::parse) };
-    ($i:expr, unsafe)   => { call!($i, <$crate::token::Unsafe as $crate::synom::Synom>::parse) };
-    ($i:expr, use)      => { call!($i, <$crate::token::Use as $crate::synom::Synom>::parse) };
-    ($i:expr, where)    => { call!($i, <$crate::token::Where as $crate::synom::Synom>::parse) };
-    ($i:expr, while)    => { call!($i, <$crate::token::While as $crate::synom::Synom>::parse) };
-    ($i:expr, yield)    => { call!($i, <$crate::token::Yield as $crate::synom::Synom>::parse) };
+    ($i:expr, as)          => { call!($i, <$crate::token::As as $crate::synom::Synom>::parse) };
+    ($i:expr, async)       => { call!($i, <$crate::token::Async as $crate::synom::Synom>::parse) };
+    ($i:expr, auto)        => { call!($i, <$crate::token::Auto as $crate::synom::Synom>::parse) };
+    ($i:expr, box)         => { call!($i, <$crate::token::Box as $crate::synom::Synom>::parse) };
+    ($i:expr, break)       => { call!($i, <$crate::token::Break as $crate::synom::Synom>::parse) };
+    ($i:expr, Self)        => { call!($i, <$crate::token::CapSelf as $crate::synom::Synom>::parse) };
+    ($i:expr, const)       => { call!($i, <$crate::token::Const as $crate::synom::Synom>::parse) };
+    ($i:expr, continue)    => { call!($i, <$crate::token::Continue as $crate::synom::Synom>::parse) };
+    ($i:expr, crate)       => { call!($i, <$crate::token::Crate as $crate::synom::Synom>::parse) };
+    ($i:expr, default)     => { call!($i, <$crate::token::Default as $crate::synom::Synom>::parse) };
+    ($i:expr, dyn)         => { call!($i, <$crate::token::Dyn as $crate::synom::Synom>::parse) };
+    ($i:expr, else)        => { call!($i, <$crate::token::Else as $crate::synom::Synom>::parse) };
+    ($i:expr, enum)        => { call!($i, <$crate::token::Enum as $crate::synom::Synom>::parse) };
+    ($i:expr, extern)      => { call!($i, <$crate::token::Extern as $crate::synom::Synom>::parse) };
+    ($i:expr, existential) => { call!($i, <$crate::token::Existential as $crate::synom::Synom>::parse) };
+    ($i:expr, fn)          => { call!($i, <$crate::token::Fn as $crate::synom::Synom>::parse) };
+    ($i:expr, for)         => { call!($i, <$crate::token::For as $crate::synom::Synom>::parse) };
+    ($i:expr, if)          => { call!($i, <$crate::token::If as $crate::synom::Synom>::parse) };
+    ($i:expr, impl)        => { call!($i, <$crate::token::Impl as $crate::synom::Synom>::parse) };
+    ($i:expr, in)          => { call!($i, <$crate::token::In as $crate::synom::Synom>::parse) };
+    ($i:expr, let)         => { call!($i, <$crate::token::Let as $crate::synom::Synom>::parse) };
+    ($i:expr, loop)        => { call!($i, <$crate::token::Loop as $crate::synom::Synom>::parse) };
+    ($i:expr, macro)       => { call!($i, <$crate::token::Macro as $crate::synom::Synom>::parse) };
+    ($i:expr, match)       => { call!($i, <$crate::token::Match as $crate::synom::Synom>::parse) };
+    ($i:expr, mod)         => { call!($i, <$crate::token::Mod as $crate::synom::Synom>::parse) };
+    ($i:expr, move)        => { call!($i, <$crate::token::Move as $crate::synom::Synom>::parse) };
+    ($i:expr, mut)         => { call!($i, <$crate::token::Mut as $crate::synom::Synom>::parse) };
+    ($i:expr, pub)         => { call!($i, <$crate::token::Pub as $crate::synom::Synom>::parse) };
+    ($i:expr, ref)         => { call!($i, <$crate::token::Ref as $crate::synom::Synom>::parse) };
+    ($i:expr, return)      => { call!($i, <$crate::token::Return as $crate::synom::Synom>::parse) };
+    ($i:expr, self)        => { call!($i, <$crate::token::Self_ as $crate::synom::Synom>::parse) };
+    ($i:expr, static)      => { call!($i, <$crate::token::Static as $crate::synom::Synom>::parse) };
+    ($i:expr, struct)      => { call!($i, <$crate::token::Struct as $crate::synom::Synom>::parse) };
+    ($i:expr, super)       => { call!($i, <$crate::token::Super as $crate::synom::Synom>::parse) };
+    ($i:expr, trait)       => { call!($i, <$crate::token::Trait as $crate::synom::Synom>::parse) };
+    ($i:expr, try)         => { call!($i, <$crate::token::Try as $crate::synom::Synom>::parse) };
+    ($i:expr, type)        => { call!($i, <$crate::token::Type as $crate::synom::Synom>::parse) };
+    ($i:expr, union)       => { call!($i, <$crate::token::Union as $crate::synom::Synom>::parse) };
+    ($i:expr, unsafe)      => { call!($i, <$crate::token::Unsafe as $crate::synom::Synom>::parse) };
+    ($i:expr, use)         => { call!($i, <$crate::token::Use as $crate::synom::Synom>::parse) };
+    ($i:expr, where)       => { call!($i, <$crate::token::Where as $crate::synom::Synom>::parse) };
+    ($i:expr, while)       => { call!($i, <$crate::token::While as $crate::synom::Synom>::parse) };
+    ($i:expr, yield)       => { call!($i, <$crate::token::Yield as $crate::synom::Synom>::parse) };
 }
 
 macro_rules! ident_from_token {
diff --git a/src/verbatim.rs b/src/verbatim.rs
index 8ab0603..35145d5 100644
--- a/src/verbatim.rs
+++ b/src/verbatim.rs
@@ -4,10 +4,12 @@
 use proc_macro2::TokenStream;
 use synom::PResult;
 
+#[allow(dead_code)]
 pub fn grab_cursor(cursor: Cursor) -> PResult<Cursor> {
     Ok((cursor, cursor))
 }
 
+#[allow(dead_code)]
 pub fn token_range(range: Range<Cursor>) -> TokenStream {
     let mut tts = Vec::new();
     let mut cursor = range.start;