Upgrade rust/crates/syn to 1.0.58

Test: make
Change-Id: Ie9cd9adfad50922610eabc0714e0f0eb76b9ff39
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 9fdbc5a..5f1d542 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "1c8ec7953893310c0ff10cbe27567846a0541187"
+    "sha1": "3414ed627f05dab27d951ce4868f08e3459a3fb8"
   }
 }
diff --git a/Android.bp b/Android.bp
index ba706b5..58b3e28 100644
--- a/Android.bp
+++ b/Android.bp
@@ -31,5 +31,5 @@
 
 // dependent_library ["feature_list"]
 //   proc-macro2-1.0.24 "default,proc-macro"
-//   quote-1.0.7 "default,proc-macro"
+//   quote-1.0.8 "default,proc-macro"
 //   unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index d5df327..90eccd0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "syn"
-version = "1.0.48"
+version = "1.0.58"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 include = ["/benches/**", "/build.rs", "/Cargo.toml", "/LICENSE-APACHE", "/LICENSE-MIT", "/README.md", "/src/**", "/tests/**"]
 description = "Parser for Rust source code"
@@ -24,6 +24,7 @@
 repository = "https://github.com/dtolnay/syn"
 [package.metadata.docs.rs]
 all-features = true
+rustdoc-args = ["--cfg", "doc_cfg"]
 targets = ["x86_64-unknown-linux-gnu"]
 
 [package.metadata.playground]
@@ -74,7 +75,7 @@
 version = "0"
 
 [dev-dependencies.tar]
-version = "0.4"
+version = "0.4.16"
 
 [dev-dependencies.termcolor]
 version = "1.0"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 0e17af4..e24f96a 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "syn"
-version = "1.0.48" # don't forget to update html_root_url and syn.json
+version = "1.0.58" # don't forget to update html_root_url and syn.json
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 license = "MIT OR Apache-2.0"
 description = "Parser for Rust source code"
@@ -48,7 +48,7 @@
 regex = "1.0"
 reqwest = { version = "0.10", features = ["blocking"] }
 syn-test-suite = { version = "0", path = "tests/features" }
-tar = "0.4"
+tar = "0.4.16"
 termcolor = "1.0"
 walkdir = "2.1"
 
@@ -64,6 +64,7 @@
 [package.metadata.docs.rs]
 all-features = true
 targets = ["x86_64-unknown-linux-gnu"]
+rustdoc-args = ["--cfg", "doc_cfg"]
 
 [package.metadata.playground]
 features = ["full", "visit", "visit-mut", "fold", "extra-traits"]
diff --git a/METADATA b/METADATA
index 0f019ed..6f412bb 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/syn/syn-1.0.48.crate"
+    value: "https://static.crates.io/crates/syn/syn-1.0.58.crate"
   }
-  version: "1.0.48"
+  version: "1.0.58"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2020
-    month: 10
-    day: 26
+    year: 2021
+    month: 1
+    day: 5
   }
 }
diff --git a/build.rs b/build.rs
index cf7681c..25190f4 100644
--- a/build.rs
+++ b/build.rs
@@ -15,6 +15,10 @@
         println!("cargo:rustc-cfg=syn_omit_await_from_token_macro");
     }
 
+    if compiler.minor < 39 {
+        println!("cargo:rustc-cfg=syn_no_const_vec_new");
+    }
+
     if !compiler.nightly {
         println!("cargo:rustc-cfg=syn_disable_nightly_tests");
     }
diff --git a/src/attr.rs b/src/attr.rs
index ea6ab09..1d82190 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -144,6 +144,7 @@
     /// };
     /// assert_eq!(doc, attr);
     /// ```
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Attribute {
         pub pound_token: Token![#],
         pub style: AttrStyle,
@@ -160,6 +161,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_meta(&self) -> Result<Meta> {
         fn clone_ident_segment(segment: &PathSegment) -> PathSegment {
             PathSegment {
@@ -207,6 +209,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_args<T: Parse>(&self) -> Result<T> {
         self.parse_args_with(T::parse)
     }
@@ -216,6 +219,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_args_with<F: Parser>(&self, parser: F) -> Result<F::Output> {
         let parser = |input: ParseStream| {
             let args = enter_args(self, input)?;
@@ -229,6 +233,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_outer(input: ParseStream) -> Result<Vec<Self>> {
         let mut attrs = Vec::new();
         while input.peek(Token![#]) {
@@ -242,6 +247,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_inner(input: ParseStream) -> Result<Vec<Self>> {
         let mut attrs = Vec::new();
         while input.peek(Token![#]) && input.peek2(Token![!]) {
@@ -321,6 +327,7 @@
     /// - `#![feature(proc_macro)]`
     /// - `//! # Example`
     /// - `/*! Please file an issue */`
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum AttrStyle {
         Outer,
         Inner(Token![!]),
@@ -350,10 +357,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum Meta {
         Path(Path),
 
@@ -370,6 +375,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct MetaList {
         pub path: Path,
         pub paren_token: token::Paren,
@@ -382,6 +388,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct MetaNameValue {
         pub path: Path,
         pub eq_token: Token![=],
@@ -408,6 +415,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum NestedMeta {
         /// A structured meta item, like the `Copy` in `#[derive(Copy)]` which
         /// would be a nested `Meta::Path`.
@@ -453,6 +461,7 @@
 /// #   "".parse().unwrap()
 /// }
 /// ```
+#[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
 pub type AttributeArgs = Vec<NestedMeta>;
 
 pub trait FilterAttrs<'a> {
@@ -553,6 +562,7 @@
         })
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Meta {
         fn parse(input: ParseStream) -> Result<Self> {
             let path = input.call(parse_meta_path)?;
@@ -560,6 +570,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for MetaList {
         fn parse(input: ParseStream) -> Result<Self> {
             let path = input.call(parse_meta_path)?;
@@ -567,6 +578,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for MetaNameValue {
         fn parse(input: ParseStream) -> Result<Self> {
             let path = input.call(parse_meta_path)?;
@@ -574,6 +586,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for NestedMeta {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Lit) && !(input.peek(LitBool) && input.peek2(Token![=])) {
@@ -622,6 +635,7 @@
     use proc_macro2::TokenStream;
     use quote::ToTokens;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Attribute {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.pound_token.to_tokens(tokens);
@@ -635,6 +649,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for MetaList {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.path.to_tokens(tokens);
@@ -644,6 +659,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for MetaNameValue {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.path.to_tokens(tokens);
diff --git a/src/custom_keyword.rs b/src/custom_keyword.rs
index eb9726e..a21842e 100644
--- a/src/custom_keyword.rs
+++ b/src/custom_keyword.rs
@@ -91,23 +91,23 @@
     ($ident:ident) => {
         #[allow(non_camel_case_types)]
         pub struct $ident {
-            pub span: $crate::export::Span,
+            pub span: $crate::__private::Span,
         }
 
         #[doc(hidden)]
         #[allow(dead_code, non_snake_case)]
-        pub fn $ident<__S: $crate::export::IntoSpans<[$crate::export::Span; 1]>>(
+        pub fn $ident<__S: $crate::__private::IntoSpans<[$crate::__private::Span; 1]>>(
             span: __S,
         ) -> $ident {
             $ident {
-                span: $crate::export::IntoSpans::into_spans(span)[0],
+                span: $crate::__private::IntoSpans::into_spans(span)[0],
             }
         }
 
-        impl $crate::export::Default for $ident {
+        impl $crate::__private::Default for $ident {
             fn default() -> Self {
                 $ident {
-                    span: $crate::export::Span::call_site(),
+                    span: $crate::__private::Span::call_site(),
                 }
             }
         }
@@ -127,7 +127,7 @@
     ($ident:ident) => {
         // For peek.
         impl $crate::token::CustomToken for $ident {
-            fn peek(cursor: $crate::buffer::Cursor) -> $crate::export::bool {
+            fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool {
                 if let Some((ident, _rest)) = cursor.ident() {
                     ident == stringify!($ident)
                 } else {
@@ -135,7 +135,7 @@
                 }
             }
 
-            fn display() -> &'static $crate::export::str {
+            fn display() -> &'static $crate::__private::str {
                 concat!("`", stringify!($ident), "`")
             }
         }
@@ -143,12 +143,12 @@
         impl $crate::parse::Parse for $ident {
             fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> {
                 input.step(|cursor| {
-                    if let $crate::export::Some((ident, rest)) = cursor.ident() {
+                    if let $crate::__private::Some((ident, rest)) = cursor.ident() {
                         if ident == stringify!($ident) {
-                            return $crate::export::Ok(($ident { span: ident.span() }, rest));
+                            return $crate::__private::Ok(($ident { span: ident.span() }, rest));
                         }
                     }
-                    $crate::export::Err(cursor.error(concat!(
+                    $crate::__private::Err(cursor.error(concat!(
                         "expected `",
                         stringify!($ident),
                         "`"
@@ -173,10 +173,10 @@
 #[macro_export]
 macro_rules! impl_to_tokens_for_custom_keyword {
     ($ident:ident) => {
-        impl $crate::export::ToTokens for $ident {
-            fn to_tokens(&self, tokens: &mut $crate::export::TokenStream2) {
+        impl $crate::__private::ToTokens for $ident {
+            fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) {
                 let ident = $crate::Ident::new(stringify!($ident), self.span);
-                $crate::export::TokenStreamExt::append(tokens, ident);
+                $crate::__private::TokenStreamExt::append(tokens, ident);
             }
         }
     };
@@ -196,9 +196,9 @@
 #[macro_export]
 macro_rules! impl_clone_for_custom_keyword {
     ($ident:ident) => {
-        impl $crate::export::Copy for $ident {}
+        impl $crate::__private::Copy for $ident {}
 
-        impl $crate::export::Clone for $ident {
+        impl $crate::__private::Clone for $ident {
             fn clone(&self) -> Self {
                 *self
             }
@@ -220,25 +220,25 @@
 #[macro_export]
 macro_rules! impl_extra_traits_for_custom_keyword {
     ($ident:ident) => {
-        impl $crate::export::Debug for $ident {
-            fn fmt(&self, f: &mut $crate::export::Formatter) -> $crate::export::fmt::Result {
-                $crate::export::Formatter::write_str(
+        impl $crate::__private::Debug for $ident {
+            fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::fmt::Result {
+                $crate::__private::Formatter::write_str(
                     f,
                     concat!("Keyword [", stringify!($ident), "]"),
                 )
             }
         }
 
-        impl $crate::export::Eq for $ident {}
+        impl $crate::__private::Eq for $ident {}
 
-        impl $crate::export::PartialEq for $ident {
-            fn eq(&self, _other: &Self) -> $crate::export::bool {
+        impl $crate::__private::PartialEq for $ident {
+            fn eq(&self, _other: &Self) -> $crate::__private::bool {
                 true
             }
         }
 
-        impl $crate::export::Hash for $ident {
-            fn hash<__H: $crate::export::Hasher>(&self, _state: &mut __H) {}
+        impl $crate::__private::Hash for $ident {
+            fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {}
         }
     };
 }
diff --git a/src/custom_punctuation.rs b/src/custom_punctuation.rs
index 2156ec2..128185d 100644
--- a/src/custom_punctuation.rs
+++ b/src/custom_punctuation.rs
@@ -83,18 +83,18 @@
 
         #[doc(hidden)]
         #[allow(dead_code, non_snake_case)]
-        pub fn $ident<__S: $crate::export::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>(
+        pub fn $ident<__S: $crate::__private::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>(
             spans: __S,
         ) -> $ident {
             let _validate_len = 0 $(+ $crate::custom_punctuation_len!(strict, $tt))*;
             $ident {
-                spans: $crate::export::IntoSpans::into_spans(spans)
+                spans: $crate::__private::IntoSpans::into_spans(spans)
             }
         }
 
-        impl $crate::export::Default for $ident {
+        impl $crate::__private::Default for $ident {
             fn default() -> Self {
-                $ident($crate::export::Span::call_site())
+                $ident($crate::__private::Span::call_site())
             }
         }
 
@@ -116,7 +116,7 @@
                 $crate::token::parsing::peek_punct(cursor, $crate::stringify_punct!($($tt)+))
             }
 
-            fn display() -> &'static $crate::export::str {
+            fn display() -> &'static $crate::__private::str {
                 concat!("`", $crate::stringify_punct!($($tt)+), "`")
             }
         }
@@ -145,8 +145,8 @@
 #[macro_export]
 macro_rules! impl_to_tokens_for_custom_punctuation {
     ($ident:ident, $($tt:tt)+) => {
-        impl $crate::export::ToTokens for $ident {
-            fn to_tokens(&self, tokens: &mut $crate::export::TokenStream2) {
+        impl $crate::__private::ToTokens for $ident {
+            fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) {
                 $crate::token::printing::punct($crate::stringify_punct!($($tt)+), &self.spans, tokens)
             }
         }
@@ -167,9 +167,9 @@
 #[macro_export]
 macro_rules! impl_clone_for_custom_punctuation {
     ($ident:ident, $($tt:tt)+) => {
-        impl $crate::export::Copy for $ident {}
+        impl $crate::__private::Copy for $ident {}
 
-        impl $crate::export::Clone for $ident {
+        impl $crate::__private::Clone for $ident {
             fn clone(&self) -> Self {
                 *self
             }
@@ -191,22 +191,22 @@
 #[macro_export]
 macro_rules! impl_extra_traits_for_custom_punctuation {
     ($ident:ident, $($tt:tt)+) => {
-        impl $crate::export::Debug for $ident {
-            fn fmt(&self, f: &mut $crate::export::Formatter) -> $crate::export::fmt::Result {
-                $crate::export::Formatter::write_str(f, stringify!($ident))
+        impl $crate::__private::Debug for $ident {
+            fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::fmt::Result {
+                $crate::__private::Formatter::write_str(f, stringify!($ident))
             }
         }
 
-        impl $crate::export::Eq for $ident {}
+        impl $crate::__private::Eq for $ident {}
 
-        impl $crate::export::PartialEq for $ident {
-            fn eq(&self, _other: &Self) -> $crate::export::bool {
+        impl $crate::__private::PartialEq for $ident {
+            fn eq(&self, _other: &Self) -> $crate::__private::bool {
                 true
             }
         }
 
-        impl $crate::export::Hash for $ident {
-            fn hash<__H: $crate::export::Hasher>(&self, _state: &mut __H) {}
+        impl $crate::__private::Hash for $ident {
+            fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {}
         }
     };
 }
@@ -224,7 +224,7 @@
 #[macro_export]
 macro_rules! custom_punctuation_repr {
     ($($tt:tt)+) => {
-        [$crate::export::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+]
+        [$crate::__private::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+]
     };
 }
 
diff --git a/src/data.rs b/src/data.rs
index bb6a854..731f5a0 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -6,6 +6,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Variant {
         /// Attributes tagged on the variant.
         pub attrs: Vec<Attribute>,
@@ -31,10 +32,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum Fields {
         /// Named fields of a struct or struct variant such as `Point { x: f64,
         /// y: f64 }`.
@@ -54,6 +53,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct FieldsNamed {
         pub brace_token: token::Brace,
         pub named: Punctuated<Field, Token![,]>,
@@ -65,6 +65,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct FieldsUnnamed {
         pub paren_token: token::Paren,
         pub unnamed: Punctuated<Field, Token![,]>,
@@ -149,6 +150,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Field {
         /// Attributes tagged on the field.
         pub attrs: Vec<Attribute>,
@@ -179,10 +181,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum Visibility {
         /// A public visibility level: `pub`.
         Public(VisPublic),
@@ -204,6 +204,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct VisPublic {
         pub pub_token: Token![pub],
     }
@@ -214,6 +215,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct VisCrate {
         pub crate_token: Token![crate],
     }
@@ -225,6 +227,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct VisRestricted {
         pub pub_token: Token![pub],
         pub paren_token: token::Paren,
@@ -240,6 +243,7 @@
     use crate::parse::discouraged::Speculative;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Variant {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -269,6 +273,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for FieldsNamed {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -279,6 +284,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for FieldsUnnamed {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -291,6 +297,7 @@
 
     impl Field {
         /// Parses a named (braced struct) field.
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn parse_named(input: ParseStream) -> Result<Self> {
             Ok(Field {
                 attrs: input.call(Attribute::parse_outer)?,
@@ -302,6 +309,7 @@
         }
 
         /// Parses an unnamed (tuple struct) field.
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn parse_unnamed(input: ParseStream) -> Result<Self> {
             Ok(Field {
                 attrs: input.call(Attribute::parse_outer)?,
@@ -313,6 +321,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Visibility {
         fn parse(input: ParseStream) -> Result<Self> {
             // Recognize an empty None-delimited group, as produced by a $:vis
@@ -408,6 +417,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Variant {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(&self.attrs);
@@ -420,6 +430,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for FieldsNamed {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.brace_token.surround(tokens, |tokens| {
@@ -428,6 +439,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for FieldsUnnamed {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.paren_token.surround(tokens, |tokens| {
@@ -436,6 +448,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Field {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(&self.attrs);
@@ -448,18 +461,21 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for VisPublic {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.pub_token.to_tokens(tokens)
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for VisCrate {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.crate_token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for VisRestricted {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.pub_token.to_tokens(tokens);
diff --git a/src/derive.rs b/src/derive.rs
index cbfd0da..af9bb91 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -5,6 +5,7 @@
     /// Data structure sent to a `proc_macro_derive` macro.
     ///
     /// *This type is available only if Syn is built with the `"derive"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
     pub struct DeriveInput {
         /// Attributes tagged on the whole struct or enum.
         pub attrs: Vec<Attribute>,
@@ -32,10 +33,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
     pub enum Data {
         /// A struct input to a `proc_macro_derive` macro.
         Struct(DataStruct),
@@ -55,6 +54,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
     pub struct DataStruct {
         pub struct_token: Token![struct],
         pub fields: Fields,
@@ -67,6 +67,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
     pub struct DataEnum {
         pub enum_token: Token![enum],
         pub brace_token: token::Brace,
@@ -79,6 +80,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
     pub struct DataUnion {
         pub union_token: Token![union],
         pub fields: FieldsNamed,
@@ -90,6 +92,7 @@
     use super::*;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for DeriveInput {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -225,6 +228,7 @@
     use proc_macro2::TokenStream;
     use quote::ToTokens;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for DeriveInput {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             for attr in self.attrs.outer() {
diff --git a/src/error.rs b/src/error.rs
index 8d65a1b..6051f3b 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -23,7 +23,7 @@
 /// [`compile_error!`] in the generated code. This produces a better diagnostic
 /// message than simply panicking the macro.
 ///
-/// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
+/// [`compile_error!`]: std::compile_error!
 ///
 /// When parsing macro input, the [`parse_macro_input!`] macro handles the
 /// conversion to `compile_error!` automatically.
@@ -189,7 +189,7 @@
     /// The [`parse_macro_input!`] macro provides a convenient way to invoke
     /// this method correctly in a procedural macro.
     ///
-    /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
+    /// [`compile_error!`]: std::compile_error!
     pub fn to_compile_error(&self) -> TokenStream {
         self.messages
             .iter()
@@ -197,6 +197,42 @@
             .collect()
     }
 
+    /// Render the error as an invocation of [`compile_error!`].
+    ///
+    /// [`compile_error!`]: std::compile_error!
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # extern crate proc_macro;
+    /// #
+    /// use proc_macro::TokenStream;
+    /// use syn::{parse_macro_input, DeriveInput, Error};
+    ///
+    /// # const _: &str = stringify! {
+    /// #[proc_macro_derive(MyTrait)]
+    /// # };
+    /// pub fn derive_my_trait(input: TokenStream) -> TokenStream {
+    ///     let input = parse_macro_input!(input as DeriveInput);
+    ///     my_trait::expand(input)
+    ///         .unwrap_or_else(Error::into_compile_error)
+    ///         .into()
+    /// }
+    ///
+    /// mod my_trait {
+    ///     use proc_macro2::TokenStream;
+    ///     use syn::{DeriveInput, Result};
+    ///
+    ///     pub(crate) fn expand(input: DeriveInput) -> Result<TokenStream> {
+    ///         /* ... */
+    ///         # unimplemented!()
+    ///     }
+    /// }
+    /// ```
+    pub fn into_compile_error(self) -> TokenStream {
+        self.to_compile_error()
+    }
+
     /// Add another error message to self such that when `to_compile_error()` is
     /// called, both errors will be emitted together.
     pub fn combine(&mut self, another: Error) {
@@ -309,11 +345,7 @@
     }
 }
 
-impl std::error::Error for Error {
-    fn description(&self) -> &str {
-        "parse error"
-    }
-}
+impl std::error::Error for Error {}
 
 impl From<LexError> for Error {
     fn from(err: LexError) -> Self {
diff --git a/src/expr.rs b/src/expr.rs
index 45dd0ce..8417475 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -86,6 +86,7 @@
     /// A sign that you may not be choosing the right variable names is if you
     /// see names getting repeated in your code, like accessing
     /// `receiver.receiver` or `pat.pat` or `cond.cond`.
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum Expr {
         /// A slice literal expression: `[a, b, c, d]`.
         Array(ExprArray),
@@ -232,6 +233,7 @@
     /// A slice literal expression: `[a, b, c, d]`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprArray #full {
         pub attrs: Vec<Attribute>,
         pub bracket_token: token::Bracket,
@@ -243,6 +245,7 @@
     /// An assignment expression: `a = compute()`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprAssign #full {
         pub attrs: Vec<Attribute>,
         pub left: Box<Expr>,
@@ -255,6 +258,7 @@
     /// A compound assignment expression: `counter += 1`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprAssignOp #full {
         pub attrs: Vec<Attribute>,
         pub left: Box<Expr>,
@@ -267,6 +271,7 @@
     /// An async block: `async { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprAsync #full {
         pub attrs: Vec<Attribute>,
         pub async_token: Token![async],
@@ -279,6 +284,7 @@
     /// An await expression: `fut.await`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprAwait #full {
         pub attrs: Vec<Attribute>,
         pub base: Box<Expr>,
@@ -292,6 +298,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprBinary {
         pub attrs: Vec<Attribute>,
         pub left: Box<Expr>,
@@ -304,6 +311,7 @@
     /// A blocked scope: `{ ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprBlock #full {
         pub attrs: Vec<Attribute>,
         pub label: Option<Label>,
@@ -315,6 +323,7 @@
     /// A box expression: `box f`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprBox #full {
         pub attrs: Vec<Attribute>,
         pub box_token: Token![box],
@@ -327,6 +336,7 @@
     /// expression.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprBreak #full {
         pub attrs: Vec<Attribute>,
         pub break_token: Token![break],
@@ -340,6 +350,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprCall {
         pub attrs: Vec<Attribute>,
         pub func: Box<Expr>,
@@ -353,6 +364,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprCast {
         pub attrs: Vec<Attribute>,
         pub expr: Box<Expr>,
@@ -365,6 +377,7 @@
     /// A closure expression: `|a, b| a + b`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprClosure #full {
         pub attrs: Vec<Attribute>,
         pub asyncness: Option<Token![async]>,
@@ -382,6 +395,7 @@
     /// A `continue`, with an optional label.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprContinue #full {
         pub attrs: Vec<Attribute>,
         pub continue_token: Token![continue],
@@ -394,6 +408,7 @@
     /// field (`obj.0`).
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprField {
         pub attrs: Vec<Attribute>,
         pub base: Box<Expr>,
@@ -406,6 +421,7 @@
     /// A for loop: `for pat in expr { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprForLoop #full {
         pub attrs: Vec<Attribute>,
         pub label: Option<Label>,
@@ -425,6 +441,7 @@
     /// `TokenStream`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprGroup #full {
         pub attrs: Vec<Attribute>,
         pub group_token: token::Group,
@@ -440,6 +457,7 @@
     /// expression, not any of the other types of expression.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprIf #full {
         pub attrs: Vec<Attribute>,
         pub if_token: Token![if],
@@ -454,6 +472,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprIndex {
         pub attrs: Vec<Attribute>,
         pub expr: Box<Expr>,
@@ -466,6 +485,7 @@
     /// A `let` guard: `let Some(x) = opt`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprLet #full {
         pub attrs: Vec<Attribute>,
         pub let_token: Token![let],
@@ -480,6 +500,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprLit {
         pub attrs: Vec<Attribute>,
         pub lit: Lit,
@@ -490,6 +511,7 @@
     /// Conditionless loop: `loop { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprLoop #full {
         pub attrs: Vec<Attribute>,
         pub label: Option<Label>,
@@ -502,6 +524,7 @@
     /// A macro invocation expression: `format!("{}", q)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprMacro #full {
         pub attrs: Vec<Attribute>,
         pub mac: Macro,
@@ -512,6 +535,7 @@
     /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprMatch #full {
         pub attrs: Vec<Attribute>,
         pub match_token: Token![match],
@@ -525,6 +549,7 @@
     /// A method call expression: `x.foo::<T>(a, b)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprMethodCall #full {
         pub attrs: Vec<Attribute>,
         pub receiver: Box<Expr>,
@@ -540,6 +565,7 @@
     /// A parenthesized expression: `(a + b)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprParen {
         pub attrs: Vec<Attribute>,
         pub paren_token: token::Paren,
@@ -555,6 +581,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprPath {
         pub attrs: Vec<Attribute>,
         pub qself: Option<QSelf>,
@@ -566,6 +593,7 @@
     /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprRange #full {
         pub attrs: Vec<Attribute>,
         pub from: Option<Box<Expr>>,
@@ -578,6 +606,7 @@
     /// A referencing operation: `&a` or `&mut a`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprReference #full {
         pub attrs: Vec<Attribute>,
         pub and_token: Token![&],
@@ -591,6 +620,7 @@
     /// An array literal constructed from one repeated element: `[0u8; N]`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprRepeat #full {
         pub attrs: Vec<Attribute>,
         pub bracket_token: token::Bracket,
@@ -604,6 +634,7 @@
     /// A `return`, with an optional value to be returned.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprReturn #full {
         pub attrs: Vec<Attribute>,
         pub return_token: Token![return],
@@ -618,6 +649,7 @@
     /// 1, b: 1, ..rest }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprStruct #full {
         pub attrs: Vec<Attribute>,
         pub path: Path,
@@ -632,6 +664,7 @@
     /// A try-expression: `expr?`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprTry #full {
         pub attrs: Vec<Attribute>,
         pub expr: Box<Expr>,
@@ -643,6 +676,7 @@
     /// A try block: `try { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprTryBlock #full {
         pub attrs: Vec<Attribute>,
         pub try_token: Token![try],
@@ -654,6 +688,7 @@
     /// A tuple expression: `(a, b, c, d)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprTuple #full {
         pub attrs: Vec<Attribute>,
         pub paren_token: token::Paren,
@@ -665,6 +700,7 @@
     /// A type ascription expression: `foo: f64`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprType #full {
         pub attrs: Vec<Attribute>,
         pub expr: Box<Expr>,
@@ -678,6 +714,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ExprUnary {
         pub attrs: Vec<Attribute>,
         pub op: UnOp,
@@ -689,6 +726,7 @@
     /// An unsafe block: `unsafe { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprUnsafe #full {
         pub attrs: Vec<Attribute>,
         pub unsafe_token: Token![unsafe],
@@ -700,6 +738,7 @@
     /// A while loop: `while expr { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprWhile #full {
         pub attrs: Vec<Attribute>,
         pub label: Option<Label>,
@@ -713,6 +752,7 @@
     /// A yield expression: `yield expr`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ExprYield #full {
         pub attrs: Vec<Attribute>,
         pub yield_token: Token![yield],
@@ -775,6 +815,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum Member {
         /// A named field like `self.x`.
         Named(Ident),
@@ -826,6 +867,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Index {
         pub index: u32,
         pub span: Span,
@@ -873,6 +915,7 @@
     /// `parse::<u64>()`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct MethodTurbofish {
         pub colon2_token: Token![::],
         pub lt_token: Token![<],
@@ -886,6 +929,7 @@
     /// An individual generic argument to a method, like `T`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum GenericMethodArgument {
         /// A type argument.
         Type(Type),
@@ -902,6 +946,7 @@
     /// A field-value pair in a struct literal.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct FieldValue {
         /// Attributes tagged on the field.
         pub attrs: Vec<Attribute>,
@@ -923,6 +968,7 @@
     /// A lifetime labeling a `for`, `while`, or `loop`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct Label {
         pub name: Lifetime,
         pub colon_token: Token![:],
@@ -950,6 +996,7 @@
     /// ```
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct Arm {
         pub attrs: Vec<Attribute>,
         pub pat: Pat,
@@ -965,6 +1012,7 @@
     /// Limit types of a range, inclusive or exclusive.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum RangeLimits {
         /// Inclusive at the beginning, exclusive at the end.
         HalfOpen(Token![..]),
@@ -996,6 +1044,8 @@
     use super::*;
     use crate::parse::{Parse, ParseStream, Result};
     use crate::path;
+    #[cfg(feature = "full")]
+    use proc_macro2::TokenTree;
     use std::cmp::Ordering;
 
     crate::custom_keyword!(raw);
@@ -1054,6 +1104,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Expr {
         fn parse(input: ParseStream) -> Result<Self> {
             ambiguous_expr(input, AllowStruct(true))
@@ -1142,6 +1193,7 @@
         /// implying tighter precedence for `..` than struct init, a
         /// contradiction.
         #[cfg(feature = "full")]
+        #[cfg_attr(doc_cfg, doc(cfg(all(feature = "full", feature = "parsing"))))]
         pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> {
             ambiguous_expr(input, AllowStruct(false))
         }
@@ -1668,10 +1720,16 @@
             input.call(expr_yield).map(Expr::Yield)
         } else if input.peek(Token![unsafe]) {
             input.call(expr_unsafe).map(Expr::Unsafe)
+        } else if input.peek(Token![const]) {
+            input.call(expr_const).map(Expr::Verbatim)
         } else if input.peek(token::Brace) {
             input.call(expr_block).map(Expr::Block)
         } else if input.peek(Token![..]) {
             expr_range(input, allow_struct).map(Expr::Range)
+        } else if input.peek(Token![_]) {
+            Ok(Expr::Verbatim(TokenStream::from(
+                input.parse::<TokenTree>()?,
+            )))
         } else if input.peek(Lifetime) {
             let the_label: Label = input.parse()?;
             let mut expr = if input.peek(Token![while]) {
@@ -1862,6 +1920,8 @@
             Expr::TryBlock(input.call(expr_try_block)?)
         } else if input.peek(Token![unsafe]) {
             Expr::Unsafe(input.call(expr_unsafe)?)
+        } else if input.peek(Token![const]) {
+            Expr::Verbatim(input.call(expr_const)?)
         } else if input.peek(token::Brace) {
             Expr::Block(input.call(expr_block)?)
         } else {
@@ -1889,6 +1949,7 @@
         Ok(expr)
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprLit {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ExprLit {
@@ -1945,6 +2006,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprIf {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1985,6 +2047,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprForLoop {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -2014,6 +2077,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprLoop {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -2035,6 +2099,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprMatch {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -2068,6 +2133,7 @@
         ) => {
             $(
                 #[cfg(all(feature = "full", feature = "printing"))]
+                #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
                 impl Parse for $expr_type {
                     fn parse(input: ParseStream) -> Result<Self> {
                         let mut expr: Expr = input.parse()?;
@@ -2244,6 +2310,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprWhile {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -2267,6 +2334,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Label {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(Label {
@@ -2277,6 +2345,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Option<Label> {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Lifetime) {
@@ -2339,6 +2408,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for FieldValue {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -2387,7 +2457,11 @@
                     path,
                     fields,
                     dot2_token: Some(content.parse()?),
-                    rest: Some(Box::new(content.parse()?)),
+                    rest: if content.is_empty() {
+                        None
+                    } else {
+                        Some(Box::new(content.parse()?))
+                    },
                 });
             }
 
@@ -2426,6 +2500,19 @@
     }
 
     #[cfg(feature = "full")]
+    pub(crate) fn expr_const(input: ParseStream) -> Result<TokenStream> {
+        let begin = input.fork();
+        input.parse::<Token![const]>()?;
+
+        let content;
+        braced!(content in input);
+        content.call(Attribute::parse_inner)?;
+        content.call(Block::parse_within)?;
+
+        Ok(verbatim::between(begin, input))
+    }
+
+    #[cfg(feature = "full")]
     pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
         let label: Option<Label> = input.parse()?;
 
@@ -2463,6 +2550,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for RangeLimits {
         fn parse(input: ParseStream) -> Result<Self> {
             let lookahead = input.lookahead1();
@@ -2479,6 +2567,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ExprPath {
         fn parse(input: ParseStream) -> Result<Self> {
             #[cfg(not(feature = "full"))]
@@ -2492,6 +2581,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Member {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Ident) {
@@ -2505,6 +2595,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Arm {
         fn parse(input: ParseStream) -> Result<Arm> {
             let requires_comma;
@@ -2537,6 +2628,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Index {
         fn parse(input: ParseStream) -> Result<Self> {
             let lit: LitInt = input.parse()?;
@@ -2590,8 +2682,6 @@
     use super::*;
     #[cfg(feature = "full")]
     use crate::attr::FilterAttrs;
-    #[cfg(feature = "full")]
-    use crate::print::TokensOrDefault;
     use proc_macro2::{Literal, TokenStream};
     use quote::{ToTokens, TokenStreamExt};
 
@@ -2625,6 +2715,7 @@
     fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprBox {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2634,6 +2725,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprArray {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2644,6 +2736,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprCall {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2655,6 +2748,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprMethodCall {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2669,6 +2763,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for MethodTurbofish {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.colon2_token.to_tokens(tokens);
@@ -2679,6 +2774,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for GenericMethodArgument {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -2689,6 +2785,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprTuple {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2704,6 +2801,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprBinary {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2713,6 +2811,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprUnary {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2721,6 +2820,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprLit {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2728,6 +2828,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprCast {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2738,6 +2839,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2768,6 +2870,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprLet {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2779,6 +2882,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprIf {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2790,6 +2894,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprWhile {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2804,6 +2909,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprForLoop {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2820,6 +2926,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprLoop {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2833,6 +2940,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprMatch {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2854,6 +2962,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprAsync {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2864,6 +2973,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprAwait {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2874,6 +2984,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprTryBlock {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2883,6 +2994,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprYield {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2892,6 +3004,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprClosure {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2907,6 +3020,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprUnsafe {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2919,6 +3033,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprBlock {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2931,6 +3046,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprAssign {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2941,6 +3057,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprAssignOp {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2950,6 +3067,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprField {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2959,6 +3077,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Member {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -2968,6 +3087,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Index {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
@@ -2976,6 +3096,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprIndex {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2987,6 +3108,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprRange {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -2999,6 +3121,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprPath {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3007,6 +3130,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprReference {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3017,6 +3141,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprBreak {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3027,6 +3152,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprContinue {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3036,6 +3162,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprReturn {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3045,6 +3172,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3053,6 +3181,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprStruct {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3060,15 +3189,18 @@
             self.brace_token.surround(tokens, |tokens| {
                 inner_attrs_to_tokens(&self.attrs, tokens);
                 self.fields.to_tokens(tokens);
-                if self.rest.is_some() {
-                    TokensOrDefault(&self.dot2_token).to_tokens(tokens);
-                    self.rest.to_tokens(tokens);
+                if let Some(dot2_token) = &self.dot2_token {
+                    dot2_token.to_tokens(tokens);
+                } else if self.rest.is_some() {
+                    Token![..](Span::call_site()).to_tokens(tokens);
                 }
+                self.rest.to_tokens(tokens);
             })
         }
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprRepeat {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3082,6 +3214,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprGroup {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3091,6 +3224,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprParen {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3102,6 +3236,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ExprTry {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3111,6 +3246,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Label {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.name.to_tokens(tokens);
@@ -3119,6 +3255,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for FieldValue {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             outer_attrs_to_tokens(&self.attrs, tokens);
@@ -3131,6 +3268,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Arm {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(&self.attrs);
diff --git a/src/file.rs b/src/file.rs
index 4a1a819..280484f 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -51,24 +51,33 @@
     ///     shebang: None,
     ///     attrs: [],
     ///     items: [
-    ///         ExternCrate(
-    ///             ItemExternCrate {
+    ///         Use(
+    ///             ItemUse {
     ///                 attrs: [],
     ///                 vis: Inherited,
-    ///                 extern_token: Extern,
-    ///                 crate_token: Crate,
-    ///                 ident: Ident {
-    ///                     term: Term(
-    ///                         "syn"
-    ///                     ),
-    ///                     span: Span
-    ///                 },
-    ///                 rename: None,
-    ///                 semi_token: Semi
-    ///             }
+    ///                 use_token: Use,
+    ///                 leading_colon: None,
+    ///                 tree: Path(
+    ///                     UsePath {
+    ///                         ident: Ident(
+    ///                             std,
+    ///                         ),
+    ///                         colon2_token: Colon2,
+    ///                         tree: Name(
+    ///                             UseName {
+    ///                                 ident: Ident(
+    ///                                     env,
+    ///                                 ),
+    ///                             },
+    ///                         ),
+    ///                     },
+    ///                 ),
+    ///                 semi_token: Semi,
+    ///             },
     ///         ),
     /// ...
     /// ```
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct File {
         pub shebang: Option<String>,
         pub attrs: Vec<Attribute>,
@@ -81,6 +90,7 @@
     use super::*;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for File {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(File {
@@ -105,6 +115,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for File {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.inner());
diff --git a/src/gen/clone.rs b/src/gen/clone.rs
index bea3887..37670f2 100644
--- a/src/gen/clone.rs
+++ b/src/gen/clone.rs
@@ -4,6 +4,7 @@
 #![allow(clippy::clone_on_copy, clippy::expl_impl_clone_on_copy)]
 use crate::*;
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Abi {
     fn clone(&self) -> Self {
         Abi {
@@ -13,6 +14,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for AngleBracketedGenericArguments {
     fn clone(&self) -> Self {
         AngleBracketedGenericArguments {
@@ -24,6 +26,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Arm {
     fn clone(&self) -> Self {
         Arm {
@@ -37,14 +40,17 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Copy for AttrStyle {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for AttrStyle {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Attribute {
     fn clone(&self) -> Self {
         Attribute {
@@ -57,6 +63,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for BareFnArg {
     fn clone(&self) -> Self {
         BareFnArg {
@@ -67,14 +74,17 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Copy for BinOp {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for BinOp {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Binding {
     fn clone(&self) -> Self {
         Binding {
@@ -85,6 +95,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Block {
     fn clone(&self) -> Self {
         Block {
@@ -94,6 +105,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for BoundLifetimes {
     fn clone(&self) -> Self {
         BoundLifetimes {
@@ -105,6 +117,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ConstParam {
     fn clone(&self) -> Self {
         ConstParam {
@@ -119,6 +132,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Constraint {
     fn clone(&self) -> Self {
         Constraint {
@@ -129,6 +143,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Data {
     fn clone(&self) -> Self {
         match self {
@@ -139,6 +154,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for DataEnum {
     fn clone(&self) -> Self {
         DataEnum {
@@ -149,6 +165,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for DataStruct {
     fn clone(&self) -> Self {
         DataStruct {
@@ -159,6 +176,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for DataUnion {
     fn clone(&self) -> Self {
         DataUnion {
@@ -168,6 +186,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for DeriveInput {
     fn clone(&self) -> Self {
         DeriveInput {
@@ -180,6 +199,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Expr {
     fn clone(&self) -> Self {
         match self {
@@ -258,6 +278,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprArray {
     fn clone(&self) -> Self {
         ExprArray {
@@ -268,6 +289,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprAssign {
     fn clone(&self) -> Self {
         ExprAssign {
@@ -279,6 +301,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprAssignOp {
     fn clone(&self) -> Self {
         ExprAssignOp {
@@ -290,6 +313,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprAsync {
     fn clone(&self) -> Self {
         ExprAsync {
@@ -301,6 +325,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprAwait {
     fn clone(&self) -> Self {
         ExprAwait {
@@ -312,6 +337,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprBinary {
     fn clone(&self) -> Self {
         ExprBinary {
@@ -323,6 +349,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprBlock {
     fn clone(&self) -> Self {
         ExprBlock {
@@ -333,6 +360,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprBox {
     fn clone(&self) -> Self {
         ExprBox {
@@ -343,6 +371,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprBreak {
     fn clone(&self) -> Self {
         ExprBreak {
@@ -354,6 +383,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprCall {
     fn clone(&self) -> Self {
         ExprCall {
@@ -365,6 +395,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprCast {
     fn clone(&self) -> Self {
         ExprCast {
@@ -376,6 +407,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprClosure {
     fn clone(&self) -> Self {
         ExprClosure {
@@ -392,6 +424,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprContinue {
     fn clone(&self) -> Self {
         ExprContinue {
@@ -402,6 +435,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprField {
     fn clone(&self) -> Self {
         ExprField {
@@ -413,6 +447,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprForLoop {
     fn clone(&self) -> Self {
         ExprForLoop {
@@ -427,6 +462,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprGroup {
     fn clone(&self) -> Self {
         ExprGroup {
@@ -437,6 +473,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprIf {
     fn clone(&self) -> Self {
         ExprIf {
@@ -449,6 +486,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprIndex {
     fn clone(&self) -> Self {
         ExprIndex {
@@ -460,6 +498,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprLet {
     fn clone(&self) -> Self {
         ExprLet {
@@ -472,6 +511,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprLit {
     fn clone(&self) -> Self {
         ExprLit {
@@ -481,6 +521,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprLoop {
     fn clone(&self) -> Self {
         ExprLoop {
@@ -492,6 +533,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprMacro {
     fn clone(&self) -> Self {
         ExprMacro {
@@ -501,6 +543,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprMatch {
     fn clone(&self) -> Self {
         ExprMatch {
@@ -513,6 +556,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprMethodCall {
     fn clone(&self) -> Self {
         ExprMethodCall {
@@ -527,6 +571,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprParen {
     fn clone(&self) -> Self {
         ExprParen {
@@ -537,6 +582,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprPath {
     fn clone(&self) -> Self {
         ExprPath {
@@ -547,6 +593,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprRange {
     fn clone(&self) -> Self {
         ExprRange {
@@ -558,6 +605,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprReference {
     fn clone(&self) -> Self {
         ExprReference {
@@ -570,6 +618,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprRepeat {
     fn clone(&self) -> Self {
         ExprRepeat {
@@ -582,6 +631,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprReturn {
     fn clone(&self) -> Self {
         ExprReturn {
@@ -592,6 +642,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprStruct {
     fn clone(&self) -> Self {
         ExprStruct {
@@ -605,6 +656,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprTry {
     fn clone(&self) -> Self {
         ExprTry {
@@ -615,6 +667,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprTryBlock {
     fn clone(&self) -> Self {
         ExprTryBlock {
@@ -625,6 +678,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprTuple {
     fn clone(&self) -> Self {
         ExprTuple {
@@ -635,6 +689,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprType {
     fn clone(&self) -> Self {
         ExprType {
@@ -646,6 +701,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprUnary {
     fn clone(&self) -> Self {
         ExprUnary {
@@ -656,6 +712,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprUnsafe {
     fn clone(&self) -> Self {
         ExprUnsafe {
@@ -666,6 +723,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprWhile {
     fn clone(&self) -> Self {
         ExprWhile {
@@ -678,6 +736,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ExprYield {
     fn clone(&self) -> Self {
         ExprYield {
@@ -688,6 +747,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Field {
     fn clone(&self) -> Self {
         Field {
@@ -700,6 +760,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for FieldPat {
     fn clone(&self) -> Self {
         FieldPat {
@@ -711,6 +772,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for FieldValue {
     fn clone(&self) -> Self {
         FieldValue {
@@ -722,6 +784,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Fields {
     fn clone(&self) -> Self {
         match self {
@@ -732,6 +795,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for FieldsNamed {
     fn clone(&self) -> Self {
         FieldsNamed {
@@ -741,6 +805,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for FieldsUnnamed {
     fn clone(&self) -> Self {
         FieldsUnnamed {
@@ -750,6 +815,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for File {
     fn clone(&self) -> Self {
         File {
@@ -760,6 +826,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for FnArg {
     fn clone(&self) -> Self {
         match self {
@@ -769,6 +836,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ForeignItem {
     fn clone(&self) -> Self {
         match self {
@@ -782,6 +850,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ForeignItemFn {
     fn clone(&self) -> Self {
         ForeignItemFn {
@@ -793,6 +862,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ForeignItemMacro {
     fn clone(&self) -> Self {
         ForeignItemMacro {
@@ -803,6 +873,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ForeignItemStatic {
     fn clone(&self) -> Self {
         ForeignItemStatic {
@@ -818,6 +889,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ForeignItemType {
     fn clone(&self) -> Self {
         ForeignItemType {
@@ -830,6 +902,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for GenericArgument {
     fn clone(&self) -> Self {
         match self {
@@ -842,6 +915,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for GenericMethodArgument {
     fn clone(&self) -> Self {
         match self {
@@ -851,6 +925,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for GenericParam {
     fn clone(&self) -> Self {
         match self {
@@ -861,6 +936,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Generics {
     fn clone(&self) -> Self {
         Generics {
@@ -872,6 +948,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ImplItem {
     fn clone(&self) -> Self {
         match self {
@@ -885,6 +962,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ImplItemConst {
     fn clone(&self) -> Self {
         ImplItemConst {
@@ -902,6 +980,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ImplItemMacro {
     fn clone(&self) -> Self {
         ImplItemMacro {
@@ -912,6 +991,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ImplItemMethod {
     fn clone(&self) -> Self {
         ImplItemMethod {
@@ -924,6 +1004,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ImplItemType {
     fn clone(&self) -> Self {
         ImplItemType {
@@ -940,6 +1021,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Index {
     fn clone(&self) -> Self {
         Index {
@@ -949,6 +1031,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Item {
     fn clone(&self) -> Self {
         match self {
@@ -974,6 +1057,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemConst {
     fn clone(&self) -> Self {
         ItemConst {
@@ -990,6 +1074,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemEnum {
     fn clone(&self) -> Self {
         ItemEnum {
@@ -1004,6 +1089,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemExternCrate {
     fn clone(&self) -> Self {
         ItemExternCrate {
@@ -1018,6 +1104,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemFn {
     fn clone(&self) -> Self {
         ItemFn {
@@ -1029,6 +1116,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemForeignMod {
     fn clone(&self) -> Self {
         ItemForeignMod {
@@ -1040,6 +1128,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemImpl {
     fn clone(&self) -> Self {
         ItemImpl {
@@ -1056,6 +1145,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemMacro {
     fn clone(&self) -> Self {
         ItemMacro {
@@ -1067,6 +1157,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemMacro2 {
     fn clone(&self) -> Self {
         ItemMacro2 {
@@ -1079,6 +1170,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemMod {
     fn clone(&self) -> Self {
         ItemMod {
@@ -1092,6 +1184,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemStatic {
     fn clone(&self) -> Self {
         ItemStatic {
@@ -1109,6 +1202,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemStruct {
     fn clone(&self) -> Self {
         ItemStruct {
@@ -1123,6 +1217,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemTrait {
     fn clone(&self) -> Self {
         ItemTrait {
@@ -1141,6 +1236,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemTraitAlias {
     fn clone(&self) -> Self {
         ItemTraitAlias {
@@ -1156,6 +1252,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemType {
     fn clone(&self) -> Self {
         ItemType {
@@ -1171,6 +1268,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemUnion {
     fn clone(&self) -> Self {
         ItemUnion {
@@ -1184,6 +1282,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ItemUse {
     fn clone(&self) -> Self {
         ItemUse {
@@ -1197,6 +1296,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Label {
     fn clone(&self) -> Self {
         Label {
@@ -1206,6 +1306,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for LifetimeDef {
     fn clone(&self) -> Self {
         LifetimeDef {
@@ -1216,6 +1317,7 @@
         }
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Lit {
     fn clone(&self) -> Self {
         match self {
@@ -1230,6 +1332,7 @@
         }
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for LitBool {
     fn clone(&self) -> Self {
         LitBool {
@@ -1239,6 +1342,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Local {
     fn clone(&self) -> Self {
         Local {
@@ -1251,6 +1355,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Macro {
     fn clone(&self) -> Self {
         Macro {
@@ -1262,6 +1367,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for MacroDelimiter {
     fn clone(&self) -> Self {
         match self {
@@ -1272,6 +1378,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Member {
     fn clone(&self) -> Self {
         match self {
@@ -1281,6 +1388,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Meta {
     fn clone(&self) -> Self {
         match self {
@@ -1291,6 +1399,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for MetaList {
     fn clone(&self) -> Self {
         MetaList {
@@ -1301,6 +1410,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for MetaNameValue {
     fn clone(&self) -> Self {
         MetaNameValue {
@@ -1311,6 +1421,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for MethodTurbofish {
     fn clone(&self) -> Self {
         MethodTurbofish {
@@ -1322,6 +1433,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for NestedMeta {
     fn clone(&self) -> Self {
         match self {
@@ -1331,6 +1443,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ParenthesizedGenericArguments {
     fn clone(&self) -> Self {
         ParenthesizedGenericArguments {
@@ -1341,6 +1454,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Pat {
     fn clone(&self) -> Self {
         match self {
@@ -1365,6 +1479,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatBox {
     fn clone(&self) -> Self {
         PatBox {
@@ -1375,6 +1490,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatIdent {
     fn clone(&self) -> Self {
         PatIdent {
@@ -1387,6 +1503,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatLit {
     fn clone(&self) -> Self {
         PatLit {
@@ -1396,6 +1513,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatMacro {
     fn clone(&self) -> Self {
         PatMacro {
@@ -1405,6 +1523,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatOr {
     fn clone(&self) -> Self {
         PatOr {
@@ -1415,6 +1534,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatPath {
     fn clone(&self) -> Self {
         PatPath {
@@ -1425,6 +1545,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatRange {
     fn clone(&self) -> Self {
         PatRange {
@@ -1436,6 +1557,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatReference {
     fn clone(&self) -> Self {
         PatReference {
@@ -1447,6 +1569,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatRest {
     fn clone(&self) -> Self {
         PatRest {
@@ -1456,6 +1579,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatSlice {
     fn clone(&self) -> Self {
         PatSlice {
@@ -1466,6 +1590,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatStruct {
     fn clone(&self) -> Self {
         PatStruct {
@@ -1478,6 +1603,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatTuple {
     fn clone(&self) -> Self {
         PatTuple {
@@ -1488,6 +1614,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatTupleStruct {
     fn clone(&self) -> Self {
         PatTupleStruct {
@@ -1498,6 +1625,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatType {
     fn clone(&self) -> Self {
         PatType {
@@ -1509,6 +1637,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PatWild {
     fn clone(&self) -> Self {
         PatWild {
@@ -1518,6 +1647,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Path {
     fn clone(&self) -> Self {
         Path {
@@ -1527,6 +1657,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PathArguments {
     fn clone(&self) -> Self {
         match self {
@@ -1537,6 +1668,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PathSegment {
     fn clone(&self) -> Self {
         PathSegment {
@@ -1546,6 +1678,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PredicateEq {
     fn clone(&self) -> Self {
         PredicateEq {
@@ -1556,6 +1689,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PredicateLifetime {
     fn clone(&self) -> Self {
         PredicateLifetime {
@@ -1566,6 +1700,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for PredicateType {
     fn clone(&self) -> Self {
         PredicateType {
@@ -1577,6 +1712,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for QSelf {
     fn clone(&self) -> Self {
         QSelf {
@@ -1589,14 +1725,17 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Copy for RangeLimits {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for RangeLimits {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Receiver {
     fn clone(&self) -> Self {
         Receiver {
@@ -1608,6 +1747,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for ReturnType {
     fn clone(&self) -> Self {
         match self {
@@ -1617,6 +1757,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Signature {
     fn clone(&self) -> Self {
         Signature {
@@ -1635,6 +1776,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Stmt {
     fn clone(&self) -> Self {
         match self {
@@ -1646,6 +1788,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitBound {
     fn clone(&self) -> Self {
         TraitBound {
@@ -1657,14 +1800,17 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Copy for TraitBoundModifier {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitBoundModifier {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitItem {
     fn clone(&self) -> Self {
         match self {
@@ -1678,6 +1824,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitItemConst {
     fn clone(&self) -> Self {
         TraitItemConst {
@@ -1692,6 +1839,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitItemMacro {
     fn clone(&self) -> Self {
         TraitItemMacro {
@@ -1702,6 +1850,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitItemMethod {
     fn clone(&self) -> Self {
         TraitItemMethod {
@@ -1713,6 +1862,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TraitItemType {
     fn clone(&self) -> Self {
         TraitItemType {
@@ -1728,6 +1878,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Type {
     fn clone(&self) -> Self {
         match self {
@@ -1751,6 +1902,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeArray {
     fn clone(&self) -> Self {
         TypeArray {
@@ -1762,6 +1914,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeBareFn {
     fn clone(&self) -> Self {
         TypeBareFn {
@@ -1777,6 +1930,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeGroup {
     fn clone(&self) -> Self {
         TypeGroup {
@@ -1786,6 +1940,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeImplTrait {
     fn clone(&self) -> Self {
         TypeImplTrait {
@@ -1795,6 +1950,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeInfer {
     fn clone(&self) -> Self {
         TypeInfer {
@@ -1803,6 +1959,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeMacro {
     fn clone(&self) -> Self {
         TypeMacro {
@@ -1811,6 +1968,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeNever {
     fn clone(&self) -> Self {
         TypeNever {
@@ -1819,6 +1977,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeParam {
     fn clone(&self) -> Self {
         TypeParam {
@@ -1832,6 +1991,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeParamBound {
     fn clone(&self) -> Self {
         match self {
@@ -1841,6 +2001,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeParen {
     fn clone(&self) -> Self {
         TypeParen {
@@ -1850,6 +2011,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypePath {
     fn clone(&self) -> Self {
         TypePath {
@@ -1859,6 +2021,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypePtr {
     fn clone(&self) -> Self {
         TypePtr {
@@ -1870,6 +2033,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeReference {
     fn clone(&self) -> Self {
         TypeReference {
@@ -1881,6 +2045,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeSlice {
     fn clone(&self) -> Self {
         TypeSlice {
@@ -1890,6 +2055,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeTraitObject {
     fn clone(&self) -> Self {
         TypeTraitObject {
@@ -1899,6 +2065,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for TypeTuple {
     fn clone(&self) -> Self {
         TypeTuple {
@@ -1908,14 +2075,17 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Copy for UnOp {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UnOp {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UseGlob {
     fn clone(&self) -> Self {
         UseGlob {
@@ -1924,6 +2094,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UseGroup {
     fn clone(&self) -> Self {
         UseGroup {
@@ -1933,6 +2104,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UseName {
     fn clone(&self) -> Self {
         UseName {
@@ -1941,6 +2113,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UsePath {
     fn clone(&self) -> Self {
         UsePath {
@@ -1951,6 +2124,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UseRename {
     fn clone(&self) -> Self {
         UseRename {
@@ -1961,6 +2135,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for UseTree {
     fn clone(&self) -> Self {
         match self {
@@ -1973,6 +2148,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Variadic {
     fn clone(&self) -> Self {
         Variadic {
@@ -1982,6 +2158,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Variant {
     fn clone(&self) -> Self {
         Variant {
@@ -1993,6 +2170,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for VisCrate {
     fn clone(&self) -> Self {
         VisCrate {
@@ -2001,6 +2179,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for VisPublic {
     fn clone(&self) -> Self {
         VisPublic {
@@ -2009,6 +2188,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for VisRestricted {
     fn clone(&self) -> Self {
         VisRestricted {
@@ -2020,6 +2200,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Visibility {
     fn clone(&self) -> Self {
         match self {
@@ -2031,6 +2212,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for WhereClause {
     fn clone(&self) -> Self {
         WhereClause {
@@ -2040,6 +2222,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for WherePredicate {
     fn clone(&self) -> Self {
         match self {
diff --git a/src/gen/debug.rs b/src/gen/debug.rs
index 72baab0..3efa278 100644
--- a/src/gen/debug.rs
+++ b/src/gen/debug.rs
@@ -4,6 +4,7 @@
 use crate::*;
 use std::fmt::{self, Debug};
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Abi {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Abi");
@@ -13,6 +14,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for AngleBracketedGenericArguments {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("AngleBracketedGenericArguments");
@@ -24,6 +26,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Arm {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Arm");
@@ -37,6 +40,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for AttrStyle {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -50,6 +54,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Attribute {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Attribute");
@@ -62,6 +67,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for BareFnArg {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("BareFnArg");
@@ -72,6 +78,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for BinOp {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -219,6 +226,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Binding {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Binding");
@@ -229,6 +237,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Block {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Block");
@@ -238,6 +247,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for BoundLifetimes {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("BoundLifetimes");
@@ -249,6 +259,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ConstParam {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ConstParam");
@@ -263,6 +274,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Constraint {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Constraint");
@@ -273,6 +285,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Data {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -295,6 +308,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for DataEnum {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("DataEnum");
@@ -305,6 +319,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for DataStruct {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("DataStruct");
@@ -315,6 +330,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for DataUnion {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("DataUnion");
@@ -324,6 +340,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for DeriveInput {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("DeriveInput");
@@ -336,6 +353,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Expr {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -574,6 +592,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprArray {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprArray");
@@ -584,6 +603,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprAssign {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprAssign");
@@ -595,6 +615,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprAssignOp {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprAssignOp");
@@ -606,6 +627,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprAsync {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprAsync");
@@ -617,6 +639,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprAwait {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprAwait");
@@ -628,6 +651,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprBinary {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprBinary");
@@ -639,6 +663,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprBlock {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprBlock");
@@ -649,6 +674,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprBox {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprBox");
@@ -659,6 +685,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprBreak {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprBreak");
@@ -670,6 +697,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprCall {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprCall");
@@ -681,6 +709,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprCast {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprCast");
@@ -692,6 +721,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprClosure {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprClosure");
@@ -708,6 +738,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprContinue {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprContinue");
@@ -718,6 +749,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprField {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprField");
@@ -729,6 +761,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprForLoop {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprForLoop");
@@ -743,6 +776,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprGroup {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprGroup");
@@ -753,6 +787,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprIf {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprIf");
@@ -765,6 +800,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprIndex {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprIndex");
@@ -776,6 +812,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprLet {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprLet");
@@ -788,6 +825,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprLit {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprLit");
@@ -797,6 +835,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprLoop {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprLoop");
@@ -808,6 +847,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprMacro");
@@ -817,6 +857,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprMatch {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprMatch");
@@ -829,6 +870,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprMethodCall {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprMethodCall");
@@ -843,6 +885,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprParen {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprParen");
@@ -853,6 +896,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprPath {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprPath");
@@ -863,6 +907,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprRange {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprRange");
@@ -874,6 +919,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprReference {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprReference");
@@ -886,6 +932,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprRepeat {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprRepeat");
@@ -898,6 +945,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprReturn {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprReturn");
@@ -908,6 +956,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprStruct {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprStruct");
@@ -921,6 +970,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprTry {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprTry");
@@ -931,6 +981,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprTryBlock {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprTryBlock");
@@ -941,6 +992,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprTuple {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprTuple");
@@ -951,6 +1003,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprType");
@@ -962,6 +1015,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprUnary {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprUnary");
@@ -972,6 +1026,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprUnsafe {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprUnsafe");
@@ -982,6 +1037,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprWhile {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprWhile");
@@ -994,6 +1050,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ExprYield {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ExprYield");
@@ -1004,6 +1061,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Field {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Field");
@@ -1016,6 +1074,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for FieldPat {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("FieldPat");
@@ -1027,6 +1086,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for FieldValue {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("FieldValue");
@@ -1038,6 +1098,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Fields {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1056,6 +1117,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for FieldsNamed {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("FieldsNamed");
@@ -1065,6 +1127,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for FieldsUnnamed {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("FieldsUnnamed");
@@ -1074,6 +1137,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for File {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("File");
@@ -1084,6 +1148,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for FnArg {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1101,6 +1166,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ForeignItem {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1134,6 +1200,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ForeignItemFn {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ForeignItemFn");
@@ -1145,6 +1212,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ForeignItemMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ForeignItemMacro");
@@ -1155,6 +1223,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ForeignItemStatic {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ForeignItemStatic");
@@ -1170,6 +1239,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ForeignItemType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ForeignItemType");
@@ -1182,6 +1252,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for GenericArgument {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1214,6 +1285,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for GenericMethodArgument {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1231,6 +1303,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for GenericParam {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1253,6 +1326,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Generics {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Generics");
@@ -1264,6 +1338,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ImplItem {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1297,6 +1372,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ImplItemConst {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ImplItemConst");
@@ -1314,6 +1390,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ImplItemMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ImplItemMacro");
@@ -1324,6 +1401,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ImplItemMethod {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ImplItemMethod");
@@ -1336,6 +1414,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ImplItemType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ImplItemType");
@@ -1352,6 +1431,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Index {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Index");
@@ -1361,6 +1441,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Item {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1454,6 +1535,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemConst {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemConst");
@@ -1470,6 +1552,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemEnum {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemEnum");
@@ -1484,6 +1567,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemExternCrate {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemExternCrate");
@@ -1498,6 +1582,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemFn {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemFn");
@@ -1509,6 +1594,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemForeignMod {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemForeignMod");
@@ -1520,6 +1606,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemImpl {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemImpl");
@@ -1536,6 +1623,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemMacro");
@@ -1547,6 +1635,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemMacro2 {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemMacro2");
@@ -1559,6 +1648,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemMod {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemMod");
@@ -1572,6 +1662,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemStatic {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemStatic");
@@ -1589,6 +1680,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemStruct {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemStruct");
@@ -1603,6 +1695,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemTrait {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemTrait");
@@ -1621,6 +1714,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemTraitAlias {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemTraitAlias");
@@ -1636,6 +1730,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemType");
@@ -1651,6 +1746,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemUnion {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemUnion");
@@ -1664,6 +1760,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ItemUse {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ItemUse");
@@ -1677,6 +1774,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Label {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Label");
@@ -1685,6 +1783,7 @@
         formatter.finish()
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Lifetime {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Lifetime");
@@ -1694,6 +1793,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for LifetimeDef {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("LifetimeDef");
@@ -1704,6 +1804,7 @@
         formatter.finish()
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Lit {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1751,6 +1852,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Local {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Local");
@@ -1763,6 +1865,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Macro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Macro");
@@ -1774,6 +1877,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for MacroDelimiter {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1796,6 +1900,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Member {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1813,6 +1918,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Meta {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1835,6 +1941,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for MetaList {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("MetaList");
@@ -1845,6 +1952,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for MetaNameValue {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("MetaNameValue");
@@ -1855,6 +1963,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for MethodTurbofish {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("MethodTurbofish");
@@ -1866,6 +1975,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for NestedMeta {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1883,6 +1993,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ParenthesizedGenericArguments {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("ParenthesizedGenericArguments");
@@ -1893,6 +2004,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Pat {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -1981,6 +2093,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatBox {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatBox");
@@ -1991,6 +2104,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatIdent {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatIdent");
@@ -2003,6 +2117,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatLit {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatLit");
@@ -2012,6 +2127,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatMacro");
@@ -2021,6 +2137,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatOr {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatOr");
@@ -2031,6 +2148,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatPath {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatPath");
@@ -2041,6 +2159,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatRange {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatRange");
@@ -2052,6 +2171,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatReference {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatReference");
@@ -2063,6 +2183,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatRest {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatRest");
@@ -2072,6 +2193,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatSlice {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatSlice");
@@ -2082,6 +2204,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatStruct {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatStruct");
@@ -2094,6 +2217,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatTuple {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatTuple");
@@ -2104,6 +2228,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatTupleStruct {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatTupleStruct");
@@ -2114,6 +2239,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatType");
@@ -2125,6 +2251,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PatWild {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PatWild");
@@ -2134,6 +2261,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Path {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Path");
@@ -2143,6 +2271,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PathArguments {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2161,6 +2290,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PathSegment {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PathSegment");
@@ -2170,6 +2300,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PredicateEq {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PredicateEq");
@@ -2180,6 +2311,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PredicateLifetime {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PredicateLifetime");
@@ -2190,6 +2322,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for PredicateType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("PredicateType");
@@ -2201,6 +2334,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for QSelf {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("QSelf");
@@ -2213,6 +2347,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for RangeLimits {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2230,6 +2365,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Receiver {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Receiver");
@@ -2241,6 +2377,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for ReturnType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2255,6 +2392,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Signature {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Signature");
@@ -2273,6 +2411,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Stmt {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2301,6 +2440,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitBound {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TraitBound");
@@ -2312,6 +2452,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitBoundModifier {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2325,6 +2466,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitItem {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2358,6 +2500,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitItemConst {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TraitItemConst");
@@ -2372,6 +2515,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitItemMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TraitItemMacro");
@@ -2382,6 +2526,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitItemMethod {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TraitItemMethod");
@@ -2393,6 +2538,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TraitItemType {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TraitItemType");
@@ -2408,6 +2554,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Type {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2491,6 +2638,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeArray {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeArray");
@@ -2502,6 +2650,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeBareFn {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeBareFn");
@@ -2517,6 +2666,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeGroup {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeGroup");
@@ -2526,6 +2676,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeImplTrait {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeImplTrait");
@@ -2535,6 +2686,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeInfer {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeInfer");
@@ -2543,6 +2695,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeMacro {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeMacro");
@@ -2551,6 +2704,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeNever {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeNever");
@@ -2559,6 +2713,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeParam {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeParam");
@@ -2572,6 +2727,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeParamBound {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2589,6 +2745,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeParen {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeParen");
@@ -2598,6 +2755,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypePath {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypePath");
@@ -2607,6 +2765,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypePtr {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypePtr");
@@ -2618,6 +2777,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeReference {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeReference");
@@ -2629,6 +2789,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeSlice {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeSlice");
@@ -2638,6 +2799,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeTraitObject {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeTraitObject");
@@ -2647,6 +2809,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for TypeTuple {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("TypeTuple");
@@ -2656,6 +2819,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UnOp {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2678,6 +2842,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UseGlob {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("UseGlob");
@@ -2686,6 +2851,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UseGroup {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("UseGroup");
@@ -2695,6 +2861,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UseName {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("UseName");
@@ -2703,6 +2870,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UsePath {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("UsePath");
@@ -2713,6 +2881,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UseRename {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("UseRename");
@@ -2723,6 +2892,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for UseTree {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2755,6 +2925,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Variadic {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Variadic");
@@ -2764,6 +2935,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Variant {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("Variant");
@@ -2775,6 +2947,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for VisCrate {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("VisCrate");
@@ -2783,6 +2956,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for VisPublic {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("VisPublic");
@@ -2791,6 +2965,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for VisRestricted {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("VisRestricted");
@@ -2802,6 +2977,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Visibility {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -2825,6 +3001,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for WhereClause {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let mut formatter = formatter.debug_struct("WhereClause");
@@ -2834,6 +3011,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for WherePredicate {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match self {
diff --git a/src/gen/eq.rs b/src/gen/eq.rs
index 15b2bcb..e6e8532 100644
--- a/src/gen/eq.rs
+++ b/src/gen/eq.rs
@@ -5,24 +5,30 @@
 use crate::tt::TokenStreamHelper;
 use crate::*;
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Abi {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Abi {
     fn eq(&self, other: &Self) -> bool {
         self.name == other.name
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for AngleBracketedGenericArguments {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for AngleBracketedGenericArguments {
     fn eq(&self, other: &Self) -> bool {
         self.colon2_token == other.colon2_token && self.args == other.args
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Arm {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Arm {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -33,8 +39,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for AttrStyle {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for AttrStyle {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -45,8 +53,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Attribute {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Attribute {
     fn eq(&self, other: &Self) -> bool {
         self.style == other.style
@@ -55,16 +65,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for BareFnArg {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for BareFnArg {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.name == other.name && self.ty == other.ty
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for BinOp {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for BinOp {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -101,32 +115,40 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Binding {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Binding {
     fn eq(&self, other: &Self) -> bool {
         self.ident == other.ident && self.ty == other.ty
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Block {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Block {
     fn eq(&self, other: &Self) -> bool {
         self.stmts == other.stmts
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for BoundLifetimes {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for BoundLifetimes {
     fn eq(&self, other: &Self) -> bool {
         self.lifetimes == other.lifetimes
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ConstParam {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ConstParam {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -137,16 +159,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Constraint {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Constraint {
     fn eq(&self, other: &Self) -> bool {
         self.ident == other.ident && self.bounds == other.bounds
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Data {}
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Data {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -158,32 +184,40 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for DataEnum {}
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for DataEnum {
     fn eq(&self, other: &Self) -> bool {
         self.variants == other.variants
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for DataStruct {}
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for DataStruct {
     fn eq(&self, other: &Self) -> bool {
         self.fields == other.fields && self.semi_token == other.semi_token
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for DataUnion {}
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for DataUnion {
     fn eq(&self, other: &Self) -> bool {
         self.fields == other.fields
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for DeriveInput {}
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for DeriveInput {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -194,8 +228,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Expr {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Expr {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -276,24 +312,30 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprArray {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprArray {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.elems == other.elems
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprAssign {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprAssign {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.left == other.left && self.right == other.right
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprAssignOp {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprAssignOp {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -303,24 +345,30 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprAsync {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprAsync {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.capture == other.capture && self.block == other.block
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprAwait {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprAwait {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.base == other.base
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprBinary {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprBinary {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -330,48 +378,60 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprBlock {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprBlock {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.label == other.label && self.block == other.block
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprBox {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprBox {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprBreak {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprBreak {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.label == other.label && self.expr == other.expr
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprCall {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprCall {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.func == other.func && self.args == other.args
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprCast {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprCast {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr && self.ty == other.ty
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprClosure {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprClosure {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -384,24 +444,30 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprContinue {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprContinue {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.label == other.label
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprField {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprField {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.base == other.base && self.member == other.member
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprForLoop {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprForLoop {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -412,16 +478,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprGroup {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprGroup {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprIf {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprIf {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -431,56 +501,70 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprIndex {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprIndex {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr && self.index == other.index
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprLet {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprLet {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.pat == other.pat && self.expr == other.expr
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprLit {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprLit {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.lit == other.lit
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprLoop {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprLoop {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.label == other.label && self.body == other.body
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprMacro {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprMacro {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mac == other.mac
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprMatch {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprMatch {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr && self.arms == other.arms
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprMethodCall {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprMethodCall {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -491,24 +575,30 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprParen {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprParen {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprPath {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprPath {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.qself == other.qself && self.path == other.path
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprRange {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprRange {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -518,32 +608,40 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprReference {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprReference {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mutability == other.mutability && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprRepeat {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprRepeat {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr && self.len == other.len
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprReturn {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprReturn {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprStruct {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprStruct {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -554,56 +652,70 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprTry {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprTry {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprTryBlock {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprTryBlock {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.block == other.block
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprTuple {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprTuple {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.elems == other.elems
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprType {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprType {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr && self.ty == other.ty
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprUnary {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprUnary {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.op == other.op && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprUnsafe {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprUnsafe {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.block == other.block
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprWhile {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprWhile {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -613,16 +725,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ExprYield {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ExprYield {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Field {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Field {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -633,8 +749,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for FieldPat {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for FieldPat {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -644,8 +762,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for FieldValue {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for FieldValue {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -655,8 +775,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Fields {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Fields {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -668,32 +790,40 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for FieldsNamed {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for FieldsNamed {
     fn eq(&self, other: &Self) -> bool {
         self.named == other.named
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for FieldsUnnamed {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for FieldsUnnamed {
     fn eq(&self, other: &Self) -> bool {
         self.unnamed == other.unnamed
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for File {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for File {
     fn eq(&self, other: &Self) -> bool {
         self.shebang == other.shebang && self.attrs == other.attrs && self.items == other.items
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for FnArg {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for FnArg {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -704,8 +834,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ForeignItem {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ForeignItem {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -721,24 +853,30 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ForeignItemFn {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ForeignItemFn {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.vis == other.vis && self.sig == other.sig
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ForeignItemMacro {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ForeignItemMacro {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mac == other.mac && self.semi_token == other.semi_token
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ForeignItemStatic {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ForeignItemStatic {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -749,16 +887,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ForeignItemType {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ForeignItemType {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for GenericArgument {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for GenericArgument {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -776,8 +918,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for GenericMethodArgument {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for GenericMethodArgument {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -792,8 +936,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for GenericParam {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for GenericParam {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -805,8 +951,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Generics {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Generics {
     fn eq(&self, other: &Self) -> bool {
         self.lt_token == other.lt_token
@@ -816,8 +964,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ImplItem {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ImplItem {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -833,8 +983,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ImplItemConst {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ImplItemConst {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -846,16 +998,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ImplItemMacro {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ImplItemMacro {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mac == other.mac && self.semi_token == other.semi_token
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ImplItemMethod {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ImplItemMethod {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -866,8 +1022,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ImplItemType {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ImplItemType {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -879,8 +1037,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Item {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Item {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -908,8 +1068,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemConst {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemConst {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -920,8 +1082,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemEnum {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemEnum {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -932,8 +1096,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemExternCrate {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemExternCrate {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -943,8 +1109,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemFn {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemFn {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -954,16 +1122,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemForeignMod {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemForeignMod {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.abi == other.abi && self.items == other.items
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemImpl {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemImpl {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -976,8 +1148,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemMacro {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemMacro {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -987,8 +1161,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemMacro2 {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemMacro2 {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -998,8 +1174,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemMod {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemMod {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1010,8 +1188,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemStatic {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemStatic {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1023,8 +1203,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemStruct {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemStruct {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1036,8 +1218,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemTrait {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemTrait {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1052,8 +1236,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemTraitAlias {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemTraitAlias {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1064,8 +1250,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemType {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemType {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1076,8 +1264,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemUnion {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemUnion {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1088,8 +1278,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ItemUse {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ItemUse {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1099,16 +1291,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Label {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Label {
     fn eq(&self, other: &Self) -> bool {
         self.name == other.name
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LifetimeDef {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for LifetimeDef {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1117,7 +1313,9 @@
             && self.bounds == other.bounds
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Lit {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Lit {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1135,29 +1333,41 @@
         }
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitBool {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for LitBool {
     fn eq(&self, other: &Self) -> bool {
         self.value == other.value
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitByte {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitByteStr {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitChar {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitFloat {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitInt {}
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for LitStr {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Local {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Local {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.pat == other.pat && self.init == other.init
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Macro {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Macro {
     fn eq(&self, other: &Self) -> bool {
         self.path == other.path
@@ -1166,8 +1376,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for MacroDelimiter {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for MacroDelimiter {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1179,8 +1391,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Meta {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Meta {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1192,32 +1406,40 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for MetaList {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for MetaList {
     fn eq(&self, other: &Self) -> bool {
         self.path == other.path && self.nested == other.nested
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for MetaNameValue {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for MetaNameValue {
     fn eq(&self, other: &Self) -> bool {
         self.path == other.path && self.lit == other.lit
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for MethodTurbofish {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for MethodTurbofish {
     fn eq(&self, other: &Self) -> bool {
         self.args == other.args
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for NestedMeta {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for NestedMeta {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1228,16 +1450,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ParenthesizedGenericArguments {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ParenthesizedGenericArguments {
     fn eq(&self, other: &Self) -> bool {
         self.inputs == other.inputs && self.output == other.output
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Pat {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Pat {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1264,16 +1490,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatBox {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatBox {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.pat == other.pat
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatIdent {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatIdent {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1284,24 +1514,30 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatLit {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatLit {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.expr == other.expr
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatMacro {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatMacro {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mac == other.mac
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatOr {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatOr {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1310,16 +1546,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatPath {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatPath {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.qself == other.qself && self.path == other.path
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatRange {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatRange {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1329,32 +1569,40 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatReference {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatReference {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mutability == other.mutability && self.pat == other.pat
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatRest {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatRest {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatSlice {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatSlice {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.elems == other.elems
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatStruct {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatStruct {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1364,48 +1612,60 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatTuple {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatTuple {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.elems == other.elems
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatTupleStruct {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatTupleStruct {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.path == other.path && self.pat == other.pat
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatType {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatType {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.pat == other.pat && self.ty == other.ty
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PatWild {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PatWild {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Path {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Path {
     fn eq(&self, other: &Self) -> bool {
         self.leading_colon == other.leading_colon && self.segments == other.segments
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PathArguments {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PathArguments {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1421,32 +1681,40 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PathSegment {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PathSegment {
     fn eq(&self, other: &Self) -> bool {
         self.ident == other.ident && self.arguments == other.arguments
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PredicateEq {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PredicateEq {
     fn eq(&self, other: &Self) -> bool {
         self.lhs_ty == other.lhs_ty && self.rhs_ty == other.rhs_ty
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PredicateLifetime {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PredicateLifetime {
     fn eq(&self, other: &Self) -> bool {
         self.lifetime == other.lifetime && self.bounds == other.bounds
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for PredicateType {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for PredicateType {
     fn eq(&self, other: &Self) -> bool {
         self.lifetimes == other.lifetimes
@@ -1455,16 +1723,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for QSelf {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for QSelf {
     fn eq(&self, other: &Self) -> bool {
         self.ty == other.ty && self.position == other.position && self.as_token == other.as_token
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for RangeLimits {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for RangeLimits {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1475,8 +1747,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Receiver {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Receiver {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1485,8 +1759,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for ReturnType {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for ReturnType {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1497,8 +1773,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Signature {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Signature {
     fn eq(&self, other: &Self) -> bool {
         self.constness == other.constness
@@ -1513,8 +1791,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Stmt {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Stmt {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1527,8 +1807,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitBound {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitBound {
     fn eq(&self, other: &Self) -> bool {
         self.paren_token == other.paren_token
@@ -1538,8 +1820,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitBoundModifier {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitBoundModifier {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1550,8 +1834,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitItem {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitItem {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1567,8 +1853,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitItemConst {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitItemConst {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1578,16 +1866,20 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitItemMacro {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitItemMacro {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs && self.mac == other.mac && self.semi_token == other.semi_token
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitItemMethod {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitItemMethod {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1597,8 +1889,10 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TraitItemType {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TraitItemType {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1610,8 +1904,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Type {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Type {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1637,16 +1933,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeArray {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeArray {
     fn eq(&self, other: &Self) -> bool {
         self.elem == other.elem && self.len == other.len
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeBareFn {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeBareFn {
     fn eq(&self, other: &Self) -> bool {
         self.lifetimes == other.lifetimes
@@ -1658,48 +1958,60 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeGroup {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeGroup {
     fn eq(&self, other: &Self) -> bool {
         self.elem == other.elem
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeImplTrait {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeImplTrait {
     fn eq(&self, other: &Self) -> bool {
         self.bounds == other.bounds
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeInfer {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeInfer {
     fn eq(&self, _other: &Self) -> bool {
         true
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeMacro {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeMacro {
     fn eq(&self, other: &Self) -> bool {
         self.mac == other.mac
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeNever {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeNever {
     fn eq(&self, _other: &Self) -> bool {
         true
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeParam {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeParam {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1711,8 +2023,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeParamBound {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeParamBound {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1723,24 +2037,30 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeParen {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeParen {
     fn eq(&self, other: &Self) -> bool {
         self.elem == other.elem
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypePath {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypePath {
     fn eq(&self, other: &Self) -> bool {
         self.qself == other.qself && self.path == other.path
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypePtr {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypePtr {
     fn eq(&self, other: &Self) -> bool {
         self.const_token == other.const_token
@@ -1749,8 +2069,10 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeReference {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeReference {
     fn eq(&self, other: &Self) -> bool {
         self.lifetime == other.lifetime
@@ -1759,32 +2081,40 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeSlice {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeSlice {
     fn eq(&self, other: &Self) -> bool {
         self.elem == other.elem
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeTraitObject {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeTraitObject {
     fn eq(&self, other: &Self) -> bool {
         self.dyn_token == other.dyn_token && self.bounds == other.bounds
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for TypeTuple {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for TypeTuple {
     fn eq(&self, other: &Self) -> bool {
         self.elems == other.elems
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UnOp {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UnOp {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1796,48 +2126,60 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UseGlob {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UseGlob {
     fn eq(&self, _other: &Self) -> bool {
         true
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UseGroup {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UseGroup {
     fn eq(&self, other: &Self) -> bool {
         self.items == other.items
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UseName {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UseName {
     fn eq(&self, other: &Self) -> bool {
         self.ident == other.ident
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UsePath {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UsePath {
     fn eq(&self, other: &Self) -> bool {
         self.ident == other.ident && self.tree == other.tree
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UseRename {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UseRename {
     fn eq(&self, other: &Self) -> bool {
         self.ident == other.ident && self.rename == other.rename
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for UseTree {}
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for UseTree {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1851,16 +2193,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Variadic {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Variadic {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Variant {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Variant {
     fn eq(&self, other: &Self) -> bool {
         self.attrs == other.attrs
@@ -1870,32 +2216,40 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for VisCrate {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for VisCrate {
     fn eq(&self, _other: &Self) -> bool {
         true
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for VisPublic {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for VisPublic {
     fn eq(&self, _other: &Self) -> bool {
         true
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for VisRestricted {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for VisRestricted {
     fn eq(&self, other: &Self) -> bool {
         self.in_token == other.in_token && self.path == other.path
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for Visibility {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for Visibility {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -1908,16 +2262,20 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for WhereClause {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for WhereClause {
     fn eq(&self, other: &Self) -> bool {
         self.predicates == other.predicates
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Eq for WherePredicate {}
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl PartialEq for WherePredicate {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
diff --git a/src/gen/hash.rs b/src/gen/hash.rs
index 9e9e84a..7247174 100644
--- a/src/gen/hash.rs
+++ b/src/gen/hash.rs
@@ -6,6 +6,7 @@
 use crate::*;
 use std::hash::{Hash, Hasher};
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Abi {
     fn hash<H>(&self, state: &mut H)
     where
@@ -15,6 +16,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for AngleBracketedGenericArguments {
     fn hash<H>(&self, state: &mut H)
     where
@@ -25,6 +27,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Arm {
     fn hash<H>(&self, state: &mut H)
     where
@@ -38,6 +41,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for AttrStyle {
     fn hash<H>(&self, state: &mut H)
     where
@@ -54,6 +58,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Attribute {
     fn hash<H>(&self, state: &mut H)
     where
@@ -65,6 +70,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for BareFnArg {
     fn hash<H>(&self, state: &mut H)
     where
@@ -76,6 +82,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for BinOp {
     fn hash<H>(&self, state: &mut H)
     where
@@ -170,6 +177,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Binding {
     fn hash<H>(&self, state: &mut H)
     where
@@ -180,6 +188,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Block {
     fn hash<H>(&self, state: &mut H)
     where
@@ -189,6 +198,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for BoundLifetimes {
     fn hash<H>(&self, state: &mut H)
     where
@@ -198,6 +208,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ConstParam {
     fn hash<H>(&self, state: &mut H)
     where
@@ -211,6 +222,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Constraint {
     fn hash<H>(&self, state: &mut H)
     where
@@ -221,6 +233,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Data {
     fn hash<H>(&self, state: &mut H)
     where
@@ -243,6 +256,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for DataEnum {
     fn hash<H>(&self, state: &mut H)
     where
@@ -252,6 +266,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for DataStruct {
     fn hash<H>(&self, state: &mut H)
     where
@@ -262,6 +277,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for DataUnion {
     fn hash<H>(&self, state: &mut H)
     where
@@ -271,6 +287,7 @@
     }
 }
 #[cfg(feature = "derive")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for DeriveInput {
     fn hash<H>(&self, state: &mut H)
     where
@@ -284,6 +301,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Expr {
     fn hash<H>(&self, state: &mut H)
     where
@@ -485,6 +503,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprArray {
     fn hash<H>(&self, state: &mut H)
     where
@@ -495,6 +514,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprAssign {
     fn hash<H>(&self, state: &mut H)
     where
@@ -506,6 +526,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprAssignOp {
     fn hash<H>(&self, state: &mut H)
     where
@@ -518,6 +539,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprAsync {
     fn hash<H>(&self, state: &mut H)
     where
@@ -529,6 +551,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprAwait {
     fn hash<H>(&self, state: &mut H)
     where
@@ -539,6 +562,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprBinary {
     fn hash<H>(&self, state: &mut H)
     where
@@ -551,6 +575,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprBlock {
     fn hash<H>(&self, state: &mut H)
     where
@@ -562,6 +587,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprBox {
     fn hash<H>(&self, state: &mut H)
     where
@@ -572,6 +598,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprBreak {
     fn hash<H>(&self, state: &mut H)
     where
@@ -583,6 +610,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprCall {
     fn hash<H>(&self, state: &mut H)
     where
@@ -594,6 +622,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprCast {
     fn hash<H>(&self, state: &mut H)
     where
@@ -605,6 +634,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprClosure {
     fn hash<H>(&self, state: &mut H)
     where
@@ -620,6 +650,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprContinue {
     fn hash<H>(&self, state: &mut H)
     where
@@ -630,6 +661,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprField {
     fn hash<H>(&self, state: &mut H)
     where
@@ -641,6 +673,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprForLoop {
     fn hash<H>(&self, state: &mut H)
     where
@@ -654,6 +687,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprGroup {
     fn hash<H>(&self, state: &mut H)
     where
@@ -664,6 +698,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprIf {
     fn hash<H>(&self, state: &mut H)
     where
@@ -676,6 +711,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprIndex {
     fn hash<H>(&self, state: &mut H)
     where
@@ -687,6 +723,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprLet {
     fn hash<H>(&self, state: &mut H)
     where
@@ -698,6 +735,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprLit {
     fn hash<H>(&self, state: &mut H)
     where
@@ -708,6 +746,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprLoop {
     fn hash<H>(&self, state: &mut H)
     where
@@ -719,6 +758,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -729,6 +769,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprMatch {
     fn hash<H>(&self, state: &mut H)
     where
@@ -740,6 +781,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprMethodCall {
     fn hash<H>(&self, state: &mut H)
     where
@@ -753,6 +795,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprParen {
     fn hash<H>(&self, state: &mut H)
     where
@@ -763,6 +806,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprPath {
     fn hash<H>(&self, state: &mut H)
     where
@@ -774,6 +818,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprRange {
     fn hash<H>(&self, state: &mut H)
     where
@@ -786,6 +831,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprReference {
     fn hash<H>(&self, state: &mut H)
     where
@@ -797,6 +843,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprRepeat {
     fn hash<H>(&self, state: &mut H)
     where
@@ -808,6 +855,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprReturn {
     fn hash<H>(&self, state: &mut H)
     where
@@ -818,6 +866,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprStruct {
     fn hash<H>(&self, state: &mut H)
     where
@@ -831,6 +880,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprTry {
     fn hash<H>(&self, state: &mut H)
     where
@@ -841,6 +891,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprTryBlock {
     fn hash<H>(&self, state: &mut H)
     where
@@ -851,6 +902,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprTuple {
     fn hash<H>(&self, state: &mut H)
     where
@@ -861,6 +913,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -872,6 +925,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprUnary {
     fn hash<H>(&self, state: &mut H)
     where
@@ -883,6 +937,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprUnsafe {
     fn hash<H>(&self, state: &mut H)
     where
@@ -893,6 +948,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprWhile {
     fn hash<H>(&self, state: &mut H)
     where
@@ -905,6 +961,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ExprYield {
     fn hash<H>(&self, state: &mut H)
     where
@@ -915,6 +972,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Field {
     fn hash<H>(&self, state: &mut H)
     where
@@ -928,6 +986,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for FieldPat {
     fn hash<H>(&self, state: &mut H)
     where
@@ -940,6 +999,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for FieldValue {
     fn hash<H>(&self, state: &mut H)
     where
@@ -952,6 +1012,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Fields {
     fn hash<H>(&self, state: &mut H)
     where
@@ -973,6 +1034,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for FieldsNamed {
     fn hash<H>(&self, state: &mut H)
     where
@@ -982,6 +1044,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for FieldsUnnamed {
     fn hash<H>(&self, state: &mut H)
     where
@@ -991,6 +1054,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for File {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1002,6 +1066,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for FnArg {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1020,6 +1085,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ForeignItem {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1051,6 +1117,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ForeignItemFn {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1062,6 +1129,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ForeignItemMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1073,6 +1141,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ForeignItemStatic {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1086,6 +1155,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ForeignItemType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1097,6 +1167,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for GenericArgument {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1127,6 +1198,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for GenericMethodArgument {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1145,6 +1217,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for GenericParam {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1167,6 +1240,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Generics {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1179,6 +1253,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ImplItem {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1210,6 +1285,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ImplItemConst {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1224,6 +1300,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ImplItemMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1235,6 +1312,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ImplItemMethod {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1248,6 +1326,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ImplItemType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1262,6 +1341,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Item {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1341,6 +1421,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemConst {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1354,6 +1435,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemEnum {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1367,6 +1449,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemExternCrate {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1379,6 +1462,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemFn {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1391,6 +1475,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemForeignMod {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1402,6 +1487,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemImpl {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1417,6 +1503,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1429,6 +1516,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemMacro2 {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1441,6 +1529,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemMod {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1454,6 +1543,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemStatic {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1468,6 +1558,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemStruct {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1482,6 +1573,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemTrait {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1499,6 +1591,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemTraitAlias {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1512,6 +1605,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1525,6 +1619,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemUnion {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1538,6 +1633,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ItemUse {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1550,6 +1646,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Label {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1559,6 +1656,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for LifetimeDef {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1570,6 +1668,7 @@
         self.bounds.hash(state);
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Lit {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1611,6 +1710,7 @@
         }
     }
 }
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for LitBool {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1620,6 +1720,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Local {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1631,6 +1732,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Macro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1642,6 +1744,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for MacroDelimiter {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1661,6 +1764,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Meta {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1683,6 +1787,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for MetaList {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1693,6 +1798,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for MetaNameValue {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1703,6 +1809,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for MethodTurbofish {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1712,6 +1819,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for NestedMeta {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1730,6 +1838,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ParenthesizedGenericArguments {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1740,6 +1849,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Pat {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1815,6 +1925,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatBox {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1825,6 +1936,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatIdent {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1838,6 +1950,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatLit {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1848,6 +1961,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1858,6 +1972,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatOr {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1869,6 +1984,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatPath {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1880,6 +1996,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatRange {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1892,6 +2009,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatReference {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1903,6 +2021,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatRest {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1912,6 +2031,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatSlice {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1922,6 +2042,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatStruct {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1934,6 +2055,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatTuple {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1944,6 +2066,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatTupleStruct {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1955,6 +2078,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1966,6 +2090,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PatWild {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1975,6 +2100,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Path {
     fn hash<H>(&self, state: &mut H)
     where
@@ -1985,6 +2111,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PathArguments {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2006,6 +2133,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PathSegment {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2016,6 +2144,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PredicateEq {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2026,6 +2155,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PredicateLifetime {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2036,6 +2166,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for PredicateType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2047,6 +2178,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for QSelf {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2058,6 +2190,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for RangeLimits {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2074,6 +2207,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Receiver {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2085,6 +2219,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for ReturnType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2102,6 +2237,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Signature {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2119,6 +2255,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Stmt {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2145,6 +2282,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitBound {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2157,6 +2295,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitBoundModifier {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2173,6 +2312,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitItem {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2204,6 +2344,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitItemConst {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2216,6 +2357,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitItemMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2227,6 +2369,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitItemMethod {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2239,6 +2382,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TraitItemType {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2253,6 +2397,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Type {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2324,6 +2469,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeArray {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2334,6 +2480,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeBareFn {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2348,6 +2495,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeGroup {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2357,6 +2505,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeImplTrait {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2366,6 +2515,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeInfer {
     fn hash<H>(&self, _state: &mut H)
     where
@@ -2374,6 +2524,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeMacro {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2383,6 +2534,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeNever {
     fn hash<H>(&self, _state: &mut H)
     where
@@ -2391,6 +2543,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeParam {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2405,6 +2558,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeParamBound {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2423,6 +2577,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeParen {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2432,6 +2587,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypePath {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2442,6 +2598,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypePtr {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2453,6 +2610,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeReference {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2464,6 +2622,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeSlice {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2473,6 +2632,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeTraitObject {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2483,6 +2643,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for TypeTuple {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2492,6 +2653,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UnOp {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2511,6 +2673,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UseGlob {
     fn hash<H>(&self, _state: &mut H)
     where
@@ -2519,6 +2682,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UseGroup {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2528,6 +2692,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UseName {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2537,6 +2702,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UsePath {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2547,6 +2713,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UseRename {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2557,6 +2724,7 @@
     }
 }
 #[cfg(feature = "full")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for UseTree {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2587,6 +2755,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Variadic {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2596,6 +2765,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Variant {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2608,6 +2778,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for VisCrate {
     fn hash<H>(&self, _state: &mut H)
     where
@@ -2616,6 +2787,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for VisPublic {
     fn hash<H>(&self, _state: &mut H)
     where
@@ -2624,6 +2796,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for VisRestricted {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2634,6 +2807,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for Visibility {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2659,6 +2833,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for WhereClause {
     fn hash<H>(&self, state: &mut H)
     where
@@ -2668,6 +2843,7 @@
     }
 }
 #[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Hash for WherePredicate {
     fn hash<H>(&self, state: &mut H)
     where
diff --git a/src/generics.rs b/src/generics.rs
index db6de9d..a78af22 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -11,6 +11,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Generics {
         pub lt_token: Option<Token![<]>,
         pub params: Punctuated<GenericParam, Token![,]>,
@@ -30,7 +31,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum GenericParam {
         /// A generic type parameter: `T: Into<String>`.
         Type(TypeParam),
@@ -48,6 +50,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeParam {
         pub attrs: Vec<Attribute>,
         pub ident: Ident,
@@ -63,6 +66,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct LifetimeDef {
         pub attrs: Vec<Attribute>,
         pub lifetime: Lifetime,
@@ -76,6 +80,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ConstParam {
         pub attrs: Vec<Attribute>,
         pub const_token: Token![const],
@@ -294,6 +299,10 @@
 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
 /// feature and the `"printing"` feature.*
 #[cfg(feature = "printing")]
+#[cfg_attr(
+    doc_cfg,
+    doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
 pub struct ImplGenerics<'a>(&'a Generics);
 
 /// Returned by `Generics::split_for_impl`.
@@ -301,6 +310,10 @@
 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
 /// feature and the `"printing"` feature.*
 #[cfg(feature = "printing")]
+#[cfg_attr(
+    doc_cfg,
+    doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
 pub struct TypeGenerics<'a>(&'a Generics);
 
 /// Returned by `TypeGenerics::as_turbofish`.
@@ -308,6 +321,10 @@
 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
 /// feature and the `"printing"` feature.*
 #[cfg(feature = "printing")]
+#[cfg_attr(
+    doc_cfg,
+    doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
 pub struct Turbofish<'a>(&'a Generics);
 
 #[cfg(feature = "printing")]
@@ -333,6 +350,10 @@
     ///
     /// *This method is available only if Syn is built with the `"derive"` or
     /// `"full"` feature and the `"printing"` feature.*
+    #[cfg_attr(
+        doc_cfg,
+        doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+    )]
     pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
         (
             ImplGenerics(self),
@@ -346,6 +367,7 @@
 macro_rules! generics_wrapper_impls {
     ($ty:ident) => {
         #[cfg(feature = "clone-impls")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
         impl<'a> Clone for $ty<'a> {
             fn clone(&self) -> Self {
                 $ty(self.0)
@@ -353,6 +375,7 @@
         }
 
         #[cfg(feature = "extra-traits")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
         impl<'a> Debug for $ty<'a> {
             fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 formatter
@@ -363,9 +386,11 @@
         }
 
         #[cfg(feature = "extra-traits")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
         impl<'a> Eq for $ty<'a> {}
 
         #[cfg(feature = "extra-traits")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
         impl<'a> PartialEq for $ty<'a> {
             fn eq(&self, other: &Self) -> bool {
                 self.0 == other.0
@@ -373,6 +398,7 @@
         }
 
         #[cfg(feature = "extra-traits")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
         impl<'a> Hash for $ty<'a> {
             fn hash<H: Hasher>(&self, state: &mut H) {
                 self.0.hash(state);
@@ -404,6 +430,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct BoundLifetimes {
         pub for_token: Token![for],
         pub lt_token: Token![<],
@@ -452,6 +479,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum TypeParamBound {
         Trait(TraitBound),
         Lifetime(Lifetime),
@@ -463,6 +491,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TraitBound {
         pub paren_token: Option<token::Paren>,
         pub modifier: TraitBoundModifier,
@@ -479,6 +508,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum TraitBoundModifier {
         None,
         Maybe(Token![?]),
@@ -491,6 +521,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct WhereClause {
         pub where_token: Token![where],
         pub predicates: Punctuated<WherePredicate, Token![,]>,
@@ -507,7 +538,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum WherePredicate {
         /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
         Type(PredicateType),
@@ -525,6 +557,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct PredicateType {
         /// Any lifetimes from a `for` binding
         pub lifetimes: Option<BoundLifetimes>,
@@ -541,6 +574,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct PredicateLifetime {
         pub lifetime: Lifetime,
         pub colon_token: Token![:],
@@ -553,6 +587,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct PredicateEq {
         pub lhs_ty: Type,
         pub eq_token: Token![=],
@@ -565,6 +600,7 @@
     use super::*;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Generics {
         fn parse(input: ParseStream) -> Result<Self> {
             if !input.peek(Token![<]) {
@@ -574,7 +610,6 @@
             let lt_token: Token![<] = input.parse()?;
 
             let mut params = Punctuated::new();
-            let mut allow_lifetime_param = true;
             loop {
                 if input.peek(Token![>]) {
                     break;
@@ -582,19 +617,17 @@
 
                 let attrs = input.call(Attribute::parse_outer)?;
                 let lookahead = input.lookahead1();
-                if allow_lifetime_param && lookahead.peek(Lifetime) {
+                if lookahead.peek(Lifetime) {
                     params.push_value(GenericParam::Lifetime(LifetimeDef {
                         attrs,
                         ..input.parse()?
                     }));
                 } else if lookahead.peek(Ident) {
-                    allow_lifetime_param = false;
                     params.push_value(GenericParam::Type(TypeParam {
                         attrs,
                         ..input.parse()?
                     }));
                 } else if lookahead.peek(Token![const]) {
-                    allow_lifetime_param = false;
                     params.push_value(GenericParam::Const(ConstParam {
                         attrs,
                         ..input.parse()?
@@ -621,6 +654,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for GenericParam {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -647,6 +681,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LifetimeDef {
         fn parse(input: ParseStream) -> Result<Self> {
             let has_colon;
@@ -684,6 +719,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for BoundLifetimes {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(BoundLifetimes {
@@ -705,6 +741,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Option<BoundLifetimes> {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Token![for]) {
@@ -715,6 +752,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeParam {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -768,6 +806,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeParamBound {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Lifetime) {
@@ -786,6 +825,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitBound {
         fn parse(input: ParseStream) -> Result<Self> {
             let modifier: TraitBoundModifier = input.parse()?;
@@ -806,6 +846,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitBoundModifier {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Token![?]) {
@@ -816,6 +857,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ConstParam {
         fn parse(input: ParseStream) -> Result<Self> {
             let mut default = None;
@@ -839,6 +881,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for WhereClause {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(WhereClause {
@@ -869,6 +912,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Option<WhereClause> {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Token![where]) {
@@ -879,6 +923,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for WherePredicate {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Lifetime) && input.peek2(Token![:]) {
@@ -951,6 +996,7 @@
     use proc_macro2::TokenTree;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Generics {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             if self.params.is_empty() {
@@ -1100,6 +1146,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for BoundLifetimes {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.for_token.to_tokens(tokens);
@@ -1109,6 +1156,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LifetimeDef {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -1120,6 +1168,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeParam {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -1133,14 +1182,21 @@
                 {
                     if self.eq_token.is_none() {
                         if let Type::Verbatim(default) = default {
-                            let mut iter = default.clone().into_iter();
-                            match (iter.next(), iter.next()) {
-                                (Some(TokenTree::Punct(ref q)), Some(TokenTree::Ident(ref c)))
-                                    if q.as_char() == '?' && c == "const" =>
-                                {
-                                    return default.to_tokens(tokens);
+                            let mut iter = default.clone().into_iter().peekable();
+                            while let Some(token) = iter.next() {
+                                if let TokenTree::Punct(q) = token {
+                                    if q.as_char() == '?' {
+                                        if let Some(TokenTree::Ident(c)) = iter.peek() {
+                                            if c == "const" {
+                                                if self.bounds.is_empty() {
+                                                    TokensOrDefault(&self.colon_token)
+                                                        .to_tokens(tokens);
+                                                }
+                                                return default.to_tokens(tokens);
+                                            }
+                                        }
+                                    }
                                 }
-                                _ => {}
                             }
                         }
                     }
@@ -1151,6 +1207,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TraitBound {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let to_tokens = |tokens: &mut TokenStream| {
@@ -1165,6 +1222,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TraitBoundModifier {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -1174,6 +1232,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ConstParam {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -1188,6 +1247,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for WhereClause {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             if !self.predicates.is_empty() {
@@ -1197,6 +1257,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PredicateType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.lifetimes.to_tokens(tokens);
@@ -1206,6 +1267,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PredicateLifetime {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.lifetime.to_tokens(tokens);
@@ -1214,6 +1276,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PredicateEq {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.lhs_ty.to_tokens(tokens);
diff --git a/src/group.rs b/src/group.rs
index 3c23f80..6b05710 100644
--- a/src/group.rs
+++ b/src/group.rs
@@ -133,15 +133,16 @@
 /// # }
 /// ```
 #[macro_export]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 macro_rules! parenthesized {
     ($content:ident in $cursor:expr) => {
         match $crate::group::parse_parens(&$cursor) {
-            $crate::export::Ok(parens) => {
+            $crate::__private::Ok(parens) => {
                 $content = parens.content;
                 parens.token
             }
-            $crate::export::Err(error) => {
-                return $crate::export::Err(error);
+            $crate::__private::Err(error) => {
+                return $crate::__private::Err(error);
             }
         }
     };
@@ -210,15 +211,16 @@
 /// # }
 /// ```
 #[macro_export]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 macro_rules! braced {
     ($content:ident in $cursor:expr) => {
         match $crate::group::parse_braces(&$cursor) {
-            $crate::export::Ok(braces) => {
+            $crate::__private::Ok(braces) => {
                 $content = braces.content;
                 braces.token
             }
-            $crate::export::Err(error) => {
-                return $crate::export::Err(error);
+            $crate::__private::Err(error) => {
+                return $crate::__private::Err(error);
             }
         }
     };
@@ -264,15 +266,16 @@
 /// # }
 /// ```
 #[macro_export]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 macro_rules! bracketed {
     ($content:ident in $cursor:expr) => {
         match $crate::group::parse_brackets(&$cursor) {
-            $crate::export::Ok(brackets) => {
+            $crate::__private::Ok(brackets) => {
                 $content = brackets.content;
                 brackets.token
             }
-            $crate::export::Err(error) => {
-                return $crate::export::Err(error);
+            $crate::__private::Err(error) => {
+                return $crate::__private::Err(error);
             }
         }
     };
diff --git a/src/ident.rs b/src/ident.rs
index 4ca7484..61e0887 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -36,6 +36,7 @@
 }
 
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for Ident {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| {
diff --git a/src/item.rs b/src/item.rs
index b7759c7..883ecc7 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -15,10 +15,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum Item {
         /// A constant item: `const MAX: u16 = 65535`.
         Const(ItemConst),
@@ -82,6 +80,7 @@
     /// A constant item: `const MAX: u16 = 65535`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemConst {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -99,6 +98,7 @@
     /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemEnum {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -114,6 +114,7 @@
     /// An `extern crate` item: `extern crate serde`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemExternCrate {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -130,6 +131,7 @@
     /// }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemFn {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -142,6 +144,7 @@
     /// A block of foreign items: `extern "C" { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemForeignMod {
         pub attrs: Vec<Attribute>,
         pub abi: Abi,
@@ -155,6 +158,7 @@
     /// for Data<A> { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemImpl {
         pub attrs: Vec<Attribute>,
         pub defaultness: Option<Token![default]>,
@@ -174,6 +178,7 @@
     /// A macro invocation, which includes `macro_rules!` definitions.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemMacro {
         pub attrs: Vec<Attribute>,
         /// The `example` in `macro_rules! example { ... }`.
@@ -187,6 +192,7 @@
     /// A 2.0-style declarative macro introduced by the `macro` keyword.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemMacro2 {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -200,6 +206,7 @@
     /// A module or module declaration: `mod m` or `mod m { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemMod {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -214,6 +221,7 @@
     /// A static item: `static BIKE: Shed = Shed(42)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemStatic {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -232,6 +240,7 @@
     /// A struct definition: `struct Foo<A> { x: A }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemStruct {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -247,6 +256,7 @@
     /// A trait definition: `pub trait Iterator { ... }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemTrait {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -266,6 +276,7 @@
     /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemTraitAlias {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -282,6 +293,7 @@
     /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemType {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -298,6 +310,7 @@
     /// A union definition: `union Foo<A, B> { x: A, y: B }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemUnion {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -312,6 +325,7 @@
     /// A use declaration: `use std::collections::HashMap`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ItemUse {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -437,10 +451,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum UseTree {
         /// A path prefix of imports in a `use` item: `std::...`.
         Path(UsePath),
@@ -463,6 +475,7 @@
     /// A path prefix of imports in a `use` item: `std::...`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct UsePath {
         pub ident: Ident,
         pub colon2_token: Token![::],
@@ -474,6 +487,7 @@
     /// An identifier imported by a `use` item: `HashMap`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct UseName {
         pub ident: Ident,
     }
@@ -483,6 +497,7 @@
     /// An renamed identifier imported by a `use` item: `HashMap as Map`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct UseRename {
         pub ident: Ident,
         pub as_token: Token![as],
@@ -494,6 +509,7 @@
     /// A glob import in a `use` item: `*`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct UseGlob {
         pub star_token: Token![*],
     }
@@ -503,6 +519,7 @@
     /// A braced group of imports in a `use` item: `{A, B, C}`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct UseGroup {
         pub brace_token: token::Brace,
         pub items: Punctuated<UseTree, Token![,]>,
@@ -518,10 +535,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum ForeignItem {
         /// A foreign function in an `extern` block.
         Fn(ForeignItemFn),
@@ -547,6 +562,7 @@
     /// A foreign function in an `extern` block.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ForeignItemFn {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -559,6 +575,7 @@
     /// A foreign static item in an `extern` block: `static ext: u8`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ForeignItemStatic {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -575,6 +592,7 @@
     /// A foreign type in an `extern` block: `type void`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ForeignItemType {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -588,6 +606,7 @@
     /// A macro invocation within an extern block.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ForeignItemMacro {
         pub attrs: Vec<Attribute>,
         pub mac: Macro,
@@ -604,10 +623,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum TraitItem {
         /// An associated constant within the definition of a trait.
         Const(TraitItemConst),
@@ -633,6 +650,7 @@
     /// An associated constant within the definition of a trait.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct TraitItemConst {
         pub attrs: Vec<Attribute>,
         pub const_token: Token![const],
@@ -648,6 +666,7 @@
     /// A trait method within the definition of a trait.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct TraitItemMethod {
         pub attrs: Vec<Attribute>,
         pub sig: Signature,
@@ -660,6 +679,7 @@
     /// An associated type within the definition of a trait.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct TraitItemType {
         pub attrs: Vec<Attribute>,
         pub type_token: Token![type],
@@ -676,6 +696,7 @@
     /// A macro invocation within the definition of a trait.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct TraitItemMacro {
         pub attrs: Vec<Attribute>,
         pub mac: Macro,
@@ -692,10 +713,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum ImplItem {
         /// An associated constant within an impl block.
         Const(ImplItemConst),
@@ -721,6 +740,7 @@
     /// An associated constant within an impl block.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ImplItemConst {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -739,6 +759,7 @@
     /// A method within an impl block.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ImplItemMethod {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -752,6 +773,7 @@
     /// An associated type within an impl block.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ImplItemType {
         pub attrs: Vec<Attribute>,
         pub vis: Visibility,
@@ -769,6 +791,7 @@
     /// A macro invocation within an impl block.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct ImplItemMacro {
         pub attrs: Vec<Attribute>,
         pub mac: Macro,
@@ -781,6 +804,7 @@
     /// initialize(&self)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct Signature {
         pub constness: Option<Token![const]>,
         pub asyncness: Option<Token![async]>,
@@ -818,6 +842,7 @@
     /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum FnArg {
         /// The `self` argument of an associated method, whether taken by value
         /// or by reference.
@@ -839,6 +864,7 @@
     /// Box<Self>`, are parsed as a `FnArg::Typed`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct Receiver {
         pub attrs: Vec<Attribute>,
         pub reference: Option<(Token![&], Option<Lifetime>)>,
@@ -865,6 +891,7 @@
 
     crate::custom_keyword!(existential);
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Item {
         fn parse(input: ParseStream) -> Result<Self> {
             let begin = input.fork();
@@ -975,6 +1002,16 @@
                     } else {
                         Ok(Item::Verbatim(verbatim::between(begin, input)))
                     }
+                } else if lookahead.peek(Token![extern]) {
+                    input.parse::<Visibility>()?;
+                    input.parse::<Token![unsafe]>()?;
+                    input.parse::<ItemForeignMod>()?;
+                    Ok(Item::Verbatim(verbatim::between(begin, input)))
+                } else if lookahead.peek(Token![mod]) {
+                    input.parse::<Visibility>()?;
+                    input.parse::<Token![unsafe]>()?;
+                    input.parse::<ItemMod>()?;
+                    Ok(Item::Verbatim(verbatim::between(begin, input)))
                 } else {
                     Err(lookahead.error())
                 }
@@ -1035,6 +1072,7 @@
         semi_token: Token![;],
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for FlexibleItemType {
         fn parse(input: ParseStream) -> Result<Self> {
             let vis: Visibility = input.parse()?;
@@ -1078,6 +1116,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemMacro {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1104,6 +1143,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemMacro2 {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1144,6 +1184,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemExternCrate {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ItemExternCrate {
@@ -1176,6 +1217,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemUse {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ItemUse {
@@ -1189,6 +1231,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for UseTree {
         fn parse(input: ParseStream) -> Result<UseTree> {
             let lookahead = input.lookahead1();
@@ -1237,6 +1280,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemStatic {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ItemStatic {
@@ -1254,6 +1298,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemConst {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ItemConst {
@@ -1334,6 +1379,7 @@
             && fork.peek(Token![fn])
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Signature {
         fn parse(input: ParseStream) -> Result<Self> {
             let constness: Option<Token![const]> = input.parse()?;
@@ -1368,6 +1414,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemFn {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -1396,6 +1443,7 @@
         })
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for FnArg {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1415,6 +1463,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Receiver {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(Receiver {
@@ -1510,6 +1559,7 @@
         })
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemMod {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -1551,6 +1601,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemForeignMod {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -1573,6 +1624,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ForeignItem {
         fn parse(input: ParseStream) -> Result<Self> {
             let begin = input.fork();
@@ -1652,6 +1704,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ForeignItemFn {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1667,6 +1720,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ForeignItemStatic {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ForeignItemStatic {
@@ -1682,6 +1736,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ForeignItemType {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ForeignItemType {
@@ -1725,6 +1780,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ForeignItemMacro {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1742,6 +1798,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemType {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ItemType {
@@ -1838,6 +1895,7 @@
         Ok(tokens)
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemStruct {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1861,6 +1919,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemEnum {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1884,6 +1943,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemUnion {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -1934,6 +1994,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemTrait {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -2007,6 +2068,7 @@
         })
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemTraitAlias {
         fn parse(input: ParseStream) -> Result<Self> {
             let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
@@ -2062,6 +2124,7 @@
         })
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitItem {
         fn parse(input: ParseStream) -> Result<Self> {
             let begin = input.fork();
@@ -2118,6 +2181,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitItemConst {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(TraitItemConst {
@@ -2147,6 +2211,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitItemMethod {
         fn parse(input: ParseStream) -> Result<Self> {
             let outer_attrs = input.call(Attribute::parse_outer)?;
@@ -2175,6 +2240,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitItemType {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -2246,6 +2312,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TraitItemMacro {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -2263,6 +2330,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ItemImpl {
         fn parse(input: ParseStream) -> Result<Self> {
             let allow_const_impl = false;
@@ -2297,20 +2365,46 @@
             input.parse::<Token![const]>()?;
         }
 
-        let trait_ = (|| -> Option<_> {
-            let ahead = input.fork();
-            let polarity: Option<Token![!]> = ahead.parse().ok()?;
-            let mut path: Path = ahead.parse().ok()?;
-            if path.segments.last().unwrap().arguments.is_empty() && ahead.peek(token::Paren) {
-                let parenthesized = PathArguments::Parenthesized(ahead.parse().ok()?);
-                path.segments.last_mut().unwrap().arguments = parenthesized;
-            }
-            let for_token: Token![for] = ahead.parse().ok()?;
-            input.advance_to(&ahead);
-            Some((polarity, path, for_token))
-        })();
+        let begin = input.fork();
+        let polarity = if input.peek(Token![!]) && !input.peek2(token::Brace) {
+            Some(input.parse::<Token![!]>()?)
+        } else {
+            None
+        };
 
-        let self_ty: Type = input.parse()?;
+        let mut first_ty: Type = input.parse()?;
+        let self_ty: Type;
+        let trait_;
+
+        let is_impl_for = input.peek(Token![for]);
+        if is_impl_for {
+            let for_token: Token![for] = input.parse()?;
+            let mut first_ty_ref = &first_ty;
+            while let Type::Group(ty) = first_ty_ref {
+                first_ty_ref = &ty.elem;
+            }
+            if let Type::Path(_) = first_ty_ref {
+                while let Type::Group(ty) = first_ty {
+                    first_ty = *ty.elem;
+                }
+                if let Type::Path(TypePath { qself: None, path }) = first_ty {
+                    trait_ = Some((polarity, path, for_token));
+                } else {
+                    unreachable!()
+                }
+            } else {
+                trait_ = None;
+            }
+            self_ty = input.parse()?;
+        } else {
+            trait_ = None;
+            self_ty = if polarity.is_none() {
+                first_ty
+            } else {
+                Type::Verbatim(verbatim::between(begin, input))
+            };
+        }
+
         generics.where_clause = input.parse()?;
 
         let content;
@@ -2322,7 +2416,7 @@
             items.push(content.parse()?);
         }
 
-        if is_const_impl {
+        if is_const_impl || is_impl_for && trait_.is_none() {
             Ok(None)
         } else {
             Ok(Some(ItemImpl {
@@ -2339,6 +2433,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ImplItem {
         fn parse(input: ParseStream) -> Result<Self> {
             let begin = input.fork();
@@ -2419,6 +2514,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ImplItemConst {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ImplItemConst {
@@ -2443,6 +2539,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ImplItemMethod {
         fn parse(input: ParseStream) -> Result<Self> {
             let mut attrs = input.call(Attribute::parse_outer)?;
@@ -2482,6 +2579,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ImplItemType {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(ImplItemType {
@@ -2533,6 +2631,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ImplItemMacro {
         fn parse(input: ParseStream) -> Result<Self> {
             let attrs = input.call(Attribute::parse_outer)?;
@@ -2578,6 +2677,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemExternCrate {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2593,6 +2693,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemUse {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2604,6 +2705,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemStatic {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2619,6 +2721,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemConst {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2633,6 +2736,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemFn {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2645,6 +2749,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemMod {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2662,6 +2767,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemForeignMod {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2673,6 +2779,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2687,6 +2794,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemEnum {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2701,6 +2809,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemStruct {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2726,6 +2835,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemUnion {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2738,6 +2848,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemTrait {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2753,11 +2864,13 @@
             }
             self.generics.where_clause.to_tokens(tokens);
             self.brace_token.surround(tokens, |tokens| {
+                tokens.append_all(self.attrs.inner());
                 tokens.append_all(&self.items);
             });
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemTraitAlias {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2772,6 +2885,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemImpl {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2793,6 +2907,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2814,6 +2929,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ItemMacro2 {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2824,6 +2940,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for UsePath {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.ident.to_tokens(tokens);
@@ -2832,12 +2949,14 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for UseName {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.ident.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for UseRename {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.ident.to_tokens(tokens);
@@ -2846,12 +2965,14 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for UseGlob {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.star_token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for UseGroup {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.brace_token.surround(tokens, |tokens| {
@@ -2860,6 +2981,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TraitItemConst {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2875,6 +2997,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TraitItemMethod {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2893,6 +3016,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TraitItemType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2912,6 +3036,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TraitItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2920,6 +3045,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ImplItemConst {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2935,6 +3061,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ImplItemMethod {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2956,6 +3083,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ImplItemType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2971,6 +3099,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ImplItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2979,6 +3108,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ForeignItemFn {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -2988,6 +3118,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ForeignItemStatic {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -3001,6 +3132,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ForeignItemType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -3011,6 +3143,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ForeignItemMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -3046,6 +3179,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Signature {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.constness.to_tokens(tokens);
@@ -3080,6 +3214,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Receiver {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
diff --git a/src/lib.rs b/src/lib.rs
index 3a34eaa..5cc3850 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,4 @@
-//! [![github]](https://github.com/dtolnay/syn)&ensp;[![crates-io]](https://crates.io/crates/syn)&ensp;[![docs-rs]](https://docs.rs/syn)
+//! [![github]](https://github.com/dtolnay/syn)&ensp;[![crates-io]](https://crates.io/crates/syn)&ensp;[![docs-rs]](crate)
 //!
 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
@@ -39,12 +39,12 @@
 //!   procedural macros enable only what they need, and do not pay in compile
 //!   time for all the rest.
 //!
-//! [`syn::File`]: struct.File.html
-//! [`syn::Item`]: enum.Item.html
-//! [`syn::Expr`]: enum.Expr.html
-//! [`syn::Type`]: enum.Type.html
-//! [`syn::DeriveInput`]: struct.DeriveInput.html
-//! [parser functions]: parse/index.html
+//! [`syn::File`]: File
+//! [`syn::Item`]: Item
+//! [`syn::Expr`]: Expr
+//! [`syn::Type`]: Type
+//! [`syn::DeriveInput`]: DeriveInput
+//! [parser functions]: mod@parse
 //!
 //! <br>
 //!
@@ -58,7 +58,7 @@
 //! tokens, then hand some tokens back to the compiler to compile into the
 //! user's crate.
 //!
-//! [`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
+//! [`TokenStream`]: proc_macro::TokenStream
 //!
 //! ```toml
 //! [dependencies]
@@ -250,24 +250,18 @@
 //!   dynamic library libproc_macro from rustc toolchain.
 
 // Syn types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/syn/1.0.48")]
-#![deny(clippy::all, clippy::pedantic)]
+#![doc(html_root_url = "https://docs.rs/syn/1.0.58")]
+#![cfg_attr(doc_cfg, feature(doc_cfg))]
 // Ignored clippy lints.
 #![allow(
-    clippy::blocks_in_if_conditions,
-    clippy::cognitive_complexity,
     clippy::doc_markdown,
     clippy::eval_order_dependence,
     clippy::inherent_to_string,
     clippy::large_enum_variant,
-    clippy::manual_non_exhaustive,
-    clippy::manual_strip,
-    clippy::match_like_matches_macro,
     clippy::match_on_vec_items,
     clippy::needless_doctest_main,
     clippy::needless_pass_by_value,
     clippy::never_loop,
-    clippy::suspicious_op_assign_impl,
     clippy::too_many_arguments,
     clippy::trivially_copy_pass_by_ref,
     clippy::unnecessary_unwrap
@@ -279,18 +273,17 @@
     clippy::empty_enum,
     clippy::expl_impl_clone_on_copy,
     clippy::if_not_else,
-    clippy::items_after_statements,
     clippy::match_same_arms,
     clippy::missing_errors_doc,
     clippy::module_name_repetitions,
     clippy::must_use_candidate,
     clippy::option_if_let_else,
+    clippy::redundant_else,
     clippy::shadow_unrelated,
     clippy::similar_names,
     clippy::single_match_else,
     clippy::too_many_lines,
     clippy::unseparated_literal_suffix,
-    clippy::use_self,
     clippy::used_underscore_binding,
     clippy::wildcard_imports
 )]
@@ -435,8 +428,10 @@
 };
 
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 pub mod buffer;
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 pub mod ext;
 pub mod punctuated;
 #[cfg(all(any(feature = "full", feature = "derive"), feature = "extra-traits"))]
@@ -457,6 +452,7 @@
 pub mod parse_macro_input;
 
 #[cfg(all(feature = "parsing", feature = "printing"))]
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "printing"))))]
 pub mod spanned;
 
 #[cfg(all(feature = "parsing", feature = "full"))]
@@ -580,6 +576,7 @@
     /// }
     /// ```
     #[cfg(feature = "visit")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "visit")))]
     #[rustfmt::skip]
     pub mod visit;
 
@@ -676,6 +673,7 @@
     /// }
     /// ```
     #[cfg(feature = "visit-mut")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "visit-mut")))]
     #[rustfmt::skip]
     pub mod visit_mut;
 
@@ -762,6 +760,7 @@
     /// }
     /// ```
     #[cfg(feature = "fold")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "fold")))]
     #[rustfmt::skip]
     pub mod fold;
 
@@ -789,7 +788,8 @@
 
 // Not public API.
 #[doc(hidden)]
-pub mod export;
+#[path = "export.rs"]
+pub mod __private;
 
 mod custom_keyword;
 mod custom_punctuation;
@@ -801,6 +801,7 @@
 mod lookahead;
 
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 pub mod parse;
 
 #[cfg(feature = "full")]
@@ -874,6 +875,7 @@
     feature = "parsing",
     feature = "proc-macro"
 ))]
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
 pub fn parse<T: parse::Parse>(tokens: proc_macro::TokenStream) -> Result<T> {
     parse::Parser::parse(T::parse, tokens)
 }
@@ -890,6 +892,7 @@
 ///
 /// *This function is available only if Syn is built with the `"parsing"` feature.*
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 pub fn parse2<T: parse::Parse>(tokens: proc_macro2::TokenStream) -> Result<T> {
     parse::Parser::parse2(T::parse, tokens)
 }
@@ -918,6 +921,7 @@
 /// # run().unwrap();
 /// ```
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 pub fn parse_str<T: parse::Parse>(s: &str) -> Result<T> {
     parse::Parser::parse_str(T::parse, s)
 }
@@ -960,6 +964,7 @@
 /// # run().unwrap();
 /// ```
 #[cfg(all(feature = "parsing", feature = "full"))]
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "full"))))]
 pub fn parse_file(mut content: &str) -> Result<File> {
     // Strip the BOM if it is present
     const BOM: &str = "\u{feff}";
diff --git a/src/lifetime.rs b/src/lifetime.rs
index 19f8a22..9cec5ee 100644
--- a/src/lifetime.rs
+++ b/src/lifetime.rs
@@ -16,9 +16,6 @@
 ///   the XID_Start property.
 /// - All following characters must be Unicode code points with the XID_Continue
 ///   property.
-///
-/// *This type is available only if Syn is built with the `"derive"` or `"full"`
-/// feature.*
 pub struct Lifetime {
     pub apostrophe: Span,
     pub ident: Ident,
@@ -116,6 +113,7 @@
     use super::*;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Lifetime {
         fn parse(input: ParseStream) -> Result<Self> {
             input.step(|cursor| {
@@ -133,6 +131,7 @@
     use proc_macro2::{Punct, Spacing, TokenStream};
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Lifetime {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let mut apostrophe = Punct::new('\'', Spacing::Joint);
diff --git a/src/lit.rs b/src/lit.rs
index e45b81b..d67ee88 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -21,10 +21,7 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: crate::Expr#syntax-tree-enums
     pub enum Lit {
         /// A UTF-8 string literal: `"foo"`.
         Str(LitStr),
@@ -173,6 +170,7 @@
     /// }
     /// ```
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse<T: Parse>(&self) -> Result<T> {
         self.parse_with(T::parse)
     }
@@ -202,6 +200,7 @@
     /// # }
     /// ```
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_with<F: Parser>(&self, parser: F) -> Result<F::Output> {
         use proc_macro2::Group;
 
@@ -511,6 +510,7 @@
     use super::*;
     use std::fmt::{self, Debug};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitStr {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -520,6 +520,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitByteStr {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -529,6 +530,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitByte {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -538,6 +540,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitChar {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -547,6 +550,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitInt {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -556,6 +560,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitFloat {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -565,6 +570,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
     impl Debug for LitBool {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter
@@ -576,6 +582,7 @@
 }
 
 #[cfg(feature = "clone-impls")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for LitRepr {
     fn clone(&self) -> Self {
         LitRepr {
@@ -586,6 +593,7 @@
 }
 
 #[cfg(feature = "clone-impls")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for LitIntRepr {
     fn clone(&self) -> Self {
         LitIntRepr {
@@ -597,6 +605,7 @@
 }
 
 #[cfg(feature = "clone-impls")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for LitFloatRepr {
     fn clone(&self) -> Self {
         LitFloatRepr {
@@ -610,6 +619,7 @@
 macro_rules! lit_extra_traits {
     ($ty:ident) => {
         #[cfg(feature = "clone-impls")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
         impl Clone for $ty {
             fn clone(&self) -> Self {
                 $ty {
@@ -619,6 +629,7 @@
         }
 
         #[cfg(feature = "extra-traits")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
         impl PartialEq for $ty {
             fn eq(&self, other: &Self) -> bool {
                 self.repr.token.to_string() == other.repr.token.to_string()
@@ -626,6 +637,7 @@
         }
 
         #[cfg(feature = "extra-traits")]
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
         impl Hash for $ty {
             fn hash<H>(&self, state: &mut H)
             where
@@ -685,6 +697,7 @@
     use crate::parse::{Parse, ParseStream, Result};
     use proc_macro2::Punct;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Lit {
         fn parse(input: ParseStream) -> Result<Self> {
             input.step(|cursor| {
@@ -756,6 +769,7 @@
         ))
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitStr {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -766,6 +780,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitByteStr {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -776,6 +791,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitByte {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -786,6 +802,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitChar {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -796,6 +813,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitInt {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -806,6 +824,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitFloat {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -816,6 +835,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for LitBool {
         fn parse(input: ParseStream) -> Result<Self> {
             let head = input.fork();
@@ -833,42 +853,49 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitStr {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.repr.token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitByteStr {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.repr.token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitByte {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.repr.token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitChar {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.repr.token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitInt {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.repr.token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitFloat {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.repr.token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for LitBool {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let s = if self.value { "true" } else { "false" };
@@ -1280,7 +1307,7 @@
 
     fn backslash_u(mut s: &str) -> (char, &str) {
         if byte(s, 0) != b'{' {
-            panic!("expected {{ after \\u");
+            panic!("{}", "expected { after \\u");
         }
         s = &s[1..];
 
diff --git a/src/mac.rs b/src/mac.rs
index 374400c..3d84f8e 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -12,6 +12,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Macro {
         pub path: Path,
         pub bang_token: Token![!],
@@ -25,6 +26,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum MacroDelimiter {
         Paren(Paren),
         Brace(Brace),
@@ -132,6 +134,7 @@
     /// }
     /// ```
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_body<T: Parse>(&self) -> Result<T> {
         self.parse_body_with(T::parse)
     }
@@ -139,6 +142,7 @@
     /// Parse the tokens within the macro invocation's delimiters using the
     /// given parser.
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_body_with<F: Parser>(&self, parser: F) -> Result<F::Output> {
         let scope = delimiter_span_close(&self.delimiter);
         crate::parse::parse_scoped(parser, scope, self.tokens.clone())
@@ -170,6 +174,7 @@
     use super::*;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Macro {
         fn parse(input: ParseStream) -> Result<Self> {
             let tokens;
@@ -193,6 +198,7 @@
     use proc_macro2::TokenStream;
     use quote::ToTokens;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Macro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.path.to_tokens(tokens);
diff --git a/src/macros.rs b/src/macros.rs
index 8060224..e0d0b81 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -132,6 +132,7 @@
     };
 
     (($($arms:tt)*) $tokens:ident $name:ident {}) => {
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
         impl ::quote::ToTokens for $name {
             fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
                 match self {
diff --git a/src/op.rs b/src/op.rs
index f9edc63..b8ef9a7 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -3,6 +3,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum BinOp {
         /// The `+` operator (addition)
         Add(Token![+]),
@@ -68,6 +69,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum UnOp {
         /// The `*` operator for dereferencing
         Deref(Token![*]),
@@ -125,6 +127,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for BinOp {
         #[cfg(not(feature = "full"))]
         fn parse(input: ParseStream) -> Result<Self> {
@@ -159,6 +162,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for UnOp {
         fn parse(input: ParseStream) -> Result<Self> {
             let lookahead = input.lookahead1();
@@ -181,6 +185,7 @@
     use proc_macro2::TokenStream;
     use quote::ToTokens;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for BinOp {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -216,6 +221,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for UnOp {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
diff --git a/src/parse.rs b/src/parse.rs
index f1aecad..d85968b 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -6,9 +6,8 @@
 //! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of
 //! tokens in a token stream.
 //!
-//! [`ParseStream`]: type.ParseStream.html
-//! [`Result<T>`]: type.Result.html
-//! [`Cursor`]: ../buffer/index.html
+//! [`Result<T>`]: Result
+//! [`Cursor`]: crate::buffer::Cursor
 //!
 //! # Example
 //!
@@ -23,7 +22,7 @@
 //! procedural macro, they will receive a helpful compiler error message
 //! pointing out the exact token that triggered the failure to parse.
 //!
-//! [`parse_macro_input!`]: ../macro.parse_macro_input.html
+//! [`parse_macro_input!`]: crate::parse_macro_input!
 //!
 //! ```
 //! # extern crate proc_macro;
@@ -96,10 +95,9 @@
 //! obvious default way. These functions can return any syntax tree node that
 //! implements the [`Parse`] trait, which includes most types in Syn.
 //!
-//! [`syn::parse`]: ../fn.parse.html
-//! [`syn::parse2`]: ../fn.parse2.html
-//! [`syn::parse_str`]: ../fn.parse_str.html
-//! [`Parse`]: trait.Parse.html
+//! [`syn::parse`]: crate::parse()
+//! [`syn::parse2`]: crate::parse2()
+//! [`syn::parse_str`]: crate::parse_str()
 //!
 //! ```
 //! use syn::Type;
@@ -114,7 +112,7 @@
 //!
 //! The [`parse_quote!`] macro also uses this approach.
 //!
-//! [`parse_quote!`]: ../macro.parse_quote.html
+//! [`parse_quote!`]: crate::parse_quote!
 //!
 //! # The `Parser` trait
 //!
@@ -124,8 +122,8 @@
 //! may or may not allow trailing punctuation, and parsing it the wrong way
 //! would either reject valid input or accept invalid input.
 //!
-//! [`Attribute`]: ../struct.Attribute.html
-//! [`Punctuated`]: ../punctuated/index.html
+//! [`Attribute`]: crate::Attribute
+//! [`Punctuated`]: crate::punctuated
 //!
 //! The `Parse` trait is not implemented in these cases because there is no good
 //! behavior to consider the default.
@@ -150,7 +148,6 @@
 //! single `Parse` implementation, and those parser functions can be invoked
 //! through the [`Parser`] trait.
 //!
-//! [`Parser`]: trait.Parser.html
 //!
 //! ```
 //! # extern crate proc_macro;
@@ -248,7 +245,7 @@
 /// - One of [the `syn::parse*` functions][syn-parse]; or
 /// - A method of the [`Parser`] trait.
 ///
-/// [syn-parse]: index.html#the-synparse-functions
+/// [syn-parse]: self#the-synparse-functions
 pub struct ParseBuffer<'a> {
     scope: Span,
     // Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a.
@@ -620,17 +617,36 @@
     /// }
     /// ```
     pub fn peek2<T: Peek>(&self, token: T) -> bool {
+        fn peek2(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
+            if let Some(group) = buffer.cursor().group(Delimiter::None) {
+                if group.0.skip().map_or(false, peek) {
+                    return true;
+                }
+            }
+            buffer.cursor().skip().map_or(false, peek)
+        }
+
         let _ = token;
-        self.cursor().skip().map_or(false, T::Token::peek)
+        peek2(self, T::Token::peek)
     }
 
     /// Looks at the third-next token in the parse stream.
     pub fn peek3<T: Peek>(&self, token: T) -> bool {
+        fn peek3(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
+            if let Some(group) = buffer.cursor().group(Delimiter::None) {
+                if group.0.skip().and_then(Cursor::skip).map_or(false, peek) {
+                    return true;
+                }
+            }
+            buffer
+                .cursor()
+                .skip()
+                .and_then(Cursor::skip)
+                .map_or(false, peek)
+        }
+
         let _ = token;
-        self.cursor()
-            .skip()
-            .and_then(Cursor::skip)
-            .map_or(false, T::Token::peek)
+        peek3(self, T::Token::peek)
     }
 
     /// Parses zero or more occurrences of `T` separated by punctuation of type
@@ -1043,12 +1059,14 @@
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl<T: Parse> Parse for Box<T> {
     fn parse(input: ParseStream) -> Result<Self> {
         input.parse().map(Box::new)
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl<T: Parse + Token> Parse for Option<T> {
     fn parse(input: ParseStream) -> Result<Self> {
         if T::peek(input.cursor()) {
@@ -1059,12 +1077,14 @@
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for TokenStream {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for TokenTree {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| match cursor.token_tree() {
@@ -1074,6 +1094,7 @@
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for Group {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| {
@@ -1089,6 +1110,7 @@
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for Punct {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| match cursor.punct() {
@@ -1098,6 +1120,7 @@
     }
 }
 
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for Literal {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| match cursor.literal() {
diff --git a/src/parse_macro_input.rs b/src/parse_macro_input.rs
index 79c0de4..8e1a5ec 100644
--- a/src/parse_macro_input.rs
+++ b/src/parse_macro_input.rs
@@ -104,20 +104,21 @@
 /// # }
 /// ```
 #[macro_export]
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
 macro_rules! parse_macro_input {
     ($tokenstream:ident as $ty:ty) => {
         match $crate::parse_macro_input::parse::<$ty>($tokenstream) {
-            $crate::export::Ok(data) => data,
-            $crate::export::Err(err) => {
-                return $crate::export::TokenStream::from(err.to_compile_error());
+            $crate::__private::Ok(data) => data,
+            $crate::__private::Err(err) => {
+                return $crate::__private::TokenStream::from(err.to_compile_error());
             }
         }
     };
     ($tokenstream:ident with $parser:path) => {
         match $crate::parse::Parser::parse($parser, $tokenstream) {
-            $crate::export::Ok(data) => data,
-            $crate::export::Err(err) => {
-                return $crate::export::TokenStream::from(err.to_compile_error());
+            $crate::__private::Ok(data) => data,
+            $crate::__private::Err(err) => {
+                return $crate::__private::TokenStream::from(err.to_compile_error());
             }
         }
     };
diff --git a/src/parse_quote.rs b/src/parse_quote.rs
index 772671b..ec551ef 100644
--- a/src/parse_quote.rs
+++ b/src/parse_quote.rs
@@ -69,12 +69,13 @@
 //
 // TODO: allow Punctuated to be inferred as intra doc link, currently blocked on
 // https://github.com/rust-lang/rust/issues/62834
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "printing"))))]
 #[macro_export]
 macro_rules! parse_quote {
     ($($tt:tt)*) => {
         $crate::parse_quote::parse(
-            $crate::export::From::from(
-                $crate::export::quote::quote!($($tt)*)
+            $crate::__private::From::from(
+                $crate::__private::quote::quote!($($tt)*)
             )
         )
     };
diff --git a/src/pat.rs b/src/pat.rs
index 473ee1c..5381076 100644
--- a/src/pat.rs
+++ b/src/pat.rs
@@ -12,10 +12,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum Pat {
         /// A box pattern: `box v`.
         Box(PatBox),
@@ -83,6 +81,7 @@
     /// A box pattern: `box v`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatBox {
         pub attrs: Vec<Attribute>,
         pub box_token: Token![box],
@@ -97,6 +96,7 @@
     /// constant; these cannot be distinguished syntactically.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatIdent {
         pub attrs: Vec<Attribute>,
         pub by_ref: Option<Token![ref]>,
@@ -113,6 +113,7 @@
     /// are represented as an `Expr::Unary`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatLit {
         pub attrs: Vec<Attribute>,
         pub expr: Box<Expr>,
@@ -123,6 +124,7 @@
     /// A macro in pattern position.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatMacro {
         pub attrs: Vec<Attribute>,
         pub mac: Macro,
@@ -133,6 +135,7 @@
     /// A pattern that matches any one of a set of cases.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatOr {
         pub attrs: Vec<Attribute>,
         pub leading_vert: Option<Token![|]>,
@@ -150,6 +153,7 @@
     /// associated constants.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatPath {
         pub attrs: Vec<Attribute>,
         pub qself: Option<QSelf>,
@@ -161,6 +165,7 @@
     /// A range pattern: `1..=2`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatRange {
         pub attrs: Vec<Attribute>,
         pub lo: Box<Expr>,
@@ -173,6 +178,7 @@
     /// A reference pattern: `&mut var`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatReference {
         pub attrs: Vec<Attribute>,
         pub and_token: Token![&],
@@ -185,6 +191,7 @@
     /// The dots in a tuple or slice pattern: `[0, 1, ..]`
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatRest {
         pub attrs: Vec<Attribute>,
         pub dot2_token: Token![..],
@@ -195,6 +202,7 @@
     /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatSlice {
         pub attrs: Vec<Attribute>,
         pub bracket_token: token::Bracket,
@@ -206,6 +214,7 @@
     /// A struct or struct variant pattern: `Variant { x, y, .. }`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatStruct {
         pub attrs: Vec<Attribute>,
         pub path: Path,
@@ -219,6 +228,7 @@
     /// A tuple pattern: `(a, b)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatTuple {
         pub attrs: Vec<Attribute>,
         pub paren_token: token::Paren,
@@ -230,6 +240,7 @@
     /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatTupleStruct {
         pub attrs: Vec<Attribute>,
         pub path: Path,
@@ -241,6 +252,7 @@
     /// A type ascription pattern: `foo: f64`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatType {
         pub attrs: Vec<Attribute>,
         pub pat: Box<Pat>,
@@ -253,6 +265,7 @@
     /// A pattern that matches any value: `_`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct PatWild {
         pub attrs: Vec<Attribute>,
         pub underscore_token: Token![_],
@@ -266,6 +279,7 @@
     /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct FieldPat {
         pub attrs: Vec<Attribute>,
         pub member: Member,
@@ -281,6 +295,7 @@
     use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
     use crate::path;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Pat {
         fn parse(input: ParseStream) -> Result<Self> {
             let begin = input.fork();
@@ -309,7 +324,8 @@
                 input.call(pat_wild).map(Pat::Wild)
             } else if input.peek(Token![box]) {
                 input.call(pat_box).map(Pat::Box)
-            } else if input.peek(Token![-]) || lookahead.peek(Lit) {
+            } else if input.peek(Token![-]) || lookahead.peek(Lit) || lookahead.peek(Token![const])
+            {
                 pat_lit_or_range(input)
             } else if lookahead.peek(Token![ref])
                 || lookahead.peek(Token![mut])
@@ -325,6 +341,8 @@
                 input.call(pat_slice).map(Pat::Slice)
             } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
                 pat_range_half_open(input, begin)
+            } else if lookahead.peek(Token![const]) {
+                input.call(pat_const).map(Pat::Verbatim)
             } else {
                 Err(lookahead.error())
             }
@@ -602,6 +620,8 @@
             } else {
                 Ok(Pat::Verbatim(verbatim::between(begin, input)))
             }
+        } else if let Expr::Verbatim(verbatim) = *lo {
+            Ok(Pat::Verbatim(verbatim))
         } else {
             Ok(Pat::Lit(PatLit {
                 attrs: Vec::new(),
@@ -635,6 +655,8 @@
             || lookahead.peek(Token![crate])
         {
             Expr::Path(input.parse()?)
+        } else if lookahead.peek(Token![const]) {
+            Expr::Verbatim(input.call(expr::parsing::expr_const)?)
         } else {
             return Err(lookahead.error());
         };
@@ -672,6 +694,18 @@
         })
     }
 
+    fn pat_const(input: ParseStream) -> Result<TokenStream> {
+        let begin = input.fork();
+        input.parse::<Token![const]>()?;
+
+        let content;
+        braced!(content in input);
+        content.call(Attribute::parse_inner)?;
+        content.call(Block::parse_within)?;
+
+        Ok(verbatim::between(begin, input))
+    }
+
     pub fn multi_pat(input: ParseStream) -> Result<Pat> {
         multi_pat_impl(input, None)
     }
@@ -711,6 +745,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatWild {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -718,6 +753,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatIdent {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -731,6 +767,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatStruct {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -746,6 +783,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatTupleStruct {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -754,6 +792,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -763,6 +802,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatPath {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -770,6 +810,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatTuple {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -779,6 +820,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatBox {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -787,6 +829,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatReference {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -796,6 +839,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatRest {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -803,6 +847,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatLit {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -810,6 +855,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatRange {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -822,6 +868,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatSlice {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -831,6 +878,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -838,6 +886,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PatOr {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -846,6 +895,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for FieldPat {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
diff --git a/src/path.rs b/src/path.rs
index 217a72e..601891e 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -6,6 +6,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Path {
         pub leading_colon: Option<Token![::]>,
         pub segments: Punctuated<PathSegment, Token![::]>,
@@ -31,6 +32,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct PathSegment {
         pub ident: Ident,
         pub arguments: PathArguments,
@@ -62,6 +64,7 @@
     /// ## Parenthesized
     ///
     /// The `(A, B) -> C` in `Fn(A, B) -> C`.
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum PathArguments {
         None,
         /// The `<'a, T>` in `std::slice::iter<'a, T>`.
@@ -100,6 +103,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum GenericArgument {
         /// A lifetime argument.
         Lifetime(Lifetime),
@@ -124,6 +128,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct AngleBracketedGenericArguments {
         pub colon2_token: Option<Token![::]>,
         pub lt_token: Token![<],
@@ -137,6 +142,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Binding {
         pub ident: Ident,
         pub eq_token: Token![=],
@@ -149,6 +155,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Constraint {
         pub ident: Ident,
         pub colon_token: Token![:],
@@ -162,6 +169,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct ParenthesizedGenericArguments {
         pub paren_token: token::Paren,
         /// `(A, B)`
@@ -191,6 +199,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct QSelf {
         pub lt_token: Token![<],
         pub ty: Box<Type>,
@@ -209,12 +218,14 @@
     use crate::ext::IdentExt;
     use crate::parse::{Parse, ParseStream, Result};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Path {
         fn parse(input: ParseStream) -> Result<Self> {
             Self::parse_helper(input, false)
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for GenericArgument {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Lifetime) && !input.peek2(Token![+]) {
@@ -230,12 +241,15 @@
                 if input.peek(Ident) && input.peek2(Token![:]) && !input.peek2(Token![::]) {
                     return Ok(GenericArgument::Constraint(input.parse()?));
                 }
+            }
 
-                if input.peek(Lit) {
-                    let lit = input.parse()?;
-                    return Ok(GenericArgument::Const(Expr::Lit(lit)));
-                }
+            if input.peek(Lit) {
+                let lit = input.parse()?;
+                return Ok(GenericArgument::Const(Expr::Lit(lit)));
+            }
 
+            #[cfg(feature = "full")]
+            {
                 if input.peek(token::Brace) {
                     let block = input.call(expr::parsing::expr_block)?;
                     return Ok(GenericArgument::Const(Expr::Block(block)));
@@ -246,6 +260,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for AngleBracketedGenericArguments {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(AngleBracketedGenericArguments {
@@ -272,6 +287,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ParenthesizedGenericArguments {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -283,6 +299,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for PathSegment {
         fn parse(input: ParseStream) -> Result<Self> {
             Self::parse_helper(input, false)
@@ -315,6 +332,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Binding {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(Binding {
@@ -326,6 +344,7 @@
     }
 
     #[cfg(feature = "full")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Constraint {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(Constraint {
@@ -385,6 +404,7 @@
         ///     }
         /// }
         /// ```
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn parse_mod_style(input: ParseStream) -> Result<Self> {
             Ok(Path {
                 leading_colon: input.parse()?,
@@ -448,6 +468,7 @@
         ///     }
         /// }
         /// ```
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn is_ident<I: ?Sized>(&self, ident: &I) -> bool
         where
             Ident: PartialEq<I>,
@@ -469,6 +490,7 @@
         ///
         /// *This function is available only if Syn is built with the `"parsing"`
         /// feature.*
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn get_ident(&self) -> Option<&Ident> {
             if self.leading_colon.is_none()
                 && self.segments.len() == 1
@@ -480,22 +502,32 @@
             }
         }
 
-        fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
-            Ok(Path {
+        pub(crate) fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
+            let mut path = Path {
                 leading_colon: input.parse()?,
                 segments: {
                     let mut segments = Punctuated::new();
                     let value = PathSegment::parse_helper(input, expr_style)?;
                     segments.push_value(value);
-                    while input.peek(Token![::]) {
-                        let punct: Token![::] = input.parse()?;
-                        segments.push_punct(punct);
-                        let value = PathSegment::parse_helper(input, expr_style)?;
-                        segments.push_value(value);
-                    }
                     segments
                 },
-            })
+            };
+            Path::parse_rest(input, &mut path, expr_style)?;
+            Ok(path)
+        }
+
+        pub(crate) fn parse_rest(
+            input: ParseStream,
+            path: &mut Self,
+            expr_style: bool,
+        ) -> Result<()> {
+            while input.peek(Token![::]) {
+                let punct: Token![::] = input.parse()?;
+                path.segments.push_punct(punct);
+                let value = PathSegment::parse_helper(input, expr_style)?;
+                path.segments.push_value(value);
+            }
+            Ok(())
         }
     }
 
@@ -560,6 +592,7 @@
     use quote::ToTokens;
     use std::cmp;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Path {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.leading_colon.to_tokens(tokens);
@@ -567,6 +600,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PathSegment {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.ident.to_tokens(tokens);
@@ -574,6 +608,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for PathArguments {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -588,6 +623,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for GenericArgument {
         #[allow(clippy::match_same_arms)]
         fn to_tokens(&self, tokens: &mut TokenStream) {
@@ -615,6 +651,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for AngleBracketedGenericArguments {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.colon2_token.to_tokens(tokens);
@@ -657,9 +694,9 @@
                     GenericArgument::Binding(_) | GenericArgument::Constraint(_) => {
                         if !trailing_or_empty {
                             <Token![,]>::default().to_tokens(tokens);
-                            trailing_or_empty = true;
                         }
                         param.to_tokens(tokens);
+                        trailing_or_empty = param.punct().is_some();
                     }
                     GenericArgument::Lifetime(_)
                     | GenericArgument::Type(_)
@@ -671,6 +708,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Binding {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.ident.to_tokens(tokens);
@@ -679,6 +717,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Constraint {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.ident.to_tokens(tokens);
@@ -687,6 +726,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ParenthesizedGenericArguments {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.paren_token.surround(tokens, |tokens| {
diff --git a/src/punctuated.rs b/src/punctuated.rs
index 46c82a6..4d34969 100644
--- a/src/punctuated.rs
+++ b/src/punctuated.rs
@@ -13,7 +13,7 @@
 //! syntax tree node + punctuation, where every node in the sequence is followed
 //! by punctuation except for possibly the final one.
 //!
-//! [`Punctuated<T, P>`]: struct.Punctuated.html
+//! [`Punctuated<T, P>`]: Punctuated
 //!
 //! ```text
 //! a_function_call(arg1, arg2, arg3);
@@ -50,7 +50,17 @@
 
 impl<T, P> Punctuated<T, P> {
     /// Creates an empty punctuated sequence.
-    pub fn new() -> Punctuated<T, P> {
+    #[cfg(not(syn_no_const_vec_new))]
+    pub const fn new() -> Self {
+        Punctuated {
+            inner: Vec::new(),
+            last: None,
+        }
+    }
+
+    /// Creates an empty punctuated sequence.
+    #[cfg(syn_no_const_vec_new)]
+    pub fn new() -> Self {
         Punctuated {
             inner: Vec::new(),
             last: None,
@@ -242,6 +252,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_terminated(input: ParseStream) -> Result<Self>
     where
         T: Parse,
@@ -262,6 +273,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_terminated_with(
         input: ParseStream,
         parser: fn(ParseStream) -> Result<T>,
@@ -298,6 +310,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
     where
         T: Parse,
@@ -318,6 +331,7 @@
     /// *This function is available only if Syn is built with the `"parsing"`
     /// feature.*
     #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     pub fn parse_separated_nonempty_with(
         input: ParseStream,
         parser: fn(ParseStream) -> Result<T>,
@@ -342,6 +356,7 @@
 }
 
 #[cfg(feature = "clone-impls")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl<T, P> Clone for Punctuated<T, P>
 where
     T: Clone,
@@ -356,6 +371,7 @@
 }
 
 #[cfg(feature = "extra-traits")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl<T, P> Eq for Punctuated<T, P>
 where
     T: Eq,
@@ -364,6 +380,7 @@
 }
 
 #[cfg(feature = "extra-traits")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl<T, P> PartialEq for Punctuated<T, P>
 where
     T: PartialEq,
@@ -376,6 +393,7 @@
 }
 
 #[cfg(feature = "extra-traits")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl<T, P> Hash for Punctuated<T, P>
 where
     T: Hash,
@@ -389,6 +407,7 @@
 }
 
 #[cfg(feature = "extra-traits")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut list = f.debug_list();
@@ -928,6 +947,7 @@
 }
 
 #[cfg(feature = "clone-impls")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl<T, P> Clone for Pair<T, P>
 where
     T: Clone,
@@ -975,6 +995,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl<T, P> ToTokens for Punctuated<T, P>
     where
         T: ToTokens,
@@ -985,6 +1006,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl<T, P> ToTokens for Pair<T, P>
     where
         T: ToTokens,
diff --git a/src/reserved.rs b/src/reserved.rs
index ccfb8b5..abfdf43 100644
--- a/src/reserved.rs
+++ b/src/reserved.rs
@@ -26,6 +26,7 @@
 }
 
 #[cfg(feature = "clone-impls")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
 impl Clone for Reserved {
     fn clone(&self) -> Self {
         Reserved {
@@ -35,6 +36,7 @@
 }
 
 #[cfg(feature = "extra-traits")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
 impl Debug for Reserved {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.debug_struct("Reserved").finish()
diff --git a/src/spanned.rs b/src/spanned.rs
index 01591ce..d51ffb3 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -13,8 +13,8 @@
 //! of a struct for which we are deriving a trait implementation, and we need to
 //! be able to pass a reference to one of those fields across threads.
 //!
-//! [`Type`]: ../enum.Type.html
-//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
+//! [`Type`]: crate::Type
+//! [`Sync`]: std::marker::Sync
 //!
 //! If the field type does *not* implement `Sync` as required, we want the
 //! compiler to report an error pointing out exactly which type it was.
diff --git a/src/stmt.rs b/src/stmt.rs
index 873e713..ba2b22e 100644
--- a/src/stmt.rs
+++ b/src/stmt.rs
@@ -4,6 +4,7 @@
     /// A braced block containing Rust statements.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct Block {
         pub brace_token: token::Brace,
         /// Statements in a block
@@ -15,6 +16,7 @@
     /// A statement, usually ending in a semicolon.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub enum Stmt {
         /// A local (let) binding.
         Local(Local),
@@ -34,6 +36,7 @@
     /// A local `let` binding: `let x: u64 = s.parse()?`.
     ///
     /// *This type is available only if Syn is built with the `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
     pub struct Local {
         pub attrs: Vec<Attribute>,
         pub let_token: Token![let],
@@ -103,6 +106,7 @@
         ///     }
         /// }
         /// ```
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn parse_within(input: ParseStream) -> Result<Vec<Stmt>> {
             let mut stmts = Vec::new();
             loop {
@@ -129,6 +133,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Block {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -139,6 +144,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Stmt {
         fn parse(input: ParseStream) -> Result<Self> {
             parse_stmt(input, false)
@@ -165,7 +171,7 @@
             || input.peek(Token![extern])
             || input.peek(Token![use])
             || input.peek(Token![static]) && (input.peek2(Token![mut]) || input.peek2(Ident))
-            || input.peek(Token![const])
+            || input.peek(Token![const]) && !input.peek2(token::Brace)
             || input.peek(Token![unsafe]) && !input.peek2(token::Brace)
             || input.peek(Token![async])
                 && (input.peek2(Token![unsafe])
@@ -276,6 +282,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Block {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.brace_token.surround(tokens, |tokens| {
@@ -284,6 +291,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Stmt {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -298,6 +306,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Local {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             expr::printing::outer_attrs_to_tokens(&self.attrs, tokens);
diff --git a/src/token.rs b/src/token.rs
index e5c6d1f..2208b07 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -4,13 +4,13 @@
 //! prefer to use the [`Token!`] macro instead. This is a type-macro that
 //! expands to the token type of the given token.
 //!
-//! [`Token!`]: ../macro.Token.html
+//! [`Token!`]: crate::Token
 //!
 //! # Example
 //!
 //! The [`ItemStatic`] syntax tree node is defined like this.
 //!
-//! [`ItemStatic`]: ../struct.ItemStatic.html
+//! [`ItemStatic`]: crate::ItemStatic
 //!
 //! ```
 //! # use syn::{Attribute, Expr, Ident, Token, Type, Visibility};
@@ -35,10 +35,10 @@
 //! method. Delimiter tokens are parsed using the [`parenthesized!`],
 //! [`bracketed!`] and [`braced!`] macros.
 //!
-//! [`ParseStream::parse`]: ../parse/struct.ParseBuffer.html#method.parse
-//! [`parenthesized!`]: ../macro.parenthesized.html
-//! [`bracketed!`]: ../macro.bracketed.html
-//! [`braced!`]: ../macro.braced.html
+//! [`ParseStream::parse`]: crate::parse::ParseBuffer::parse()
+//! [`parenthesized!`]: crate::parenthesized!
+//! [`bracketed!`]: crate::bracketed!
+//! [`braced!`]: crate::braced!
 //!
 //! ```
 //! use syn::{Attribute, Result};
@@ -83,8 +83,8 @@
 //!
 //! - Field access to its span — `let sp = the_token.span`
 //!
-//! [Peeking]: ../parse/struct.ParseBuffer.html#method.peek
-//! [Parsing]: ../parse/struct.ParseBuffer.html#method.parse
+//! [Peeking]: crate::parse::ParseBuffer::peek()
+//! [Parsing]: crate::parse::ParseBuffer::parse()
 //! [Printing]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html
 //! [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
 
@@ -268,9 +268,11 @@
             }
 
             #[cfg(feature = "clone-impls")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
             impl Copy for $name {}
 
             #[cfg(feature = "clone-impls")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
             impl Clone for $name {
                 fn clone(&self) -> Self {
                     *self
@@ -278,6 +280,7 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl Debug for $name {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     f.write_str(stringify!($name))
@@ -285,9 +288,11 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl cmp::Eq for $name {}
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl PartialEq for $name {
                 fn eq(&self, _other: &$name) -> bool {
                     true
@@ -295,11 +300,13 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl Hash for $name {
                 fn hash<H: Hasher>(&self, _state: &mut H) {}
             }
 
             #[cfg(feature = "printing")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
             impl ToTokens for $name {
                 fn to_tokens(&self, tokens: &mut TokenStream) {
                     printing::keyword($token, self.span, tokens);
@@ -307,6 +314,7 @@
             }
 
             #[cfg(feature = "parsing")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
             impl Parse for $name {
                 fn parse(input: ParseStream) -> Result<Self> {
                     Ok($name {
@@ -383,9 +391,11 @@
             }
 
             #[cfg(feature = "clone-impls")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
             impl Copy for $name {}
 
             #[cfg(feature = "clone-impls")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
             impl Clone for $name {
                 fn clone(&self) -> Self {
                     *self
@@ -393,6 +403,7 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl Debug for $name {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     f.write_str(stringify!($name))
@@ -400,9 +411,11 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl cmp::Eq for $name {}
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl PartialEq for $name {
                 fn eq(&self, _other: &$name) -> bool {
                     true
@@ -410,6 +423,7 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl Hash for $name {
                 fn hash<H: Hasher>(&self, _state: &mut H) {}
             }
@@ -427,6 +441,7 @@
             }
 
             #[cfg(feature = "printing")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
             impl ToTokens for $name {
                 fn to_tokens(&self, tokens: &mut TokenStream) {
                     printing::punct($token, &self.spans, tokens);
@@ -434,6 +449,7 @@
             }
 
             #[cfg(feature = "parsing")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
             impl Parse for $name {
                 fn parse(input: ParseStream) -> Result<Self> {
                     Ok($name {
@@ -484,9 +500,11 @@
             }
 
             #[cfg(feature = "clone-impls")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
             impl Copy for $name {}
 
             #[cfg(feature = "clone-impls")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
             impl Clone for $name {
                 fn clone(&self) -> Self {
                     *self
@@ -494,6 +512,7 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl Debug for $name {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     f.write_str(stringify!($name))
@@ -501,9 +520,11 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl cmp::Eq for $name {}
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl PartialEq for $name {
                 fn eq(&self, _other: &$name) -> bool {
                     true
@@ -511,6 +532,7 @@
             }
 
             #[cfg(feature = "extra-traits")]
+            #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
             impl Hash for $name {
                 fn hash<H: Hasher>(&self, _state: &mut H) {}
             }
@@ -536,6 +558,7 @@
 }
 
 #[cfg(feature = "printing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
 impl ToTokens for Underscore {
     fn to_tokens(&self, tokens: &mut TokenStream) {
         tokens.append(Ident::new("_", self.span));
@@ -543,6 +566,7 @@
 }
 
 #[cfg(feature = "parsing")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
 impl Parse for Underscore {
     fn parse(input: ParseStream) -> Result<Self> {
         input.step(|cursor| {
diff --git a/src/ty.rs b/src/ty.rs
index fb90e26..eacae3b 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -12,10 +12,8 @@
     ///
     /// This type is a [syntax tree enum].
     ///
-    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
-    //
-    // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
-    // blocked on https://github.com/rust-lang/rust/issues/62833
+    /// [syntax tree enum]: Expr#syntax-tree-enums
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum Type {
         /// A fixed size array type: `[T; n]`.
         Array(TypeArray),
@@ -75,6 +73,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeArray {
         pub bracket_token: token::Bracket,
         pub elem: Box<Type>,
@@ -88,6 +87,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeBareFn {
         pub lifetimes: Option<BoundLifetimes>,
         pub unsafety: Option<Token![unsafe]>,
@@ -105,6 +105,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeGroup {
         pub group_token: token::Group,
         pub elem: Box<Type>,
@@ -117,6 +118,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeImplTrait {
         pub impl_token: Token![impl],
         pub bounds: Punctuated<TypeParamBound, Token![+]>,
@@ -128,6 +130,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeInfer {
         pub underscore_token: Token![_],
     }
@@ -138,6 +141,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeMacro {
         pub mac: Macro,
     }
@@ -148,6 +152,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeNever {
         pub bang_token: Token![!],
     }
@@ -158,6 +163,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeParen {
         pub paren_token: token::Paren,
         pub elem: Box<Type>,
@@ -170,6 +176,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypePath {
         pub qself: Option<QSelf>,
         pub path: Path,
@@ -181,6 +188,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypePtr {
         pub star_token: Token![*],
         pub const_token: Option<Token![const]>,
@@ -194,6 +202,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeReference {
         pub and_token: Token![&],
         pub lifetime: Option<Lifetime>,
@@ -207,6 +216,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeSlice {
         pub bracket_token: token::Bracket,
         pub elem: Box<Type>,
@@ -219,6 +229,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeTraitObject {
         pub dyn_token: Option<Token![dyn]>,
         pub bounds: Punctuated<TypeParamBound, Token![+]>,
@@ -230,6 +241,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or
     /// `"full"` feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct TypeTuple {
         pub paren_token: token::Paren,
         pub elems: Punctuated<Type, Token![,]>,
@@ -241,6 +253,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Abi {
         pub extern_token: Token![extern],
         pub name: Option<LitStr>,
@@ -252,6 +265,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct BareFnArg {
         pub attrs: Vec<Attribute>,
         pub name: Option<(Ident, Token![:])>,
@@ -274,6 +288,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub struct Variadic {
         pub attrs: Vec<Attribute>,
         pub dots: Token![...],
@@ -285,6 +300,7 @@
     ///
     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
     /// feature.*
+    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum ReturnType {
         /// Return type is not specified.
         ///
@@ -304,6 +320,7 @@
     use proc_macro2::{Punct, Spacing, TokenTree};
     use std::iter::FromIterator;
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Type {
         fn parse(input: ParseStream) -> Result<Self> {
             let allow_plus = true;
@@ -317,6 +334,7 @@
         /// contain a `+` character.
         ///
         /// This parser does not allow a `+`, while the default parser does.
+        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
         pub fn without_plus(input: ParseStream) -> Result<Self> {
             let allow_plus = false;
             ambig_ty(input, allow_plus)
@@ -324,11 +342,41 @@
     }
 
     fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
-        if input.peek(token::Group) && !input.peek2(Token![::]) && !input.peek2(Token![<]) {
-            return input.parse().map(Type::Group);
+        let begin = input.fork();
+
+        if input.peek(token::Group) {
+            let mut group: TypeGroup = input.parse()?;
+            if input.peek(Token![::]) && input.peek3(Ident::peek_any) {
+                if let Type::Path(mut ty) = *group.elem {
+                    Path::parse_rest(input, &mut ty.path, false)?;
+                    return Ok(Type::Path(ty));
+                } else {
+                    return Ok(Type::Path(TypePath {
+                        qself: Some(QSelf {
+                            lt_token: Token![<](group.group_token.span),
+                            position: 0,
+                            as_token: None,
+                            gt_token: Token![>](group.group_token.span),
+                            ty: group.elem,
+                        }),
+                        path: Path::parse_helper(input, false)?,
+                    }));
+                }
+            } else if input.peek(Token![<]) || input.peek(Token![::]) && input.peek3(Token![<]) {
+                if let Type::Path(mut ty) = *group.elem {
+                    let arguments = &mut ty.path.segments.last_mut().unwrap().arguments;
+                    if let PathArguments::None = arguments {
+                        *arguments = PathArguments::AngleBracketed(input.parse()?);
+                        Path::parse_rest(input, &mut ty.path, false)?;
+                        return Ok(Type::Path(ty));
+                    } else {
+                        group.elem = Box::new(Type::Path(ty));
+                    }
+                }
+            }
+            return Ok(Type::Group(group));
         }
 
-        let begin = input.fork();
         let mut lifetimes = None::<BoundLifetimes>;
         let mut lookahead = input.lookahead1();
         if lookahead.peek(Token![for]) {
@@ -566,6 +614,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeSlice {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -576,6 +625,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeArray {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -588,6 +638,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypePtr {
         fn parse(input: ParseStream) -> Result<Self> {
             let star_token: Token![*] = input.parse()?;
@@ -610,6 +661,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeReference {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(TypeReference {
@@ -622,6 +674,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeBareFn {
         fn parse(input: ParseStream) -> Result<Self> {
             let allow_mut_self = false;
@@ -679,6 +732,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeNever {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(TypeNever {
@@ -687,6 +741,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeInfer {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(TypeInfer {
@@ -695,6 +750,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeTuple {
         fn parse(input: ParseStream) -> Result<Self> {
             let content;
@@ -723,6 +779,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeMacro {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(TypeMacro {
@@ -731,6 +788,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypePath {
         fn parse(input: ParseStream) -> Result<Self> {
             let (qself, mut path) = path::parsing::qpath(input, false)?;
@@ -763,12 +821,14 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for ReturnType {
         fn parse(input: ParseStream) -> Result<Self> {
             Self::parse(input, true)
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeTraitObject {
         fn parse(input: ParseStream) -> Result<Self> {
             Self::parse(input, true)
@@ -821,6 +881,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeImplTrait {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(TypeImplTrait {
@@ -842,6 +903,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeGroup {
         fn parse(input: ParseStream) -> Result<Self> {
             let group = crate::group::parse_group(input)?;
@@ -852,6 +914,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for TypeParen {
         fn parse(input: ParseStream) -> Result<Self> {
             let allow_plus = false;
@@ -869,6 +932,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for BareFnArg {
         fn parse(input: ParseStream) -> Result<Self> {
             let allow_mut_self = false;
@@ -940,6 +1004,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Abi {
         fn parse(input: ParseStream) -> Result<Self> {
             Ok(Abi {
@@ -949,6 +1014,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
     impl Parse for Option<Abi> {
         fn parse(input: ParseStream) -> Result<Self> {
             if input.peek(Token![extern]) {
@@ -968,6 +1034,7 @@
     use proc_macro2::TokenStream;
     use quote::{ToTokens, TokenStreamExt};
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeSlice {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.bracket_token.surround(tokens, |tokens| {
@@ -976,6 +1043,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeArray {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.bracket_token.surround(tokens, |tokens| {
@@ -986,6 +1054,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypePtr {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.star_token.to_tokens(tokens);
@@ -999,6 +1068,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeReference {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.and_token.to_tokens(tokens);
@@ -1008,6 +1078,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeBareFn {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.lifetimes.to_tokens(tokens);
@@ -1028,12 +1099,14 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeNever {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.bang_token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeTuple {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.paren_token.surround(tokens, |tokens| {
@@ -1042,12 +1115,14 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypePath {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             private::print_path(tokens, &self.qself, &self.path);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeTraitObject {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.dyn_token.to_tokens(tokens);
@@ -1055,6 +1130,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeImplTrait {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.impl_token.to_tokens(tokens);
@@ -1062,6 +1138,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeGroup {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.group_token.surround(tokens, |tokens| {
@@ -1070,6 +1147,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeParen {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.paren_token.surround(tokens, |tokens| {
@@ -1078,18 +1156,21 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeInfer {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.underscore_token.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for TypeMacro {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.mac.to_tokens(tokens);
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for ReturnType {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             match self {
@@ -1102,6 +1183,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for BareFnArg {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -1113,6 +1195,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Variadic {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             tokens.append_all(self.attrs.outer());
@@ -1120,6 +1203,7 @@
         }
     }
 
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
     impl ToTokens for Abi {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             self.extern_token.to_tokens(tokens);
diff --git a/tests/common/eq.rs b/tests/common/eq.rs
index 4ec910b..8690769 100644
--- a/tests/common/eq.rs
+++ b/tests/common/eq.rs
@@ -1,7 +1,6 @@
 extern crate rustc_ast;
 extern crate rustc_data_structures;
 extern crate rustc_span;
-extern crate rustc_target;
 
 use rustc_ast::ast::{
     AngleBracketedArg, AngleBracketedArgs, AnonConst, Arm, AssocItemKind, AssocTyConstraint,
@@ -15,20 +14,19 @@
     LlvmInlineAsm, LlvmInlineAsmOutput, Local, MacArgs, MacCall, MacCallStmt, MacDelimiter,
     MacStmtStyle, MacroDef, Mod, Movability, MutTy, Mutability, NodeId, Param, ParenthesizedArgs,
     Pat, PatKind, Path, PathSegment, PolyTraitRef, QSelf, RangeEnd, RangeLimits, RangeSyntax, Stmt,
-    StmtKind, StrLit, StrStyle, StructField, TraitBoundModifier, TraitObjectSyntax, TraitRef, Ty,
-    TyKind, UintTy, UnOp, Unsafe, UnsafeSource, UseTree, UseTreeKind, Variant, VariantData,
-    Visibility, VisibilityKind, WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
-    WhereRegionPredicate,
+    StmtKind, StrLit, StrStyle, StructField, StructRest, TraitBoundModifier, TraitObjectSyntax,
+    TraitRef, Ty, TyKind, UintTy, UnOp, Unsafe, UnsafeSource, UseTree, UseTreeKind, Variant,
+    VariantData, Visibility, VisibilityKind, WhereBoundPredicate, WhereClause, WhereEqPredicate,
+    WherePredicate, WhereRegionPredicate,
 };
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, CommentKind, DelimToken, Token, TokenKind};
-use rustc_ast::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
+use rustc_ast::token::{self, CommentKind, DelimToken, Nonterminal, Token, TokenKind};
+use rustc_ast::tokenstream::{self, DelimSpan, LazyTokenStream, TokenStream, TokenTree};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::Ident;
-use rustc_span::{Span, Symbol, SyntaxContext};
-use std::mem;
+use rustc_span::symbol::{sym, Ident};
+use rustc_span::{Span, Symbol, SyntaxContext, DUMMY_SP};
 
 pub trait SpanlessEq {
     fn eq(&self, other: &Self) -> bool;
@@ -91,7 +89,7 @@
 }
 
 macro_rules! spanless_eq_true {
-    ($name:ident) => {
+    ($name:ty) => {
         impl SpanlessEq for $name {
             fn eq(&self, _other: &Self) -> bool {
                 true
@@ -107,7 +105,7 @@
 spanless_eq_true!(SyntaxContext);
 
 macro_rules! spanless_eq_partial_eq {
-    ($name:ident) => {
+    ($name:ty) => {
         impl SpanlessEq for $name {
             fn eq(&self, other: &Self) -> bool {
                 PartialEq::eq(self, other)
@@ -127,73 +125,74 @@
 spanless_eq_partial_eq!(CommentKind);
 spanless_eq_partial_eq!(DelimToken);
 spanless_eq_partial_eq!(InlineAsmOptions);
+spanless_eq_partial_eq!(token::LitKind);
 
 macro_rules! spanless_eq_struct {
     {
-        $name:ident $(<$param:ident>)?;
+        $($name:ident)::+ $(<$param:ident>)?;
         $([$field:ident $other:ident])*
         $(![$ignore:ident])*
     } => {
-        impl $(<$param: SpanlessEq>)* SpanlessEq for $name $(<$param>)* {
+        impl $(<$param: SpanlessEq>)* SpanlessEq for $($name)::+ $(<$param>)* {
             fn eq(&self, other: &Self) -> bool {
-                let $name { $($field,)* $($ignore: _,)* } = self;
-                let $name { $($field: $other,)* $($ignore: _,)* } = other;
-                $(SpanlessEq::eq($field, $other))&&*
+                let $($name)::+ { $($field,)* $($ignore: _,)* } = self;
+                let $($name)::+ { $($field: $other,)* $($ignore: _,)* } = other;
+                true $(&& SpanlessEq::eq($field, $other))*
             }
         }
     };
 
     {
-        $name:ident $(<$param:ident>)?;
+        $($name:ident)::+ $(<$param:ident>)?;
         $([$field:ident $other:ident])*
+        $(![$ignore:ident])*
         $next:ident
-        $($rest:ident)*
-        $(!$ignore:ident)*
+        $($rest:tt)*
     } => {
         spanless_eq_struct! {
-            $name $(<$param>)*;
+            $($name)::+ $(<$param>)*;
             $([$field $other])*
             [$next other]
+            $(![$ignore])*
             $($rest)*
-            $(!$ignore)*
         }
     };
 
     {
-        $name:ident $(<$param:ident>)?;
+        $($name:ident)::+ $(<$param:ident>)?;
         $([$field:ident $other:ident])*
         $(![$ignore:ident])*
         !$next:ident
-        $(!$rest:ident)*
+        $($rest:tt)*
     } => {
         spanless_eq_struct! {
-            $name $(<$param>)*;
+            $($name)::+ $(<$param>)*;
             $([$field $other])*
             $(![$ignore])*
             ![$next]
-            $(!$rest)*
+            $($rest)*
         }
     };
 }
 
 macro_rules! spanless_eq_enum {
     {
-        $name:ident;
-        $([$variant:ident $([$field:tt $this:ident $other:ident])*])*
+        $($name:ident)::+;
+        $([$($variant:ident)::+; $([$field:tt $this:ident $other:ident])* $(![$ignore:tt])*])*
     } => {
-        impl SpanlessEq for $name {
+        impl SpanlessEq for $($name)::+ {
             fn eq(&self, other: &Self) -> bool {
                 match self {
                     $(
-                        $name::$variant { .. } => {}
+                        $($variant)::+ { .. } => {}
                     )*
                 }
                 #[allow(unreachable_patterns)]
                 match (self, other) {
                     $(
                         (
-                            $name::$variant { $($field: $this),* },
-                            $name::$variant { $($field: $other),* },
+                            $($variant)::+ { $($field: $this,)* $($ignore: _,)* },
+                            $($variant)::+ { $($field: $other,)* $($ignore: _,)* },
                         ) => {
                             true $(&& SpanlessEq::eq($this, $other))*
                         }
@@ -205,57 +204,71 @@
     };
 
     {
-        $name:ident;
-        $([$variant:ident $($fields:tt)*])*
-        $next:ident [$($named:tt)*] ( $i:tt $($field:tt)* )
+        $($name:ident)::+;
+        $([$($variant:ident)::+; $($fields:tt)*])*
+        $next:ident [$([$($named:tt)*])* $(![$ignore:tt])*] (!$i:tt $($field:tt)*)
         $($rest:tt)*
     } => {
         spanless_eq_enum! {
-            $name;
-            $([$variant $($fields)*])*
-            $next [$($named)* [$i this other]] ( $($field)* )
+            $($name)::+;
+            $([$($variant)::+; $($fields)*])*
+            $next [$([$($named)*])* $(![$ignore])* ![$i]] ($($field)*)
             $($rest)*
         }
     };
 
     {
-        $name:ident;
-        $([$variant:ident $($fields:tt)*])*
+        $($name:ident)::+;
+        $([$($variant:ident)::+; $($fields:tt)*])*
+        $next:ident [$([$($named:tt)*])* $(![$ignore:tt])*] ($i:tt $($field:tt)*)
+        $($rest:tt)*
+    } => {
+        spanless_eq_enum! {
+            $($name)::+;
+            $([$($variant)::+; $($fields)*])*
+            $next [$([$($named)*])* [$i this other] $(![$ignore])*] ($($field)*)
+            $($rest)*
+        }
+    };
+
+    {
+        $($name:ident)::+;
+        $([$($variant:ident)::+; $($fields:tt)*])*
         $next:ident [$($named:tt)*] ()
         $($rest:tt)*
     } => {
         spanless_eq_enum! {
-            $name;
-            $([$variant $($fields)*])*
-            [$next $($named)*]
+            $($name)::+;
+            $([$($variant)::+; $($fields)*])*
+            [$($name)::+::$next; $($named)*]
             $($rest)*
         }
     };
 
     {
-        $name:ident;
-        $([$variant:ident $($fields:tt)*])*
-        $next:ident ( $($field:tt)* )
+        $($name:ident)::+;
+        $([$($variant:ident)::+; $($fields:tt)*])*
+        $next:ident ($($field:tt)*)
         $($rest:tt)*
     } => {
         spanless_eq_enum! {
-            $name;
-            $([$variant $($fields)*])*
-            $next [] ( $($field)* )
+            $($name)::+;
+            $([$($variant)::+; $($fields)*])*
+            $next [] ($($field)*)
             $($rest)*
         }
     };
 
     {
-        $name:ident;
-        $([$variant:ident $($fields:tt)*])*
+        $($name:ident)::+;
+        $([$($variant:ident)::+; $($fields:tt)*])*
         $next:ident
         $($rest:tt)*
     } => {
         spanless_eq_enum! {
-            $name;
-            $([$variant $($fields)*])*
-            [$next]
+            $($name)::+;
+            $([$($variant)::+; $($fields)*])*
+            [$($name)::+::$next;]
             $($rest)*
         }
     };
@@ -264,7 +277,7 @@
 spanless_eq_struct!(AngleBracketedArgs; span args);
 spanless_eq_struct!(AnonConst; id value);
 spanless_eq_struct!(Arm; attrs pat guard body span id is_placeholder);
-spanless_eq_struct!(AssocTyConstraint; id ident kind span);
+spanless_eq_struct!(AssocTyConstraint; id ident gen_args kind span);
 spanless_eq_struct!(AttrItem; path args tokens);
 spanless_eq_struct!(Attribute; kind id style span);
 spanless_eq_struct!(BareFnTy; unsafety ext generic_params decl);
@@ -288,37 +301,36 @@
 spanless_eq_struct!(Lit; token kind span);
 spanless_eq_struct!(LlvmInlineAsm; asm asm_str_style outputs inputs clobbers volatile alignstack dialect);
 spanless_eq_struct!(LlvmInlineAsmOutput; constraint expr is_rw is_indirect);
-spanless_eq_struct!(Local; pat ty init id span attrs);
+spanless_eq_struct!(Local; pat ty init id span attrs !tokens);
 spanless_eq_struct!(MacCall; path args prior_type_ascription);
-spanless_eq_struct!(MacCallStmt; mac style attrs);
+spanless_eq_struct!(MacCallStmt; mac style attrs tokens);
 spanless_eq_struct!(MacroDef; body macro_rules);
 spanless_eq_struct!(Mod; inner unsafety items inline);
 spanless_eq_struct!(MutTy; ty mutbl);
-spanless_eq_struct!(Param; attrs ty pat id span is_placeholder);
 spanless_eq_struct!(ParenthesizedArgs; span inputs output);
 spanless_eq_struct!(Pat; id kind span tokens);
 spanless_eq_struct!(Path; span segments tokens);
 spanless_eq_struct!(PathSegment; ident id args);
 spanless_eq_struct!(PolyTraitRef; bound_generic_params trait_ref span);
 spanless_eq_struct!(QSelf; ty path_span position);
-spanless_eq_struct!(Stmt; id kind span tokens);
+spanless_eq_struct!(Stmt; id kind span);
 spanless_eq_struct!(StrLit; style symbol suffix span symbol_unescaped);
 spanless_eq_struct!(StructField; attrs id span vis ident ty is_placeholder);
 spanless_eq_struct!(Token; kind span);
 spanless_eq_struct!(TraitRef; path ref_id);
 spanless_eq_struct!(Ty; id kind span tokens);
 spanless_eq_struct!(UseTree; prefix kind span);
-spanless_eq_struct!(Variant; attrs id span vis ident data disr_expr is_placeholder);
+spanless_eq_struct!(Variant; attrs id span !vis ident data disr_expr is_placeholder);
 spanless_eq_struct!(Visibility; kind span tokens);
 spanless_eq_struct!(WhereBoundPredicate; span bound_generic_params bounded_ty bounds);
 spanless_eq_struct!(WhereClause; has_where_token predicates span);
 spanless_eq_struct!(WhereEqPredicate; id span lhs_ty rhs_ty);
 spanless_eq_struct!(WhereRegionPredicate; span lifetime bounds);
+spanless_eq_struct!(token::Lit; kind symbol suffix);
 spanless_eq_enum!(AngleBracketedArg; Arg(0) Constraint(0));
 spanless_eq_enum!(AssocItemKind; Const(0 1 2) Fn(0 1 2 3) TyAlias(0 1 2 3) MacCall(0));
 spanless_eq_enum!(AssocTyConstraintKind; Equality(ty) Bound(bounds));
 spanless_eq_enum!(Async; Yes(span closure_id return_impl_trait_id) No);
-spanless_eq_enum!(AttrKind; Normal(0) DocComment(0 1));
 spanless_eq_enum!(AttrStyle; Outer Inner);
 spanless_eq_enum!(BinOpKind; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt);
 spanless_eq_enum!(BindingMode; ByRef(0) ByValue(0));
@@ -335,7 +347,7 @@
 spanless_eq_enum!(GenericArg; Lifetime(0) Type(0) Const(0));
 spanless_eq_enum!(GenericArgs; AngleBracketed(0) Parenthesized(0));
 spanless_eq_enum!(GenericBound; Trait(0 1) Outlives(0));
-spanless_eq_enum!(GenericParamKind; Lifetime Type(default) Const(ty kw_span));
+spanless_eq_enum!(GenericParamKind; Lifetime Type(default) Const(ty kw_span default));
 spanless_eq_enum!(ImplPolarity; Positive Negative(0));
 spanless_eq_enum!(InlineAsmRegOrRegClass; Reg(0) RegClass(0));
 spanless_eq_enum!(InlineAsmTemplatePiece; String(0) Placeholder(operand_idx modifier span));
@@ -353,6 +365,7 @@
 spanless_eq_enum!(RangeLimits; HalfOpen Closed);
 spanless_eq_enum!(StmtKind; Local(0) Item(0) Expr(0) Semi(0) Empty MacCall(0));
 spanless_eq_enum!(StrStyle; Cooked Raw(0));
+spanless_eq_enum!(StructRest; Base(0) Rest(0) None);
 spanless_eq_enum!(TokenTree; Token(0) Delimited(0 1 2));
 spanless_eq_enum!(TraitBoundModifier; None Maybe MaybeConst MaybeConstMaybe);
 spanless_eq_enum!(TraitObjectSyntax; Dyn None);
@@ -368,9 +381,10 @@
     MethodCall(0 1 2) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1)
     Let(0 1) If(0 1 2) While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) Match(0 1)
     Closure(0 1 2 3 4 5) Block(0 1) Async(0 1 2) Await(0) TryBlock(0)
-    Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Range(0 1 2) Path(0 1)
-    AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0) LlvmInlineAsm(0)
-    MacCall(0) Struct(0 1 2) Repeat(0 1) Paren(0) Try(0) Yield(0) Err);
+    Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore Range(0 1 2)
+    Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0)
+    LlvmInlineAsm(0) MacCall(0) Struct(0 1 2) Repeat(0 1) Paren(0) Try(0)
+    Yield(0) Err);
 spanless_eq_enum!(InlineAsmOperand; In(reg expr) Out(reg late expr)
     InOut(reg late expr) SplitInOut(reg late in_expr out_expr) Const(expr)
     Sym(expr));
@@ -394,14 +408,6 @@
     }
 }
 
-// Give up on comparing literals inside of macros because there are so many
-// equivalent representations of the same literal; they are tested elsewhere
-impl SpanlessEq for token::Lit {
-    fn eq(&self, other: &Self) -> bool {
-        mem::discriminant(self) == mem::discriminant(other)
-    }
-}
-
 impl SpanlessEq for RangeSyntax {
     fn eq(&self, _other: &Self) -> bool {
         match self {
@@ -410,6 +416,34 @@
     }
 }
 
+impl SpanlessEq for Param {
+    fn eq(&self, other: &Self) -> bool {
+        let Param {
+            attrs,
+            ty,
+            pat,
+            id,
+            span: _,
+            is_placeholder,
+        } = self;
+        let Param {
+            attrs: attrs2,
+            ty: ty2,
+            pat: pat2,
+            id: id2,
+            span: _,
+            is_placeholder: is_placeholder2,
+        } = other;
+        SpanlessEq::eq(id, id2)
+            && SpanlessEq::eq(is_placeholder, is_placeholder2)
+            && (matches!(ty.kind, TyKind::Err)
+                || matches!(ty2.kind, TyKind::Err)
+                || SpanlessEq::eq(attrs, attrs2)
+                    && SpanlessEq::eq(ty, ty2)
+                    && SpanlessEq::eq(pat, pat2))
+    }
+}
+
 impl SpanlessEq for TokenKind {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
@@ -418,6 +452,14 @@
                 TokenKind::DotDotEq | TokenKind::DotDotDot => true,
                 _ => false,
             },
+            (TokenKind::Interpolated(this), TokenKind::Interpolated(other)) => {
+                match (this.as_ref(), other.as_ref()) {
+                    (Nonterminal::NtExpr(this), Nonterminal::NtExpr(other)) => {
+                        SpanlessEq::eq(this, other)
+                    }
+                    _ => this == other,
+                }
+            }
             _ => self == other,
         }
     }
@@ -425,28 +467,146 @@
 
 impl SpanlessEq for TokenStream {
     fn eq(&self, other: &Self) -> bool {
-        let mut this = self.clone().into_trees();
-        let mut other = other.clone().into_trees();
+        let mut this_trees = self.trees_ref();
+        let mut other_trees = other.trees_ref();
         loop {
-            let this = match this.next() {
-                None => return other.next().is_none(),
-                Some(val) => val,
+            let this = match this_trees.next() {
+                None => return other_trees.next().is_none(),
+                Some(tree) => tree,
             };
-            let other = match other.next() {
+            let other = match other_trees.next() {
                 None => return false,
-                Some(val) => val,
+                Some(tree) => tree,
             };
-            if !SpanlessEq::eq(&this, &other) {
-                return false;
+            if SpanlessEq::eq(this, other) {
+                continue;
             }
+            if let (TokenTree::Token(this), TokenTree::Token(other)) = (this, other) {
+                if match (&this.kind, &other.kind) {
+                    (TokenKind::Literal(this), TokenKind::Literal(other)) => {
+                        SpanlessEq::eq(this, other)
+                    }
+                    (TokenKind::DocComment(_kind, style, symbol), TokenKind::Pound) => {
+                        doc_comment(*style, *symbol, &mut other_trees)
+                    }
+                    (TokenKind::Pound, TokenKind::DocComment(_kind, style, symbol)) => {
+                        doc_comment(*style, *symbol, &mut this_trees)
+                    }
+                    _ => false,
+                } {
+                    continue;
+                }
+            }
+            return false;
         }
     }
 }
 
+fn doc_comment<'a>(
+    style: AttrStyle,
+    unescaped: Symbol,
+    trees: &mut impl Iterator<Item = &'a TokenTree>,
+) -> bool {
+    if match style {
+        AttrStyle::Outer => false,
+        AttrStyle::Inner => true,
+    } {
+        match trees.next() {
+            Some(TokenTree::Token(Token {
+                kind: TokenKind::Not,
+                span: _,
+            })) => {}
+            _ => return false,
+        }
+    }
+    let stream = match trees.next() {
+        Some(TokenTree::Delimited(_span, DelimToken::Bracket, stream)) => stream,
+        _ => return false,
+    };
+    let mut trees = stream.trees_ref();
+    match trees.next() {
+        Some(TokenTree::Token(Token {
+            kind: TokenKind::Ident(symbol, false),
+            span: _,
+        })) if *symbol == sym::doc => {}
+        _ => return false,
+    }
+    match trees.next() {
+        Some(TokenTree::Token(Token {
+            kind: TokenKind::Eq,
+            span: _,
+        })) => {}
+        _ => return false,
+    }
+    is_escaped_literal(trees, unescaped)
+}
+
+fn is_escaped_literal(mut trees: tokenstream::CursorRef, unescaped: Symbol) -> bool {
+    match match trees.next() {
+        Some(TokenTree::Token(Token {
+            kind: TokenKind::Literal(lit),
+            span: _,
+        })) => Lit::from_lit_token(*lit, DUMMY_SP),
+        Some(TokenTree::Token(Token {
+            kind: TokenKind::Interpolated(nonterminal),
+            span: _,
+        })) => match nonterminal.as_ref() {
+            Nonterminal::NtExpr(expr) => match &expr.kind {
+                ExprKind::Lit(lit) => Ok(lit.clone()),
+                _ => return false,
+            },
+            _ => return false,
+        },
+        _ => return false,
+    } {
+        Ok(Lit {
+            token:
+                token::Lit {
+                    kind: token::LitKind::Str,
+                    symbol: _,
+                    suffix: None,
+                },
+            kind: LitKind::Str(symbol, StrStyle::Cooked),
+            span: _,
+        }) => {
+            symbol.as_str().replace('\r', "") == unescaped.as_str().replace('\r', "")
+                && trees.next().is_none()
+        }
+        _ => false,
+    }
+}
+
 impl SpanlessEq for LazyTokenStream {
     fn eq(&self, other: &Self) -> bool {
-        let this = self.into_token_stream();
-        let other = other.into_token_stream();
+        let this = self.create_token_stream();
+        let other = other.create_token_stream();
         SpanlessEq::eq(&this, &other)
     }
 }
+
+impl SpanlessEq for AttrKind {
+    fn eq(&self, other: &Self) -> bool {
+        match (self, other) {
+            (AttrKind::Normal(item, tokens), AttrKind::Normal(item2, tokens2)) => {
+                SpanlessEq::eq(item, item2) && SpanlessEq::eq(tokens, tokens2)
+            }
+            (AttrKind::DocComment(kind, symbol), AttrKind::DocComment(kind2, symbol2)) => {
+                SpanlessEq::eq(kind, kind2) && SpanlessEq::eq(symbol, symbol2)
+            }
+            (AttrKind::DocComment(kind, unescaped), AttrKind::Normal(item2, _tokens)) => {
+                match kind {
+                    CommentKind::Line | CommentKind::Block => {}
+                }
+                let path = Path::from_ident(Ident::with_dummy_span(sym::doc));
+                SpanlessEq::eq(&path, &item2.path)
+                    && match &item2.args {
+                        MacArgs::Empty | MacArgs::Delimited(..) => false,
+                        MacArgs::Eq(_span, tokens) => {
+                            is_escaped_literal(tokens.trees_ref(), *unescaped)
+                        }
+                    }
+            }
+            (AttrKind::Normal(..), AttrKind::DocComment(..)) => SpanlessEq::eq(other, self),
+        }
+    }
+}
diff --git a/tests/debug/gen.rs b/tests/debug/gen.rs
index 85a1a39..1eae327 100644
--- a/tests/debug/gen.rs
+++ b/tests/debug/gen.rs
@@ -3424,12 +3424,24 @@
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let _val = &self.value;
         match _val {
-            syn::Lit::Str(_val) => write!(formatter, "{:?}", _val.value()),
-            syn::Lit::ByteStr(_val) => write!(formatter, "{:?}", _val.value()),
-            syn::Lit::Byte(_val) => write!(formatter, "{:?}", _val.value()),
-            syn::Lit::Char(_val) => write!(formatter, "{:?}", _val.value()),
-            syn::Lit::Int(_val) => write!(formatter, "{}", _val),
-            syn::Lit::Float(_val) => write!(formatter, "{}", _val),
+            syn::Lit::Str(_val) => {
+                write!(formatter, "{:?}", _val.value())
+            }
+            syn::Lit::ByteStr(_val) => {
+                write!(formatter, "{:?}", _val.value())
+            }
+            syn::Lit::Byte(_val) => {
+                write!(formatter, "{:?}", _val.value())
+            }
+            syn::Lit::Char(_val) => {
+                write!(formatter, "{:?}", _val.value())
+            }
+            syn::Lit::Int(_val) => {
+                write!(formatter, "{}", _val)
+            }
+            syn::Lit::Float(_val) => {
+                write!(formatter, "{}", _val)
+            }
             syn::Lit::Bool(_val) => {
                 let mut formatter = formatter.debug_struct("Lit::Bool");
                 formatter.field("value", Lite(&_val.value));
diff --git a/tests/repo/mod.rs b/tests/repo/mod.rs
index 1d3e1f0..afb7127 100644
--- a/tests/repo/mod.rs
+++ b/tests/repo/mod.rs
@@ -8,29 +8,30 @@
 use tar::Archive;
 use walkdir::DirEntry;
 
-const REVISION: &str = "792c645ca7d11a8d254df307d019c5bf01445c37";
+const REVISION: &str = "72da5a9d85a522b11e80d0fdd1fd95247d442604";
 
 #[rustfmt::skip]
 static EXCLUDE: &[&str] = &[
     // Compile-fail expr parameter in const generic position: f::<1 + 2>()
-    "test/ui/const-generics/const-expression-parameter.rs",
+    "src/test/ui/const-generics/closing-args-token.rs",
+    "src/test/ui/const-generics/const-expression-parameter.rs",
 
     // Deprecated anonymous parameter syntax in traits
-    "test/ui/issues/issue-13105.rs",
-    "test/ui/issues/issue-13775.rs",
-    "test/ui/issues/issue-34074.rs",
-    "test/ui/proc-macro/trait-fn-args-2015.rs",
+    "src/test/ui/issues/issue-13105.rs",
+    "src/test/ui/issues/issue-13775.rs",
+    "src/test/ui/issues/issue-34074.rs",
+    "src/test/ui/proc-macro/trait-fn-args-2015.rs",
 
     // Not actually test cases
-    "test/rustdoc-ui/test-compile-fail2.rs",
-    "test/rustdoc-ui/test-compile-fail3.rs",
-    "test/ui/include-single-expr-helper.rs",
-    "test/ui/include-single-expr-helper-1.rs",
-    "test/ui/issues/auxiliary/issue-21146-inc.rs",
-    "test/ui/json-bom-plus-crlf-multifile-aux.rs",
-    "test/ui/lint/expansion-time-include.rs",
-    "test/ui/macros/auxiliary/macro-comma-support.rs",
-    "test/ui/macros/auxiliary/macro-include-items-expr.rs",
+    "src/test/rustdoc-ui/test-compile-fail2.rs",
+    "src/test/rustdoc-ui/test-compile-fail3.rs",
+    "src/test/ui/include-single-expr-helper.rs",
+    "src/test/ui/include-single-expr-helper-1.rs",
+    "src/test/ui/issues/auxiliary/issue-21146-inc.rs",
+    "src/test/ui/json-bom-plus-crlf-multifile-aux.rs",
+    "src/test/ui/lint/expansion-time-include.rs",
+    "src/test/ui/macros/auxiliary/macro-comma-support.rs",
+    "src/test/ui/macros/auxiliary/macro-include-items-expr.rs",
 ];
 
 pub fn base_dir_filter(entry: &DirEntry) -> bool {
@@ -46,23 +47,17 @@
     if cfg!(windows) {
         path_string = path_string.replace('\\', "/").into();
     }
-    let path = if let Some(path) = path_string.strip_prefix("tests/rust/src/") {
-        path
-    } else if let Some(path) = path_string.strip_prefix("tests/rust/library/") {
+    let path = if let Some(path) = path_string.strip_prefix("tests/rust/") {
         path
     } else {
         panic!("unexpected path in Rust dist: {}", path_string);
     };
 
-    // TODO assert that parsing fails on the parse-fail cases
-    if path.starts_with("test/parse-fail")
-        || path.starts_with("test/compile-fail")
-        || path.starts_with("test/rustfix")
-    {
+    if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") {
         return false;
     }
 
-    if path.starts_with("test/ui") {
+    if path.starts_with("src/test/ui") {
         let stderr_path = entry.path().with_extension("stderr");
         if stderr_path.exists() {
             // Expected to fail in some way
@@ -91,10 +86,10 @@
         download_and_unpack().unwrap();
     }
     let mut missing = String::new();
-    let test_src = Path::new("tests/rust/src");
+    let test_src = Path::new("tests/rust");
     for exclude in EXCLUDE {
         if !test_src.join(exclude).exists() {
-            missing += "\ntests/rust/src/";
+            missing += "\ntests/rust/";
             missing += exclude;
         }
     }
diff --git a/tests/test_item.rs b/tests/test_item.rs
index 74ac4ba..c28fc87 100644
--- a/tests/test_item.rs
+++ b/tests/test_item.rs
@@ -43,3 +43,119 @@
     }
     "###);
 }
+
+#[test]
+fn test_negative_impl() {
+    // Rustc parses all of the following.
+
+    #[cfg(any())]
+    impl ! {}
+    let tokens = quote! {
+        impl ! {}
+    };
+    snapshot!(tokens as Item, @r###"
+    Item::Impl {
+        generics: Generics,
+        self_ty: Type::Never,
+    }
+    "###);
+
+    #[cfg(any())]
+    #[rustfmt::skip]
+    impl !Trait {}
+    let tokens = quote! {
+        impl !Trait {}
+    };
+    snapshot!(tokens as Item, @r###"
+    Item::Impl {
+        generics: Generics,
+        self_ty: Verbatim(`! Trait`),
+    }
+    "###);
+
+    #[cfg(any())]
+    impl !Trait for T {}
+    let tokens = quote! {
+        impl !Trait for T {}
+    };
+    snapshot!(tokens as Item, @r###"
+    Item::Impl {
+        generics: Generics,
+        trait_: Some((
+            Some,
+            Path {
+                segments: [
+                    PathSegment {
+                        ident: "Trait",
+                        arguments: None,
+                    },
+                ],
+            },
+        )),
+        self_ty: Type::Path {
+            path: Path {
+                segments: [
+                    PathSegment {
+                        ident: "T",
+                        arguments: None,
+                    },
+                ],
+            },
+        },
+    }
+    "###);
+
+    #[cfg(any())]
+    #[rustfmt::skip]
+    impl !! {}
+    let tokens = quote! {
+        impl !! {}
+    };
+    snapshot!(tokens as Item, @r###"
+    Item::Impl {
+        generics: Generics,
+        self_ty: Verbatim(`! !`),
+    }
+    "###);
+}
+
+#[test]
+fn test_macro_variable_impl() {
+    // mimics the token stream corresponding to `impl $trait for $ty {}`
+    let tokens = TokenStream::from_iter(vec![
+        TokenTree::Ident(Ident::new("impl", Span::call_site())),
+        TokenTree::Group(Group::new(Delimiter::None, quote!(Trait))),
+        TokenTree::Ident(Ident::new("for", Span::call_site())),
+        TokenTree::Group(Group::new(Delimiter::None, quote!(Type))),
+        TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+    ]);
+
+    snapshot!(tokens as Item, @r###"
+    Item::Impl {
+        generics: Generics,
+        trait_: Some((
+            None,
+            Path {
+                segments: [
+                    PathSegment {
+                        ident: "Trait",
+                        arguments: None,
+                    },
+                ],
+            },
+        )),
+        self_ty: Type::Group {
+            elem: Type::Path {
+                path: Path {
+                    segments: [
+                        PathSegment {
+                            ident: "Type",
+                            arguments: None,
+                        },
+                    ],
+                },
+            },
+        },
+    }
+    "###);
+}
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
index 1519cf0..4b4cb2f 100644
--- a/tests/test_precedence.rs
+++ b/tests/test_precedence.rs
@@ -26,8 +26,7 @@
 use rustc_ast::ast;
 use rustc_ast::ptr::P;
 use rustc_span::edition::Edition;
-use std::fs::File;
-use std::io::Read;
+use std::fs;
 use std::process;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use walkdir::{DirEntry, WalkDir};
@@ -107,9 +106,7 @@
                 return;
             }
 
-            let mut file = File::open(path).unwrap();
-            let mut content = String::new();
-            file.read_to_string(&mut content).unwrap();
+            let content = fs::read_to_string(path).unwrap();
             let content = edition_regex.replace_all(&content, "_$0");
 
             let (l_passed, l_failed) = match syn::parse_file(&content) {
@@ -198,7 +195,7 @@
 /// This method operates on librustc objects.
 fn librustc_brackets(mut librustc_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
     use rustc_ast::ast::{
-        Block, BorrowKind, Expr, ExprKind, Field, GenericArg, MacCall, Pat, Stmt, StmtKind, Ty,
+        Block, BorrowKind, Expr, ExprKind, Field, GenericArg, Pat, Stmt, StmtKind, StructRest, Ty,
     };
     use rustc_ast::mut_visit::{noop_visit_generic_arg, MutVisitor};
     use rustc_data_structures::map_in_place::MapInPlace;
@@ -208,7 +205,7 @@
 
     struct BracketsVisitor {
         failed: bool,
-    };
+    }
 
     fn flat_map_field<T: MutVisitor>(mut f: Field, vis: &mut T) -> Vec<Field> {
         if f.is_shorthand {
@@ -237,13 +234,15 @@
     }
 
     fn noop_visit_expr<T: MutVisitor>(e: &mut Expr, vis: &mut T) {
-        use rustc_ast::mut_visit::{noop_visit_expr, visit_opt, visit_thin_attrs};
+        use rustc_ast::mut_visit::{noop_visit_expr, visit_thin_attrs};
         match &mut e.kind {
             ExprKind::AddrOf(BorrowKind::Raw, ..) => {}
             ExprKind::Struct(path, fields, expr) => {
                 vis.visit_path(path);
                 fields.flat_map_in_place(|field| flat_map_field(field, vis));
-                visit_opt(expr, |expr| vis.visit_expr(expr));
+                if let StructRest::Base(expr) = expr {
+                    vis.visit_expr(expr);
+                }
                 vis.visit_id(&mut e.id);
                 vis.visit_span(&mut e.span);
                 visit_thin_attrs(&mut e.attrs, vis);
@@ -254,7 +253,10 @@
 
     impl MutVisitor for BracketsVisitor {
         fn visit_expr(&mut self, e: &mut P<Expr>) {
-            noop_visit_expr(e, self);
+            match e.kind {
+                ExprKind::ConstBlock(..) => {}
+                _ => noop_visit_expr(e, self),
+            }
             match e.kind {
                 ExprKind::If(..) | ExprKind::Block(..) | ExprKind::Let(..) => {}
                 _ => {
@@ -299,15 +301,6 @@
         fn visit_ty(&mut self, ty: &mut P<Ty>) {
             let _ = ty;
         }
-
-        fn visit_mac(&mut self, mac: &mut MacCall) {
-            // By default when folding over macros, librustc panics. This is
-            // because it's usually not what you want, you want to run after
-            // macro expansion. We do want to do that (syn doesn't do macro
-            // expansion), so we implement visit_mac to just return the macro
-            // unchanged.
-            let _ = mac;
-        }
     }
 
     let mut folder = BracketsVisitor { failed: false };
diff --git a/tests/test_round_trip.rs b/tests/test_round_trip.rs
index b742034..e8ed345 100644
--- a/tests/test_round_trip.rs
+++ b/tests/test_round_trip.rs
@@ -12,14 +12,17 @@
 use crate::common::eq::SpanlessEq;
 use quote::quote;
 use rayon::iter::{IntoParallelIterator, ParallelIterator};
-use rustc_ast::ast;
+use rustc_ast::ast::{
+    AngleBracketedArg, AngleBracketedArgs, Crate, GenericArg, GenericParamKind, Generics,
+};
+use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_errors::PResult;
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::FilePathMapping;
 use rustc_span::FileName;
-use std::fs::File;
-use std::io::Read;
+use std::fs;
 use std::panic;
+use std::path::Path;
 use std::process;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::time::Instant;
@@ -53,88 +56,8 @@
         .into_par_iter()
         .for_each(|entry| {
             let path = entry.path();
-            if path.is_dir() {
-                return;
-            }
-
-            let mut file = File::open(path).unwrap();
-            let mut content = String::new();
-            file.read_to_string(&mut content).unwrap();
-
-            let start = Instant::now();
-            let (krate, elapsed) = match syn::parse_file(&content) {
-                Ok(krate) => (krate, start.elapsed()),
-                Err(msg) => {
-                    errorf!("=== {}: syn failed to parse\n{:?}\n", path.display(), msg);
-                    let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
-                    if prev_failed + 1 >= abort_after {
-                        process::exit(1);
-                    }
-                    return;
-                }
-            };
-            let back = quote!(#krate).to_string();
-            let edition = repo::edition(path).parse().unwrap();
-
-            let equal = panic::catch_unwind(|| {
-                rustc_span::with_session_globals(edition, || {
-                    let sess = ParseSess::new(FilePathMapping::empty());
-                    let before = match librustc_parse(content, &sess) {
-                        Ok(before) => before,
-                        Err(mut diagnostic) => {
-                            diagnostic.cancel();
-                            if diagnostic
-                                .message()
-                                .starts_with("file not found for module")
-                            {
-                                errorf!("=== {}: ignore\n", path.display());
-                            } else {
-                                errorf!(
-                                "=== {}: ignore - librustc failed to parse original content: {}\n",
-                                path.display(),
-                                diagnostic.message()
-                            );
-                            }
-                            return true;
-                        }
-                    };
-                    let after = match librustc_parse(back, &sess) {
-                        Ok(after) => after,
-                        Err(mut diagnostic) => {
-                            errorf!("=== {}: librustc failed to parse", path.display());
-                            diagnostic.emit();
-                            return false;
-                        }
-                    };
-
-                    if SpanlessEq::eq(&before, &after) {
-                        errorf!(
-                            "=== {}: pass in {}ms\n",
-                            path.display(),
-                            elapsed.as_secs() * 1000
-                                + u64::from(elapsed.subsec_nanos()) / 1_000_000
-                        );
-                        true
-                    } else {
-                        errorf!(
-                            "=== {}: FAIL\nbefore: {:#?}\nafter: {:#?}\n",
-                            path.display(),
-                            before,
-                            after,
-                        );
-                        false
-                    }
-                })
-            });
-            match equal {
-                Err(_) => errorf!("=== {}: ignoring librustc panic\n", path.display()),
-                Ok(true) => {}
-                Ok(false) => {
-                    let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
-                    if prev_failed + 1 >= abort_after {
-                        process::exit(1);
-                    }
-                }
+            if !path.is_dir() {
+                test(path, &failed, abort_after);
             }
         });
 
@@ -144,7 +67,134 @@
     }
 }
 
-fn librustc_parse(content: String, sess: &ParseSess) -> PResult<ast::Crate> {
-    let name = FileName::Custom("test_round_trip".to_string());
+fn test(path: &Path, failed: &AtomicUsize, abort_after: usize) {
+    let content = fs::read_to_string(path).unwrap();
+
+    let start = Instant::now();
+    let (krate, elapsed) = match syn::parse_file(&content) {
+        Ok(krate) => (krate, start.elapsed()),
+        Err(msg) => {
+            errorf!("=== {}: syn failed to parse\n{:?}\n", path.display(), msg);
+            let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
+            if prev_failed + 1 >= abort_after {
+                process::exit(1);
+            }
+            return;
+        }
+    };
+    let back = quote!(#krate).to_string();
+    let edition = repo::edition(path).parse().unwrap();
+
+    rustc_span::with_session_globals(edition, || {
+        let equal = match panic::catch_unwind(|| {
+            let sess = ParseSess::new(FilePathMapping::empty());
+            let before = match librustc_parse(content, &sess) {
+                Ok(before) => before,
+                Err(mut diagnostic) => {
+                    diagnostic.cancel();
+                    if diagnostic
+                        .message()
+                        .starts_with("file not found for module")
+                    {
+                        errorf!("=== {}: ignore\n", path.display());
+                    } else {
+                        errorf!(
+                            "=== {}: ignore - librustc failed to parse original content: {}\n",
+                            path.display(),
+                            diagnostic.message(),
+                        );
+                    }
+                    return Err(true);
+                }
+            };
+            let after = match librustc_parse(back, &sess) {
+                Ok(after) => after,
+                Err(mut diagnostic) => {
+                    errorf!("=== {}: librustc failed to parse", path.display());
+                    diagnostic.emit();
+                    return Err(false);
+                }
+            };
+            Ok((before, after))
+        }) {
+            Err(_) => {
+                errorf!("=== {}: ignoring librustc panic\n", path.display());
+                true
+            }
+            Ok(Err(equal)) => equal,
+            Ok(Ok((mut before, mut after))) => {
+                normalize(&mut before);
+                normalize(&mut after);
+                if SpanlessEq::eq(&before, &after) {
+                    errorf!(
+                        "=== {}: pass in {}ms\n",
+                        path.display(),
+                        elapsed.as_secs() * 1000 + u64::from(elapsed.subsec_nanos()) / 1_000_000
+                    );
+                    true
+                } else {
+                    errorf!(
+                        "=== {}: FAIL\nbefore: {:#?}\nafter: {:#?}\n",
+                        path.display(),
+                        before,
+                        after,
+                    );
+                    false
+                }
+            }
+        };
+        if !equal {
+            let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
+            if prev_failed + 1 >= abort_after {
+                process::exit(1);
+            }
+        }
+    });
+}
+
+fn librustc_parse(content: String, sess: &ParseSess) -> PResult<Crate> {
+    static COUNTER: AtomicUsize = AtomicUsize::new(0);
+    let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
+    let name = FileName::Custom(format!("test_round_trip{}", counter));
     parse::parse_crate_from_source_str(name, content, sess)
 }
+
+fn normalize(krate: &mut Crate) {
+    struct NormalizeVisitor;
+
+    impl MutVisitor for NormalizeVisitor {
+        fn visit_angle_bracketed_parameter_data(&mut self, e: &mut AngleBracketedArgs) {
+            #[derive(Ord, PartialOrd, Eq, PartialEq)]
+            enum Group {
+                Lifetimes,
+                TypesAndConsts,
+                Constraints,
+            }
+            e.args.sort_by_key(|arg| match arg {
+                AngleBracketedArg::Arg(arg) => match arg {
+                    GenericArg::Lifetime(_) => Group::Lifetimes,
+                    GenericArg::Type(_) | GenericArg::Const(_) => Group::TypesAndConsts,
+                },
+                AngleBracketedArg::Constraint(_) => Group::Constraints,
+            });
+            mut_visit::noop_visit_angle_bracketed_parameter_data(e, self);
+        }
+
+        fn visit_generics(&mut self, e: &mut Generics) {
+            #[derive(Ord, PartialOrd, Eq, PartialEq)]
+            enum Group {
+                Lifetimes,
+                TypesAndConsts,
+            }
+            e.params.sort_by_key(|param| match param.kind {
+                GenericParamKind::Lifetime => Group::Lifetimes,
+                GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
+                    Group::TypesAndConsts
+                }
+            });
+            mut_visit::noop_visit_generics(e, self);
+        }
+    }
+
+    NormalizeVisitor.visit_crate(krate);
+}
diff --git a/tests/test_stmt.rs b/tests/test_stmt.rs
index d68b47f..943d856 100644
--- a/tests/test_stmt.rs
+++ b/tests/test_stmt.rs
@@ -1,6 +1,8 @@
 #[macro_use]
 mod macros;
 
+use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+use std::iter::FromIterator;
 use syn::Stmt;
 
 #[test]
@@ -42,3 +44,31 @@
 fn test_raw_invalid() {
     assert!(syn::parse_str::<Stmt>("let _ = &raw x;").is_err());
 }
+
+#[test]
+fn test_none_group() {
+    // <Ø async fn f() {} Ø>
+    let tokens = TokenStream::from_iter(vec![TokenTree::Group(Group::new(
+        Delimiter::None,
+        TokenStream::from_iter(vec![
+            TokenTree::Ident(Ident::new("async", Span::call_site())),
+            TokenTree::Ident(Ident::new("fn", Span::call_site())),
+            TokenTree::Ident(Ident::new("f", Span::call_site())),
+            TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+            TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+        ]),
+    ))]);
+
+    snapshot!(tokens as Stmt, @r###"
+    Item(Item::Fn {
+        vis: Inherited,
+        sig: Signature {
+            asyncness: Some,
+            ident: "f",
+            generics: Generics,
+            output: Default,
+        },
+        block: Block,
+    })
+    "###);
+}
diff --git a/tests/test_ty.rs b/tests/test_ty.rs
index 9cbdcd6..7e20dd9 100644
--- a/tests/test_ty.rs
+++ b/tests/test_ty.rs
@@ -50,4 +50,170 @@
         },
     }
     "###);
+
+    // mimics the token stream corresponding to `$ty::<T>`
+    let tokens = TokenStream::from_iter(vec![
+        TokenTree::Group(Group::new(Delimiter::None, quote! { ty })),
+        TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+        TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+        TokenTree::Punct(Punct::new('<', Spacing::Alone)),
+        TokenTree::Ident(Ident::new("T", Span::call_site())),
+        TokenTree::Punct(Punct::new('>', Spacing::Alone)),
+    ]);
+
+    snapshot!(tokens as Type, @r###"
+    Type::Path {
+        path: Path {
+            segments: [
+                PathSegment {
+                    ident: "ty",
+                    arguments: PathArguments::AngleBracketed {
+                        colon2_token: Some,
+                        args: [
+                            Type(Type::Path {
+                                path: Path {
+                                    segments: [
+                                        PathSegment {
+                                            ident: "T",
+                                            arguments: None,
+                                        },
+                                    ],
+                                },
+                            }),
+                        ],
+                    },
+                },
+            ],
+        },
+    }
+    "###);
+}
+
+#[test]
+fn test_group_angle_brackets() {
+    // mimics the token stream corresponding to `Option<$ty>`
+    let tokens = TokenStream::from_iter(vec![
+        TokenTree::Ident(Ident::new("Option", Span::call_site())),
+        TokenTree::Punct(Punct::new('<', Spacing::Alone)),
+        TokenTree::Group(Group::new(Delimiter::None, quote! { Vec<u8> })),
+        TokenTree::Punct(Punct::new('>', Spacing::Alone)),
+    ]);
+
+    snapshot!(tokens as Type, @r###"
+    Type::Path {
+        path: Path {
+            segments: [
+                PathSegment {
+                    ident: "Option",
+                    arguments: PathArguments::AngleBracketed {
+                        args: [
+                            Type(Type::Group {
+                                elem: Type::Path {
+                                    path: Path {
+                                        segments: [
+                                            PathSegment {
+                                                ident: "Vec",
+                                                arguments: PathArguments::AngleBracketed {
+                                                    args: [
+                                                        Type(Type::Path {
+                                                            path: Path {
+                                                                segments: [
+                                                                    PathSegment {
+                                                                        ident: "u8",
+                                                                        arguments: None,
+                                                                    },
+                                                                ],
+                                                            },
+                                                        }),
+                                                    ],
+                                                },
+                                            },
+                                        ],
+                                    },
+                                },
+                            }),
+                        ],
+                    },
+                },
+            ],
+        },
+    }
+    "###);
+}
+
+#[test]
+fn test_group_colons() {
+    // mimics the token stream corresponding to `$ty::Item`
+    let tokens = TokenStream::from_iter(vec![
+        TokenTree::Group(Group::new(Delimiter::None, quote! { Vec<u8> })),
+        TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+        TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+        TokenTree::Ident(Ident::new("Item", Span::call_site())),
+    ]);
+
+    snapshot!(tokens as Type, @r###"
+    Type::Path {
+        path: Path {
+            segments: [
+                PathSegment {
+                    ident: "Vec",
+                    arguments: PathArguments::AngleBracketed {
+                        args: [
+                            Type(Type::Path {
+                                path: Path {
+                                    segments: [
+                                        PathSegment {
+                                            ident: "u8",
+                                            arguments: None,
+                                        },
+                                    ],
+                                },
+                            }),
+                        ],
+                    },
+                },
+                PathSegment {
+                    ident: "Item",
+                    arguments: None,
+                },
+            ],
+        },
+    }
+    "###);
+
+    let tokens = TokenStream::from_iter(vec![
+        TokenTree::Group(Group::new(Delimiter::None, quote! { [T] })),
+        TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+        TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+        TokenTree::Ident(Ident::new("Element", Span::call_site())),
+    ]);
+
+    snapshot!(tokens as Type, @r###"
+    Type::Path {
+        qself: Some(QSelf {
+            ty: Type::Slice {
+                elem: Type::Path {
+                    path: Path {
+                        segments: [
+                            PathSegment {
+                                ident: "T",
+                                arguments: None,
+                            },
+                        ],
+                    },
+                },
+            },
+            position: 0,
+        }),
+        path: Path {
+            leading_colon: Some,
+            segments: [
+                PathSegment {
+                    ident: "Element",
+                    arguments: None,
+                },
+            ],
+        },
+    }
+    "###);
 }
diff --git a/tests/test_visibility.rs b/tests/test_visibility.rs
index c3d0ac7..7b2c00b 100644
--- a/tests/test_visibility.rs
+++ b/tests/test_visibility.rs
@@ -92,7 +92,10 @@
 
 #[test]
 fn test_crate_path() {
-    assert_vis_parse!("pub(crate::A, crate::B)", Ok(Visibility::Public(_)) + "(crate::A, crate::B)");
+    assert_vis_parse!(
+        "pub(crate::A, crate::B)",
+        Ok(Visibility::Public(_)) + "(crate::A, crate::B)"
+    );
 }
 
 #[test]